├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.cjs
├── .github
├── CODEOWNERS
└── workflows
│ └── main.yaml
├── .gitignore
├── .husky
└── pre-commit
├── .npmignore
├── .prettierignore
├── .prettierrc
├── CODE_OF_CONDUCT.md
├── CONTRIBUTE.md
├── LICENSE
├── README.md
├── ci
├── compose.sh
├── docker-compose-async.yml
├── docker-compose-azure-cc.yml
├── docker-compose-backup.yml
├── docker-compose-cluster.yml
├── docker-compose-okta-cc.yml
├── docker-compose-okta-users.yml
├── docker-compose-openai.yml
├── docker-compose-proxy.yml
├── docker-compose-rbac.yml
├── docker-compose-wcs.yml
├── docker-compose.yml
├── proxy
│ ├── grpc.yaml
│ └── http.yaml
├── run_dependencies.sh
└── stop_dependencies.sh
├── examples
├── README.md
├── javascript
│ ├── .gitignore
│ ├── index.js
│ └── package.json
└── typescript
│ ├── .gitignore
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── jest.config.ts
├── package-lock.json
├── package.json
├── public
└── favicon.ico
├── src
├── backup
│ ├── backupCreateStatusGetter.ts
│ ├── backupCreator.ts
│ ├── backupGetter.ts
│ ├── backupRestoreStatusGetter.ts
│ ├── backupRestorer.ts
│ ├── index.ts
│ ├── journey.test.ts
│ └── validation.ts
├── batch
│ ├── index.ts
│ ├── journey.test.ts
│ ├── objectsBatchDeleter.ts
│ ├── objectsBatcher.ts
│ ├── path.test.ts
│ ├── path.ts
│ ├── referencePayloadBuilder.ts
│ └── referencesBatcher.ts
├── c11y
│ ├── conceptsGetter.ts
│ ├── extensionCreator.ts
│ ├── index.ts
│ └── journey.test.ts
├── classifications
│ ├── contextual.journey.test.ts
│ ├── getter.ts
│ ├── index.ts
│ ├── knn.journey.test.ts
│ └── scheduler.ts
├── cluster
│ ├── index.ts
│ └── nodesStatusGetter.ts
├── collections
│ ├── aggregate
│ │ ├── index.ts
│ │ └── integration.test.ts
│ ├── backup
│ │ ├── client.ts
│ │ ├── collection.ts
│ │ ├── index.ts
│ │ ├── integration.test.ts
│ │ ├── types.ts
│ │ └── unit.test.ts
│ ├── cluster
│ │ ├── index.ts
│ │ └── integration.test.ts
│ ├── collection
│ │ └── index.ts
│ ├── config
│ │ ├── classes.ts
│ │ ├── index.ts
│ │ ├── integration.test.ts
│ │ ├── types
│ │ │ ├── generative.ts
│ │ │ ├── index.ts
│ │ │ ├── reranker.ts
│ │ │ ├── vectorIndex.ts
│ │ │ └── vectorizer.ts
│ │ ├── unit.test.ts
│ │ └── utils.ts
│ ├── configure
│ │ ├── generative.ts
│ │ ├── index.ts
│ │ ├── parsing.ts
│ │ ├── reranker.ts
│ │ ├── types
│ │ │ ├── base.ts
│ │ │ ├── generative.ts
│ │ │ ├── index.ts
│ │ │ ├── vectorIndex.ts
│ │ │ └── vectorizer.ts
│ │ ├── unit.test.ts
│ │ ├── vectorIndex.ts
│ │ └── vectorizer.ts
│ ├── data
│ │ ├── index.ts
│ │ └── integration.test.ts
│ ├── deserialize
│ │ └── index.ts
│ ├── filters
│ │ ├── classes.ts
│ │ ├── index.ts
│ │ ├── integration.test.ts
│ │ ├── types.ts
│ │ ├── unit.test.ts
│ │ └── utils.ts
│ ├── generate
│ │ ├── config.ts
│ │ ├── index.ts
│ │ ├── integration.test.ts
│ │ ├── mock.test.ts
│ │ ├── types.ts
│ │ └── unit.test.ts
│ ├── index.ts
│ ├── integration.test.ts
│ ├── iterator
│ │ ├── index.ts
│ │ └── integration.test.ts
│ ├── journey.test.ts
│ ├── query
│ │ ├── check.ts
│ │ ├── index.ts
│ │ ├── integration.test.ts
│ │ ├── types.ts
│ │ └── utils.ts
│ ├── references
│ │ ├── classes.ts
│ │ ├── index.ts
│ │ ├── types.ts
│ │ └── utils.ts
│ ├── serialize
│ │ ├── index.ts
│ │ └── unit.test.ts
│ ├── sort
│ │ ├── classes.ts
│ │ ├── index.ts
│ │ ├── integration.test.ts
│ │ └── types.ts
│ ├── tenants
│ │ ├── index.ts
│ │ ├── integration.test.ts
│ │ ├── types.ts
│ │ └── unit.test.ts
│ ├── types
│ │ ├── batch.ts
│ │ ├── data.ts
│ │ ├── generate.ts
│ │ ├── index.ts
│ │ ├── internal.ts
│ │ └── query.ts
│ └── vectors
│ │ └── multiTargetVector.ts
├── connection
│ ├── auth.ts
│ ├── gql.ts
│ ├── grpc.ts
│ ├── helpers.test.ts
│ ├── helpers.ts
│ ├── http.ts
│ ├── index.ts
│ ├── integration.test.ts
│ ├── journey.test.ts
│ ├── proxy.test.ts
│ └── unit.test.ts
├── data
│ ├── checker.ts
│ ├── creator.ts
│ ├── deleter.ts
│ ├── getter.ts
│ ├── getterById.ts
│ ├── index.ts
│ ├── journey.test.ts
│ ├── merger.ts
│ ├── path.test.ts
│ ├── path.ts
│ ├── referenceCreator.ts
│ ├── referenceDeleter.ts
│ ├── referencePayloadBuilder.ts
│ ├── referenceReplacer.ts
│ ├── replication.ts
│ ├── updater.ts
│ └── validator.ts
├── errors.ts
├── graphql
│ ├── aggregator.ts
│ ├── ask.ts
│ ├── bm25.ts
│ ├── explorer.ts
│ ├── generate.ts
│ ├── getter.test.ts
│ ├── getter.ts
│ ├── group.ts
│ ├── groupBy.ts
│ ├── hybrid.ts
│ ├── index.ts
│ ├── journey.test.ts
│ ├── nearImage.ts
│ ├── nearMedia.ts
│ ├── nearObject.ts
│ ├── nearText.ts
│ ├── nearVector.ts
│ ├── raw.test.ts
│ ├── raw.ts
│ ├── sort.ts
│ └── where.ts
├── grpc
│ ├── aggregator.ts
│ ├── base.ts
│ ├── batcher.ts
│ ├── retry.ts
│ ├── searcher.ts
│ └── tenantsManager.ts
├── index.ts
├── integration.test.ts
├── misc
│ ├── index.ts
│ ├── journey.test.ts
│ ├── liveChecker.ts
│ ├── metaGetter.ts
│ ├── openidConfigurationGetter.ts
│ └── readyChecker.ts
├── openapi
│ ├── schema.ts
│ └── types.ts
├── proto
│ ├── google
│ │ ├── health
│ │ │ └── v1
│ │ │ │ └── health.ts
│ │ └── protobuf
│ │ │ └── struct.ts
│ └── v1
│ │ ├── aggregate.ts
│ │ ├── base.ts
│ │ ├── base_search.ts
│ │ ├── batch.ts
│ │ ├── batch_delete.ts
│ │ ├── generative.ts
│ │ ├── properties.ts
│ │ ├── search_get.ts
│ │ ├── tenants.ts
│ │ └── weaviate.ts
├── roles
│ ├── index.ts
│ ├── integration.test.ts
│ ├── types.ts
│ └── util.ts
├── schema
│ ├── classCreator.ts
│ ├── classDeleter.ts
│ ├── classExists.ts
│ ├── classGetter.ts
│ ├── classUpdater.ts
│ ├── deleteAll.ts
│ ├── getter.ts
│ ├── index.ts
│ ├── journey.test.ts
│ ├── propertyCreator.ts
│ ├── shardUpdater.ts
│ ├── shardsGetter.ts
│ ├── shardsUpdater.ts
│ ├── tenantsCreator.ts
│ ├── tenantsDeleter.ts
│ ├── tenantsExists.ts
│ ├── tenantsGetter.ts
│ ├── tenantsUpdater.ts
│ └── vectorAdder.ts
├── users
│ ├── index.ts
│ ├── integration.test.ts
│ └── types.ts
├── utils
│ ├── base64.test.ts
│ ├── base64.ts
│ ├── beaconPath.ts
│ ├── dbVersion.ts
│ ├── journey.test.ts
│ ├── testData.ts
│ └── uuid.ts
├── v2
│ └── index.ts
└── validation
│ ├── commandBase.ts
│ ├── number.ts
│ ├── string.ts
│ └── version.ts
├── test
├── dbVersionProvider.ts
├── server.ts
└── version.ts
├── tools
├── health.proto
├── prepare_release.sh
├── refresh_protos.sh
└── refresh_schema.sh
├── tsconfig-test.json
├── tsconfig.json
└── tsup.config.ts
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "plugins": [
4 | "@babel/plugin-proposal-class-properties",
5 | "@babel/plugin-transform-runtime"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*]
2 | charset = utf-8
3 | indent_style = space
4 | indent_size = 2
5 | insert_final_newline = true
6 | trim_trailing_whitespace = true
7 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | types
4 | docs
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Ci related folders
2 | /.github/ @weaviate/core
3 | /ci/ @weaviate/core
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | coverage/
3 | node_modules/
4 | config.yaml
5 | lib.js
6 | weaviate-data/
7 | .vscode/
8 | .idea/
9 | *.tgz
10 | .npmrc
11 | .eslintcache
12 | test.sh
13 | scratch/
14 | docs/
15 | dist/
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npx lint-staged
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # This file is written to be a whitelist instead of a blacklist. Start by
2 | # ignoring everything, then add back the files we want to be included in the
3 | # final NPM package.
4 | *
5 |
6 | # And these are the files that are allowed.
7 | !/LICENSE
8 | !/README.md
9 | !/package.json
10 | !/dist/**/*
11 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | src/proto/**/*.ts
2 | src/dist/**/*
3 | src/docs/**/*.js
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "arrowParens": "always",
4 | "trailingComma": "es5",
5 | "bracketSpacing": true,
6 | "singleQuote": true,
7 | "printWidth": 110,
8 | "tabWidth": 2
9 | }
10 |
--------------------------------------------------------------------------------
/CONTRIBUTE.md:
--------------------------------------------------------------------------------
1 | ### Thanks for looking into contributing to Weaviate TypeScript client!
2 | Contributing works pretty easy. You can do a pull request or you can commit if you are part of a Weaviate team.
3 |
4 | ### Code of Conduct
5 | Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.
6 | [](CODE_OF_CONDUCT.md)
7 |
8 |
9 | ### How we use Gitflow
10 | How we use [Gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) and how you can contribute following a few steps.
11 |
12 | - The main branch is what is released and developed currently.
13 | - You can create a feature-branch that is named: feature/YOUR-FEATURE-NAME.
14 | - Your feature branch always has the main branch as a starting point.
15 | - When you are done with your feature you should create a pull request into the main branch.
16 | - The main branch is protected.
17 |
18 | ### Tagging your commit
19 |
20 | Always add a reference to your issue to your git commit.
21 |
22 | For example: `gh-100: This is the commit message`
23 |
24 | AKA: smart commits
25 |
26 | ### Pull Request
27 |
28 | If you create a pull request without smart commits, the pull request will be [squashed into](https://blog.github.com/2016-04-01-squash-your-commits/) one git commit.
29 |
30 | ### Contributor License Agreement
31 |
32 | Contributions to Weaviate TypeScript client must be accompanied by a Contributor License Agreement. You (or your employer) retain the copyright to your contribution; this simply gives us permission to use and redistribute your contributions as part of Weaviate TypeScript client. Go to [this page](https://www.semi.technology/playbooks/misc/contributor-license-agreement.html) to read the current agreement.
33 |
34 | The process works as follows:
35 |
36 | - You contribute by opening a [pull request](#pull-request).
37 | - If your account has no CLA, a DocuSign link will be added as a comment to the pull request.
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2020-2023, Weaviate B.V.
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Weaviate JS/TS client
2 |
3 | Official JS/TS client for easy interaction with a Weaviate instance.
4 |
5 | ## Documentation
6 |
7 | - [General Documentation](https://weaviate.io/developers/weaviate/client-libraries/typescript).
8 | - [Client-specific Documentation](https://weaviate.github.io/typescript-client/)
9 |
10 | ## Support
11 |
12 | - [Stackoverflow for questions](https://stackoverflow.com/questions/tagged/weaviate).
13 | - [Github for issues](https://github.com/weaviate/typescript-client/issues).
14 |
15 | ## Contributing
16 |
17 | - [How to Contribute](https://github.com/weaviate/typescript-client/blob/main/CONTRIBUTE.md).
18 |
19 | ## Build Status
20 |
21 | [](https://github.com/weaviate/typescript-client/actions/workflows/.github/workflows/main.yaml)
22 |
--------------------------------------------------------------------------------
/ci/compose.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -eou pipefail
4 |
5 | function ls_compose {
6 | ls ci | grep 'docker-compose'
7 | }
8 |
9 | function exec_all {
10 | for file in $(ls_compose); do
11 | docker compose -f $(echo "ci/${file} ${1}")
12 | done
13 | }
14 |
15 | function compose_up_all {
16 | exec_all "up -d"
17 | }
18 |
19 | function compose_down_all {
20 | exec_all "down --remove-orphans"
21 | }
22 |
23 | function all_weaviate_ports {
24 | echo "8078 8080 8081 8082 8083 8085 8086 8087 8088 8089 8090 8091"
25 | }
26 |
--------------------------------------------------------------------------------
/ci/docker-compose-async.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: '3.4'
3 | services:
4 | weaviate_async:
5 | command:
6 | - --host
7 | - 0.0.0.0
8 | - --port
9 | - '8090'
10 | - --scheme
11 | - http
12 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
13 | ports:
14 | - "8078:8090"
15 | - "50049:50051"
16 | restart: on-failure:0
17 | environment:
18 | QUERY_DEFAULTS_LIMIT: 25
19 | AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
20 | PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
21 | CLUSTER_HOSTNAME: 'node1'
22 | ASYNC_INDEXING: 'true'
23 | DISABLE_TELEMETRY: 'true'
24 |
--------------------------------------------------------------------------------
/ci/docker-compose-azure-cc.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: '3.4'
3 | services:
4 | weaviate-auth-azure:
5 | command:
6 | - --host
7 | - 0.0.0.0
8 | - --port
9 | - '8081'
10 | - --scheme
11 | - http
12 | - --write-timeout=600s
13 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
14 | ports:
15 | - 8081:8081
16 | restart: on-failure:0
17 | environment:
18 | PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
19 | AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
20 | AUTHENTICATION_OIDC_ENABLED: 'true'
21 | AUTHENTICATION_OIDC_CLIENT_ID: '4706508f-30c2-469b-8b12-ad272b3de864'
22 | AUTHENTICATION_OIDC_ISSUER: 'https://login.microsoftonline.com/36c47fb4-f57c-4e1c-8760-d42293932cc2/v2.0'
23 | AUTHENTICATION_OIDC_USERNAME_CLAIM: 'oid'
24 | AUTHENTICATION_OIDC_GROUPS_CLAIM: 'groups'
25 | AUTHORIZATION_ADMINLIST_ENABLED: 'true'
26 | AUTHORIZATION_ADMINLIST_USERS: 'b6bf8e1d-d398-4e5d-8f1b-50fda9146a64'
27 | DISABLE_TELEMETRY: 'true'
28 | ...
29 |
--------------------------------------------------------------------------------
/ci/docker-compose-backup.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: '3.4'
3 | services:
4 | weaviate-backup:
5 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
6 | restart: on-failure:0
7 | ports:
8 | - 8090:8080
9 | - 50061:50051
10 | environment:
11 | QUERY_DEFAULTS_LIMIT: 20
12 | AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
13 | PERSISTENCE_DATA_PATH: "./weaviate-data"
14 | BACKUP_FILESYSTEM_PATH: "/tmp/backups"
15 | ENABLE_MODULES: backup-filesystem
16 | CLUSTER_GOSSIP_BIND_PORT: "7100"
17 | CLUSTER_DATA_BIND_PORT: "7101"
18 | DISABLE_TELEMETRY: 'true'
19 | ...
20 |
--------------------------------------------------------------------------------
/ci/docker-compose-cluster.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: '3.4'
3 | services:
4 | weaviate-node-1:
5 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
6 | restart: on-failure:0
7 | ports:
8 | - "8087:8080"
9 | - "50058:50051"
10 | environment:
11 | QUERY_DEFAULTS_LIMIT: 20
12 | AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
13 | PERSISTENCE_DATA_PATH: "./weaviate-node-1"
14 | CLUSTER_HOSTNAME: "node1"
15 | CLUSTER_GOSSIP_BIND_PORT: "7110"
16 | CLUSTER_DATA_BIND_PORT: "7111"
17 | RAFT_PORT: '8300'
18 | RAFT_INTERNAL_RPC_PORT: "8301"
19 | RAFT_JOIN: "node1:8300,node2:8300,node3:8300"
20 | RAFT_BOOTSTRAP_EXPECT: "3"
21 | DISABLE_TELEMETRY: 'true'
22 | CONTEXTIONARY_URL: contextionary:9999
23 | DEFAULT_VECTORIZER_MODULE: text2vec-contextionary
24 | ENABLE_MODULES: text2vec-contextionary
25 |
26 | weaviate-node-2:
27 | init: true
28 | command:
29 | - --host
30 | - 0.0.0.0
31 | - --port
32 | - '8080'
33 | - --scheme
34 | - http
35 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
36 | ports:
37 | - 8088:8080
38 | - "50059:50051"
39 | restart: on-failure:0
40 | environment:
41 | LOG_LEVEL: 'debug'
42 | QUERY_DEFAULTS_LIMIT: 20
43 | AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
44 | PERSISTENCE_DATA_PATH: './weaviate-node-2'
45 | CLUSTER_HOSTNAME: 'node2'
46 | CLUSTER_GOSSIP_BIND_PORT: '7110'
47 | CLUSTER_DATA_BIND_PORT: '7111'
48 | CLUSTER_JOIN: 'weaviate-node-1:7110'
49 | RAFT_PORT: '8300'
50 | RAFT_INTERNAL_RPC_PORT: "8301"
51 | RAFT_JOIN: "node1:8300,node2:8300,node3:8300"
52 | RAFT_BOOTSTRAP_EXPECT: "3"
53 | DISABLE_TELEMETRY: 'true'
54 | CONTEXTIONARY_URL: contextionary:9999
55 | DEFAULT_VECTORIZER_MODULE: text2vec-contextionary
56 | ENABLE_MODULES: text2vec-contextionary
57 |
58 | weaviate-node-3:
59 | init: true
60 | command:
61 | - --host
62 | - 0.0.0.0
63 | - --port
64 | - '8080'
65 | - --scheme
66 | - http
67 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
68 | ports:
69 | - 8089:8080
70 | - "50060:50051"
71 | restart: on-failure:0
72 | environment:
73 | LOG_LEVEL: 'debug'
74 | QUERY_DEFAULTS_LIMIT: 20
75 | AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
76 | PERSISTENCE_DATA_PATH: './weaviate-node-2'
77 | CLUSTER_HOSTNAME: 'node3'
78 | CLUSTER_GOSSIP_BIND_PORT: '7110'
79 | CLUSTER_DATA_BIND_PORT: '7111'
80 | CLUSTER_JOIN: 'weaviate-node-1:7110'
81 | RAFT_PORT: '8300'
82 | RAFT_INTERNAL_RPC_PORT: "8301"
83 | RAFT_JOIN: "node1:8300,node2:8300,node3:8300"
84 | RAFT_BOOTSTRAP_EXPECT: "3"
85 | DISABLE_TELEMETRY: 'true'
86 | CONTEXTIONARY_URL: contextionary:9999
87 | DEFAULT_VECTORIZER_MODULE: text2vec-contextionary
88 | ENABLE_MODULES: text2vec-contextionary
89 | ...
90 |
--------------------------------------------------------------------------------
/ci/docker-compose-okta-cc.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: '3.4'
3 | services:
4 | weaviate-auth-okta-cc:
5 | command:
6 | - --host
7 | - 0.0.0.0
8 | - --port
9 | - '8082'
10 | - --scheme
11 | - http
12 | - --write-timeout=600s
13 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
14 | ports:
15 | - 8082:8082
16 | restart: on-failure:0
17 | environment:
18 | PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
19 | AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
20 | AUTHENTICATION_OIDC_ENABLED: 'true'
21 | AUTHENTICATION_OIDC_CLIENT_ID: '0oa7e9ipdkVZRUcxo5d7'
22 | AUTHENTICATION_OIDC_ISSUER: 'https://dev-32300990.okta.com/oauth2/aus7e9kxbwYQB0eht5d7'
23 | AUTHENTICATION_OIDC_USERNAME_CLAIM: 'cid'
24 | AUTHENTICATION_OIDC_GROUPS_CLAIM: 'groups'
25 | AUTHORIZATION_ADMINLIST_ENABLED: 'true'
26 | AUTHORIZATION_ADMINLIST_USERS: '0oa7e9ipdkVZRUcxo5d7'
27 | DISABLE_TELEMETRY: 'true'
28 | ...
29 |
--------------------------------------------------------------------------------
/ci/docker-compose-okta-users.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: '3.4'
3 | services:
4 | weaviate-auth-okta-users:
5 | command:
6 | - --host
7 | - 0.0.0.0
8 | - --port
9 | - '8083'
10 | - --scheme
11 | - http
12 | - --write-timeout=600s
13 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
14 | ports:
15 | - 8083:8083
16 | restart: on-failure:0
17 | environment:
18 | PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
19 | AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
20 | AUTHENTICATION_OIDC_ENABLED: 'true'
21 | AUTHENTICATION_OIDC_CLIENT_ID: '0oa7iz2g41rNxv95B5d7'
22 | AUTHENTICATION_OIDC_ISSUER: 'https://dev-32300990.okta.com/oauth2/aus7iz3tna3kckRWS5d7'
23 | AUTHENTICATION_OIDC_USERNAME_CLAIM: 'sub'
24 | AUTHENTICATION_OIDC_GROUPS_CLAIM: 'groups'
25 | AUTHORIZATION_ADMINLIST_ENABLED: 'true'
26 | AUTHORIZATION_ADMINLIST_USERS: 'test@test.de'
27 | AUTHENTICATION_OIDC_SCOPES: 'openid,email'
28 | DISABLE_TELEMETRY: 'true'
29 | ...
30 |
--------------------------------------------------------------------------------
/ci/docker-compose-openai.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: '3.4'
3 | services:
4 | weaviate_openai:
5 | command:
6 | - --host
7 | - 0.0.0.0
8 | - --port
9 | - '8086'
10 | - --scheme
11 | - http
12 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
13 | ports:
14 | - 8086:8086
15 | - 50057:50051
16 | restart: on-failure:0
17 | environment:
18 | QUERY_DEFAULTS_LIMIT: 25
19 | AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
20 | PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
21 | DEFAULT_VECTORIZER_MODULE: 'text2vec-openai'
22 | ENABLE_MODULES: 'text2vec-openai,generative-openai'
23 | CLUSTER_HOSTNAME: 'node1'
24 | DISABLE_TELEMETRY: 'true'
25 | ...
26 |
--------------------------------------------------------------------------------
/ci/docker-compose-proxy.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: '3.4'
3 | services:
4 | weaviate-proxy:
5 | command:
6 | - --host
7 | - 0.0.0.0
8 | - --port
9 | - '8020'
10 | - --scheme
11 | - http
12 | - --write-timeout=600s
13 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
14 | restart: on-failure:0
15 | environment:
16 | CONTEXTIONARY_URL: contextionary:9999
17 | QUERY_DEFAULTS_LIMIT: 25
18 | AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
19 | PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
20 | DEFAULT_VECTORIZER_MODULE: 'text2vec-contextionary'
21 | ENABLE_MODULES: text2vec-contextionary
22 | BACKUP_FILESYSTEM_PATH: "/tmp/backups"
23 | CLUSTER_GOSSIP_BIND_PORT: "7100"
24 | CLUSTER_DATA_BIND_PORT: "7101"
25 | CLUSTER_HOSTNAME: "node1"
26 | AUTOSCHEMA_ENABLED: 'false'
27 | DISABLE_TELEMETRY: 'true'
28 | GRPC_PORT: 8021
29 | proxy-http:
30 | image: envoyproxy/envoy:v1.29-latest
31 | command: envoy --config-path /etc/envoy/http.yaml
32 | ports:
33 | - 10000:10000
34 | volumes:
35 | - ./proxy:/etc/envoy
36 | proxy-grpc:
37 | image: envoyproxy/envoy:v1.29-latest
38 | command: envoy --config-path /etc/envoy/grpc.yaml
39 | ports:
40 | - 10001:10000
41 | volumes:
42 | - ./proxy:/etc/envoy
43 | ...
44 |
--------------------------------------------------------------------------------
/ci/docker-compose-rbac.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: '3.4'
3 | services:
4 | weaviate-rbac:
5 | command:
6 | - --host
7 | - 0.0.0.0
8 | - --port
9 | - '8085'
10 | - --scheme
11 | - http
12 | - --write-timeout=600s
13 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
14 | ports:
15 | - 8091:8085
16 | - 50062:50051
17 | restart: on-failure:0
18 | environment:
19 | ENABLE_MODULES: "generative-dummy,reranker-dummy"
20 | PERSISTENCE_DATA_PATH: "./data-weaviate-0"
21 | CLUSTER_IN_LOCALHOST: "true"
22 | CLUSTER_GOSSIP_BIND_PORT: "7100"
23 | CLUSTER_DATA_BIND_PORT: "7101"
24 | RAFT_BOOTSTRAP_EXPECT: "1"
25 | AUTHENTICATION_APIKEY_ENABLED: "true"
26 | AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'viewer-key,editor-key,admin-key,custom-key'
27 | AUTHENTICATION_APIKEY_USERS: 'viewer-user,editor-user,admin-user,custom-user'
28 | AUTHORIZATION_RBAC_ENABLED: "true"
29 | AUTHORIZATION_ADMIN_USERS: "admin-user"
30 | AUTHORIZATION_VIEWER_USERS: "viewer-user"
31 | AUTHENTICATION_DB_USERS_ENABLED: "true"
32 | AUTHENTICATION_OIDC_ENABLED: "true"
33 | AUTHENTICATION_OIDC_CLIENT_ID: "wcs"
34 | AUTHENTICATION_OIDC_ISSUER: "https://auth.wcs.api.weaviate.io/auth/realms/SeMI"
35 | AUTHENTICATION_OIDC_USERNAME_CLAIM: "email"
36 | AUTHENTICATION_OIDC_GROUPS_CLAIM: "groups"
37 | ...
38 |
--------------------------------------------------------------------------------
/ci/docker-compose-wcs.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: '3.4'
3 | services:
4 | weaviate-auth-wcs:
5 | command:
6 | - --host
7 | - 0.0.0.0
8 | - --port
9 | - '8085'
10 | - --scheme
11 | - http
12 | - --write-timeout=600s
13 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
14 | ports:
15 | - 8085:8085
16 | restart: on-failure:0
17 | environment:
18 | PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
19 | AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
20 | AUTHENTICATION_OIDC_ENABLED: 'true'
21 | AUTHENTICATION_OIDC_CLIENT_ID: 'wcs'
22 | AUTHENTICATION_OIDC_ISSUER: 'https://auth.wcs.api.weaviate.io/auth/realms/SeMI'
23 | AUTHENTICATION_OIDC_USERNAME_CLAIM: 'email'
24 | AUTHENTICATION_OIDC_GROUPS_CLAIM: 'groups'
25 | AUTHORIZATION_ADMINLIST_ENABLED: 'true'
26 | AUTHORIZATION_ADMINLIST_USERS: 'oidc-test-user@weaviate.io'
27 | AUTHENTICATION_OIDC_SCOPES: 'openid,email'
28 | AUTHENTICATION_APIKEY_ENABLED: 'true'
29 | AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'my-secret-key'
30 | AUTHENTICATION_APIKEY_USERS: 'oidc-test-user@weaviate.io'
31 | DISABLE_TELEMETRY: 'true'
32 | ...
33 |
--------------------------------------------------------------------------------
/ci/docker-compose.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: '3.4'
3 | services:
4 | weaviate:
5 | command:
6 | - --host
7 | - 0.0.0.0
8 | - --port
9 | - '8080'
10 | - --scheme
11 | - http
12 | - --write-timeout=600s
13 | image: semitechnologies/weaviate:${WEAVIATE_VERSION}
14 | ports:
15 | - "8080:8080"
16 | - "50051:50051"
17 | restart: on-failure:0
18 | environment:
19 | CONTEXTIONARY_URL: contextionary:9999
20 | QUERY_DEFAULTS_LIMIT: 25
21 | AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
22 | PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
23 | DEFAULT_VECTORIZER_MODULE: 'text2vec-contextionary'
24 | ENABLE_MODULES: text2vec-contextionary,backup-filesystem,generative-cohere,reranker-cohere
25 | BACKUP_FILESYSTEM_PATH: "/tmp/backups"
26 | CLUSTER_GOSSIP_BIND_PORT: "7100"
27 | CLUSTER_DATA_BIND_PORT: "7101"
28 | CLUSTER_HOSTNAME: "node1"
29 | AUTOSCHEMA_ENABLED: 'false'
30 | IMAGE_INFERENCE_API: "http://i2v-neural:8080"
31 | DISABLE_TELEMETRY: 'true'
32 | contextionary:
33 | environment:
34 | OCCURRENCE_WEIGHT_LINEAR_FACTOR: 0.75
35 | EXTENSIONS_STORAGE_MODE: weaviate
36 | EXTENSIONS_STORAGE_ORIGIN: http://weaviate:8080
37 | NEIGHBOR_OCCURRENCE_IGNORE_PERCENTILE: 5
38 | ENABLE_COMPOUND_SPLITTING: 'false'
39 | image: semitechnologies/contextionary:en0.16.0-v1.2.0
40 | ports:
41 | - 9999:9999
42 | ...
43 |
--------------------------------------------------------------------------------
/ci/proxy/grpc.yaml:
--------------------------------------------------------------------------------
1 | # This proxy configuration is one that allows the use of a gRPC proxy between Weaviate and the client.
2 | # It is used in the CI/CD pipeline to test the gRPC proxy functionality of the client.
3 | # It follows the method as described here: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/http/upgrades#connect-support
4 | # where special attention should be paid to the fact that we are using a terminating HTTP/2 connection,
5 | # as in this example: https://github.com/envoyproxy/envoy/blob/8e93d16d433d3364c2b000dc9067ffc400e8f0d6/configs/terminate_http2_connect.yaml,
6 | # because Weaviate itself is not capable of handling CONNECT requests. So Envoy instead upgrades these to POSTs and sends them on
7 | admin:
8 | address:
9 | socket_address:
10 | protocol: TCP
11 | address: 127.0.0.1
12 | port_value: 9902
13 | static_resources:
14 | listeners:
15 | - name: proxy
16 | address:
17 | socket_address:
18 | protocol: TCP
19 | address: 0.0.0.0
20 | port_value: 10000
21 | filter_chains:
22 | - filters:
23 | - name: envoy.filters.network.http_connection_manager
24 | typed_config:
25 | "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
26 | stat_prefix: ingress_http
27 | route_config:
28 | name: local_route
29 | virtual_hosts:
30 | - name: local_service
31 | domains:
32 | - "*"
33 | routes:
34 | - match:
35 | connect_matcher: {}
36 | route:
37 | cluster: weaviate-grpc
38 | upgrade_configs:
39 | - upgrade_type: CONNECT
40 | connect_config:
41 | {}
42 | http_filters:
43 | - name: envoy.filters.http.router
44 | typed_config:
45 | "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
46 | http2_protocol_options:
47 | allow_connect: true
48 | upgrade_configs:
49 | - upgrade_type: CONNECT
50 | clusters:
51 | - name: weaviate-grpc
52 | type: STRICT_DNS
53 | typed_extension_protocol_options:
54 | envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
55 | "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
56 | explicit_http_config:
57 | http2_protocol_options: {}
58 | load_assignment:
59 | cluster_name: weaviate-grpc
60 | endpoints:
61 | - lb_endpoints:
62 | - endpoint:
63 | address:
64 | socket_address:
65 | address: weaviate-proxy
66 | port_value: 8021
--------------------------------------------------------------------------------
/ci/proxy/http.yaml:
--------------------------------------------------------------------------------
1 | # This proxy configuration is one that allows the use of a gRPC proxy between Weaviate and the client.
2 | # It is used in the CI/CD pipeline to test the gRPC proxy functionality of the client.
3 | # It follows the method as described here: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/http/upgrades#connect-support
4 | # where special attention should be paid to the fact that we are using a terminating HTTP/2 connection,
5 | # as in this example: https://github.com/envoyproxy/envoy/blob/8e93d16d433d3364c2b000dc9067ffc400e8f0d6/configs/terminate_http2_connect.yaml,
6 | # because Weaviate itself is not capable of handling CONNECT requests. So Envoy instead upgrades these to POSTs and sends them on
7 | admin:
8 | address:
9 | socket_address:
10 | protocol: TCP
11 | address: 127.0.0.1
12 | port_value: 9902
13 | static_resources:
14 | listeners:
15 | - name: proxy
16 | address:
17 | socket_address:
18 | protocol: TCP
19 | address: 0.0.0.0
20 | port_value: 10000
21 | filter_chains:
22 | - filters:
23 | - name: envoy.filters.network.http_connection_manager
24 | typed_config:
25 | "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
26 | stat_prefix: ingress_http
27 | codec_type: HTTP1
28 | route_config:
29 | name: local_route
30 | virtual_hosts:
31 | - name: local_service
32 | domains:
33 | - "*"
34 | routes:
35 | - match:
36 | prefix: "/http"
37 | route:
38 | prefix_rewrite: "/"
39 | cluster: weaviate-http
40 | http_filters:
41 | - name: envoy.filters.http.router
42 | typed_config:
43 | "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
44 |
45 | clusters:
46 | - name: weaviate-http
47 | type: STRICT_DNS
48 | connect_timeout: 5s
49 | lb_policy: ROUND_ROBIN
50 | load_assignment:
51 | cluster_name: weaviate-http
52 | endpoints:
53 | - lb_endpoints:
54 | - endpoint:
55 | address:
56 | socket_address:
57 | address: weaviate-proxy
58 | port_value: 8020
--------------------------------------------------------------------------------
/ci/run_dependencies.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -eou pipefail
4 |
5 | export WEAVIATE_VERSION=$1
6 |
7 | source ./ci/compose.sh
8 |
9 | echo "Stop existing session if running"
10 | compose_down_all
11 | rm -rf weaviate-data || true
12 |
13 | echo "Run Docker compose"
14 | compose_up_all
15 |
16 | echo "Wait until all containers are up"
17 |
18 | function wait(){
19 | MAX_WAIT_SECONDS=60
20 | ALREADY_WAITING=0
21 |
22 | echo "Waiting for $1"
23 | while true; do
24 | # first check if weaviate already responds
25 | if ! curl -s $1 > /dev/null; then
26 | continue
27 | fi
28 |
29 | # endpoint available, check if it is ready
30 | HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$1/v1/.well-known/ready")
31 |
32 | if [ "$HTTP_STATUS" -eq 200 ]; then
33 | break
34 | else
35 | echo "Weaviate is not up yet. (waited for ${ALREADY_WAITING}s)"
36 | if [ $ALREADY_WAITING -gt $MAX_WAIT_SECONDS ]; then
37 | echo "Weaviate did not start up in $MAX_WAIT_SECONDS."
38 | exit 1
39 | else
40 | sleep 2
41 | let ALREADY_WAITING=$ALREADY_WAITING+2
42 | fi
43 | fi
44 | done
45 |
46 | echo "Weaviate is up and running!"
47 | }
48 |
49 | for port in $(all_weaviate_ports); do
50 | wait "http://localhost:$port"
51 | done
52 |
53 | echo "All containers running"
54 |
--------------------------------------------------------------------------------
/ci/stop_dependencies.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -eou pipefail
4 |
5 | export WEAVIATE_VERSION=$1
6 |
7 | source ./ci/compose.sh
8 |
9 | compose_down_all
10 | rm -rf weaviate-data || true
11 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | # Weaviate TypeScript Client Examples
2 |
3 | These examples reflect the most current state of the client and its features, so please make sure that you have the latest version of `weaviate-ts-client` installed 🙂
4 |
5 | ## JavaScript
6 |
7 | Usage within a CommonJS project.
8 |
9 | ## TypeScipt
10 |
11 | TypeScript & ESM JavaScript usage.
12 |
--------------------------------------------------------------------------------
/examples/javascript/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 |
--------------------------------------------------------------------------------
/examples/javascript/index.js:
--------------------------------------------------------------------------------
1 | const { default: weaviate } = require('weaviate-ts-client');
2 |
3 | const client = weaviate.client({
4 | scheme: 'http',
5 | host: 'localhost:8080',
6 | });
7 |
8 | console.log(
9 | JSON.stringify(
10 | new weaviate.AuthAccessTokenCredentials({
11 | accessToken: 'token123',
12 | expiresIn: 123,
13 | })
14 | )
15 | );
16 |
17 | console.log(
18 | JSON.stringify(
19 | new weaviate.AuthUserPasswordCredentials({
20 | username: 'user123',
21 | password: 'password',
22 | })
23 | )
24 | );
25 |
26 | console.log(
27 | JSON.stringify(
28 | new weaviate.AuthClientCredentials({
29 | clientSecret: 'secret123',
30 | })
31 | )
32 | );
33 |
34 | console.log(JSON.stringify(new weaviate.ApiKey('abcd1234')));
35 |
36 | client.misc
37 | .metaGetter()
38 | .do()
39 | .then((res) => console.log(`res: ${JSON.stringify(res)}`));
40 |
--------------------------------------------------------------------------------
/examples/javascript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "weaviate-js-example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "dependencies": {
7 | "weaviate-ts-client": "latest"
8 | },
9 | "scripts": {
10 | "start": "node index.js"
11 | },
12 | "author": "",
13 | "license": "ISC"
14 | }
15 |
--------------------------------------------------------------------------------
/examples/typescript/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | package-lock.json
4 |
--------------------------------------------------------------------------------
/examples/typescript/index.ts:
--------------------------------------------------------------------------------
1 | import weaviate, {
2 | ApiKey,
3 | AuthAccessTokenCredentials,
4 | AuthClientCredentials,
5 | AuthUserPasswordCredentials,
6 | generateUuid5,
7 | } from 'weaviate-ts-client';
8 |
9 | const client = weaviate.client({
10 | scheme: 'http',
11 | host: 'localhost:8080',
12 | });
13 |
14 | console.log(
15 | JSON.stringify(
16 | new AuthAccessTokenCredentials({
17 | accessToken: 'token123',
18 | expiresIn: 123,
19 | })
20 | )
21 | );
22 |
23 | console.log(
24 | JSON.stringify(
25 | new AuthUserPasswordCredentials({
26 | username: 'user123',
27 | password: 'password',
28 | })
29 | )
30 | );
31 |
32 | console.log(
33 | JSON.stringify(
34 | new AuthClientCredentials({
35 | clientSecret: 'secret123',
36 | })
37 | )
38 | );
39 |
40 | console.log(JSON.stringify(new ApiKey('abcd1234')));
41 | console.log(generateUuid5('55dfccce-0142-4807-a1ff-60be9b38f5cc', 'the-best-namespace'));
42 |
43 | client.misc
44 | .metaGetter()
45 | .do()
46 | .then((res: any) => console.log(`res: ${JSON.stringify(res)}`));
47 |
--------------------------------------------------------------------------------
/examples/typescript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "weaviate-ts-example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "dist/index.js",
6 | "types": "dist/index.d.ts",
7 | "type": "module",
8 | "dependencies": {
9 | "weaviate-ts-client": "latest"
10 | },
11 | "scripts": {
12 | "start": "tsc && node dist/index.js"
13 | },
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "typescript": "^4.9.5"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/examples/typescript/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2020",
4 | "strict": true,
5 | "preserveConstEnums": true,
6 | "noEmit": false,
7 | "sourceMap": false,
8 | "module":"ES2022",
9 | "moduleResolution":"node",
10 | "esModuleInterop": true,
11 | "skipLibCheck": true,
12 | "forceConsistentCasingInFileNames": true,
13 | "isolatedModules": true,
14 | "outDir": "./dist"
15 | },
16 | "include": ["**/*"],
17 | "exclude": ["node_modules"]
18 | }
19 |
--------------------------------------------------------------------------------
/jest.config.ts:
--------------------------------------------------------------------------------
1 | import { JestConfigWithTsJest } from 'ts-jest';
2 |
3 | const config: JestConfigWithTsJest = {
4 | clearMocks: false,
5 | collectCoverage: false,
6 | coverageDirectory: 'coverage',
7 | coveragePathIgnorePatterns: ['/node_modules/', '/dist/', '/src/proto'],
8 | coverageProvider: 'v8',
9 | preset: 'ts-jest/presets/default-esm', // or other ESM presets
10 | moduleNameMapper: {
11 | '^(\\.{1,2}/.*)\\.js$': '$1',
12 | },
13 | transform: {
14 | // '^.+\\.[tj]sx?$' to process js/ts with `ts-jest`
15 | // '^.+\\.m?[tj]sx?$' to process js/ts/mjs/mts with `ts-jest`
16 | '^.+\\.tsx?$': [
17 | 'ts-jest',
18 | {
19 | useESM: true,
20 | },
21 | ],
22 | },
23 | testEnvironment: 'node',
24 | testMatch: ['**/*.test.ts'],
25 | testTimeout: 100000,
26 | };
27 |
28 | export default config;
29 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weaviate/typescript-client/f7591d649b05929c5a45b601fecd468935447b9a/public/favicon.ico
--------------------------------------------------------------------------------
/src/backup/backupCreateStatusGetter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { WeaviateInvalidInputError } from '../errors.js';
3 | import { BackupCreateStatusResponse } from '../openapi/types.js';
4 | import { CommandBase } from '../validation/commandBase.js';
5 | import { Backend } from './index.js';
6 | import { validateBackend, validateBackupId } from './validation.js';
7 |
8 | export default class BackupCreateStatusGetter extends CommandBase {
9 | private backend?: Backend;
10 | private backupId?: string;
11 |
12 | constructor(client: Connection) {
13 | super(client);
14 | }
15 |
16 | withBackend(backend: Backend) {
17 | this.backend = backend;
18 | return this;
19 | }
20 |
21 | withBackupId(backupId: string) {
22 | this.backupId = backupId;
23 | return this;
24 | }
25 |
26 | validate = (): void => {
27 | this.addErrors([...validateBackend(this.backend), ...validateBackupId(this.backupId)]);
28 | };
29 |
30 | do = (): Promise => {
31 | this.validate();
32 | if (this.errors.length > 0) {
33 | return Promise.reject(new WeaviateInvalidInputError('invalid usage: ' + this.errors.join(', ')));
34 | }
35 | return this.client.get(this._path()) as Promise;
36 | };
37 |
38 | private _path = (): string => {
39 | return `/backups/${this.backend}/${this.backupId}`;
40 | };
41 | }
42 |
--------------------------------------------------------------------------------
/src/backup/backupGetter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { WeaviateInvalidInputError } from '../errors.js';
3 | import { BackupCreateResponse } from '../openapi/types.js';
4 | import { CommandBase } from '../validation/commandBase.js';
5 | import { Backend } from './index.js';
6 | import { validateBackend } from './validation.js';
7 |
8 | export default class BackupGetter extends CommandBase {
9 | private backend?: Backend;
10 |
11 | constructor(client: Connection) {
12 | super(client);
13 | }
14 |
15 | withBackend(backend: Backend) {
16 | this.backend = backend;
17 | return this;
18 | }
19 |
20 | validate = (): void => {
21 | this.addErrors(validateBackend(this.backend));
22 | };
23 |
24 | do = (): Promise => {
25 | this.validate();
26 | if (this.errors.length > 0) {
27 | return Promise.reject(new WeaviateInvalidInputError('invalid usage: ' + this.errors.join(', ')));
28 | }
29 |
30 | return this.client.get(this._path());
31 | };
32 |
33 | private _path = (): string => {
34 | return `/backups/${this.backend}`;
35 | };
36 | }
37 |
--------------------------------------------------------------------------------
/src/backup/backupRestoreStatusGetter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { WeaviateInvalidInputError } from '../errors.js';
3 | import { BackupRestoreStatusResponse } from '../openapi/types.js';
4 | import { CommandBase } from '../validation/commandBase.js';
5 | import { Backend } from './index.js';
6 | import { validateBackend, validateBackupId } from './validation.js';
7 |
8 | export default class BackupRestoreStatusGetter extends CommandBase {
9 | private backend?: Backend;
10 | private backupId?: string;
11 |
12 | constructor(client: Connection) {
13 | super(client);
14 | }
15 |
16 | withBackend(backend: Backend) {
17 | this.backend = backend;
18 | return this;
19 | }
20 |
21 | withBackupId(backupId: string) {
22 | this.backupId = backupId;
23 | return this;
24 | }
25 |
26 | validate = (): void => {
27 | this.addErrors([...validateBackend(this.backend), ...validateBackupId(this.backupId)]);
28 | };
29 |
30 | do = (): Promise => {
31 | this.validate();
32 | if (this.errors.length > 0) {
33 | return Promise.reject(new WeaviateInvalidInputError('invalid usage: ' + this.errors.join(', ')));
34 | }
35 |
36 | return this.client.get(this._path());
37 | };
38 |
39 | private _path = (): string => {
40 | return `/backups/${this.backend}/${this.backupId}/restore`;
41 | };
42 | }
43 |
--------------------------------------------------------------------------------
/src/backup/index.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import BackupCreateStatusGetter from './backupCreateStatusGetter.js';
3 | import BackupCreator from './backupCreator.js';
4 | import BackupRestoreStatusGetter from './backupRestoreStatusGetter.js';
5 | import BackupRestorer from './backupRestorer.js';
6 |
7 | export type Backend = 'filesystem' | 's3' | 'gcs' | 'azure';
8 | export type BackupStatus = 'STARTED' | 'TRANSFERRING' | 'TRANSFERRED' | 'SUCCESS' | 'FAILED';
9 | export type BackupCompressionLevel = 'DefaultCompression' | 'BestSpeed' | 'BestCompression';
10 |
11 | export interface Backup {
12 | creator: () => BackupCreator;
13 | createStatusGetter: () => BackupCreateStatusGetter;
14 | restorer: () => BackupRestorer;
15 | restoreStatusGetter: () => BackupRestoreStatusGetter;
16 | }
17 |
18 | const backup = (client: Connection): Backup => {
19 | return {
20 | creator: () => new BackupCreator(client, new BackupCreateStatusGetter(client)),
21 | createStatusGetter: () => new BackupCreateStatusGetter(client),
22 | restorer: () => new BackupRestorer(client, new BackupRestoreStatusGetter(client)),
23 | restoreStatusGetter: () => new BackupRestoreStatusGetter(client),
24 | };
25 | };
26 |
27 | export default backup;
28 | export { default as BackupCreateStatusGetter } from './backupCreateStatusGetter.js';
29 | export { default as BackupCreator } from './backupCreator.js';
30 | export { default as BackupRestoreStatusGetter } from './backupRestoreStatusGetter.js';
31 | export { default as BackupRestorer } from './backupRestorer.js';
32 |
--------------------------------------------------------------------------------
/src/backup/validation.ts:
--------------------------------------------------------------------------------
1 | import { isValidStringProperty } from '../validation/string.js';
2 |
3 | export function validateIncludeClassNames(classNames?: string[]) {
4 | if (Array.isArray(classNames)) {
5 | const errors: any[] = [];
6 | classNames.forEach((className) => {
7 | if (!isValidStringProperty(className)) {
8 | errors.push('string className invalid - set with .withIncludeClassNames(...classNames)');
9 | }
10 | });
11 | return errors;
12 | }
13 | if (classNames !== null && classNames !== undefined) {
14 | return ['strings classNames invalid - set with .withIncludeClassNames(...classNames)'];
15 | }
16 | return [];
17 | }
18 |
19 | export function validateExcludeClassNames(classNames?: string[]) {
20 | if (Array.isArray(classNames)) {
21 | const errors: any[] = [];
22 | classNames.forEach((className) => {
23 | if (!isValidStringProperty(className)) {
24 | errors.push('string className invalid - set with .withExcludeClassNames(...classNames)');
25 | }
26 | });
27 | return errors;
28 | }
29 | if (classNames !== null && classNames !== undefined) {
30 | return ['strings classNames invalid - set with .withExcludeClassNames(...classNames)'];
31 | }
32 | return [];
33 | }
34 |
35 | export function validateBackend(backend?: string) {
36 | if (!isValidStringProperty(backend)) {
37 | return ['string backend must set - set with .withBackend(backend)'];
38 | }
39 | return [];
40 | }
41 |
42 | export function validateBackupId(backupId?: string) {
43 | if (!isValidStringProperty(backupId)) {
44 | return ['string backupId must be set - set with .withBackupId(backupId)'];
45 | }
46 | return [];
47 | }
48 |
--------------------------------------------------------------------------------
/src/batch/index.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { BeaconPath } from '../utils/beaconPath.js';
3 | import { DbVersionSupport } from '../utils/dbVersion.js';
4 | import ObjectsBatchDeleter from './objectsBatchDeleter.js';
5 | import ObjectsBatcher from './objectsBatcher.js';
6 | import ReferencePayloadBuilder from './referencePayloadBuilder.js';
7 | import ReferencesBatcher from './referencesBatcher.js';
8 |
9 | export type DeleteOutput = 'verbose' | 'minimal';
10 | export type DeleteResultStatus = 'SUCCESS' | 'FAILED' | 'DRYRUN';
11 |
12 | export interface Batch {
13 | objectsBatcher: () => ObjectsBatcher;
14 | objectsBatchDeleter: () => ObjectsBatchDeleter;
15 | referencesBatcher: () => ReferencesBatcher;
16 | referencePayloadBuilder: () => ReferencePayloadBuilder;
17 | }
18 |
19 | const batch = (client: Connection, dbVersionSupport: DbVersionSupport): Batch => {
20 | const beaconPath = new BeaconPath(dbVersionSupport);
21 |
22 | return {
23 | objectsBatcher: () => new ObjectsBatcher(client),
24 | objectsBatchDeleter: () => new ObjectsBatchDeleter(client),
25 | referencesBatcher: () => new ReferencesBatcher(client, beaconPath),
26 | referencePayloadBuilder: () => new ReferencePayloadBuilder(client),
27 | };
28 | };
29 |
30 | export default batch;
31 | export { default as ObjectsBatchDeleter } from './objectsBatchDeleter.js';
32 | export { default as ObjectsBatcher } from './objectsBatcher.js';
33 | export { default as ReferencesBatcher } from './referencesBatcher.js';
34 |
--------------------------------------------------------------------------------
/src/batch/objectsBatchDeleter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { ConsistencyLevel } from '../data/replication.js';
3 | import { BatchDelete, BatchDeleteResponse, WhereFilter } from '../openapi/types.js';
4 | import { CommandBase } from '../validation/commandBase.js';
5 | import { isValidStringProperty } from '../validation/string.js';
6 | import { DeleteOutput } from './index.js';
7 | import { buildObjectsPath } from './path.js';
8 |
9 | export default class ObjectsBatchDeleter extends CommandBase {
10 | private className?: string;
11 | private consistencyLevel?: ConsistencyLevel;
12 | private dryRun?: boolean;
13 | private output?: DeleteOutput;
14 | private whereFilter?: WhereFilter;
15 | private tenant?: string;
16 |
17 | constructor(client: Connection) {
18 | super(client);
19 | }
20 |
21 | withClassName(className: string) {
22 | this.className = className;
23 | return this;
24 | }
25 |
26 | withWhere(whereFilter: WhereFilter) {
27 | this.whereFilter = whereFilter;
28 | return this;
29 | }
30 |
31 | withOutput(output: DeleteOutput) {
32 | this.output = output;
33 | return this;
34 | }
35 |
36 | withDryRun(dryRun: boolean) {
37 | this.dryRun = dryRun;
38 | return this;
39 | }
40 |
41 | withConsistencyLevel = (cl: ConsistencyLevel) => {
42 | this.consistencyLevel = cl;
43 | return this;
44 | };
45 |
46 | withTenant(tenant: string) {
47 | this.tenant = tenant;
48 | return this;
49 | }
50 |
51 | payload = (): BatchDelete => {
52 | return {
53 | match: {
54 | class: this.className,
55 | where: this.whereFilter,
56 | },
57 | output: this.output,
58 | dryRun: this.dryRun,
59 | };
60 | };
61 |
62 | validateClassName = (): void => {
63 | if (!isValidStringProperty(this.className)) {
64 | this.addError('string className must be set - set with .withClassName(className)');
65 | }
66 | };
67 |
68 | validateWhereFilter = (): void => {
69 | if (typeof this.whereFilter != 'object') {
70 | this.addError('object where must be set - set with .withWhere(whereFilter)');
71 | }
72 | };
73 |
74 | validate = (): void => {
75 | this.validateClassName();
76 | this.validateWhereFilter();
77 | };
78 |
79 | do = (): Promise => {
80 | this.validate();
81 | if (this.errors.length > 0) {
82 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
83 | }
84 | const params = new URLSearchParams();
85 | if (this.consistencyLevel) {
86 | params.set('consistency_level', this.consistencyLevel);
87 | }
88 | if (this.tenant) {
89 | params.set('tenant', this.tenant);
90 | }
91 | const path = buildObjectsPath(params);
92 | return this.client.delete(path, this.payload(), true);
93 | };
94 | }
95 |
--------------------------------------------------------------------------------
/src/batch/objectsBatcher.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { ConsistencyLevel } from '../data/replication.js';
3 | import { BatchRequest, WeaviateObject, WeaviateObjectsGet } from '../openapi/types.js';
4 | import { CommandBase } from '../validation/commandBase.js';
5 | import { buildObjectsPath } from './path.js';
6 |
7 | export default class ObjectsBatcher extends CommandBase {
8 | private consistencyLevel?: ConsistencyLevel;
9 | public objects: WeaviateObject[];
10 |
11 | constructor(client: Connection) {
12 | super(client);
13 | this.objects = [];
14 | }
15 |
16 | /**
17 | * can be called as:
18 | * - withObjects(...[obj1, obj2, obj3])
19 | * - withObjects(obj1, obj2, obj3)
20 | * - withObjects(obj1)
21 | * @param {...WeaviateObject[]} objects
22 | */
23 | withObjects(...objects: WeaviateObject[]) {
24 | let objs = objects;
25 | if (objects.length && Array.isArray(objects[0])) {
26 | objs = objects[0];
27 | }
28 | this.objects = [...this.objects, ...objs];
29 | return this;
30 | }
31 |
32 | withObject(object: WeaviateObject) {
33 | return this.withObjects(object);
34 | }
35 |
36 | withConsistencyLevel = (cl: ConsistencyLevel) => {
37 | this.consistencyLevel = cl;
38 | return this;
39 | };
40 |
41 | payload = (): BatchRequest => ({
42 | objects: this.objects,
43 | });
44 |
45 | validateObjectCount = (): void => {
46 | if (this.objects.length == 0) {
47 | this.addError('need at least one object to send a request, add one with .withObject(obj)');
48 | }
49 | };
50 |
51 | validate = (): void => {
52 | this.validateObjectCount();
53 | };
54 |
55 | do = (): Promise => {
56 | this.validate();
57 | if (this.errors.length > 0) {
58 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
59 | }
60 | const params = new URLSearchParams();
61 | if (this.consistencyLevel) {
62 | params.set('consistency_level', this.consistencyLevel);
63 | }
64 | const path = buildObjectsPath(params);
65 | return this.client.postReturn(path, this.payload());
66 | };
67 | }
68 |
--------------------------------------------------------------------------------
/src/batch/path.test.ts:
--------------------------------------------------------------------------------
1 | import { buildObjectsPath, buildRefsPath } from './path.js';
2 |
3 | describe('paths', () => {
4 | it('builds batch objects without params', () => {
5 | const path = buildObjectsPath(new URLSearchParams());
6 | expect(path).toEqual('/batch/objects');
7 | });
8 |
9 | it('builds batch objects with params', () => {
10 | const path = buildObjectsPath(
11 | new URLSearchParams({
12 | consistency_level: 'ONE',
13 | })
14 | );
15 | expect(path).toEqual('/batch/objects?consistency_level=ONE');
16 | });
17 |
18 | it('builds batch references without params', () => {
19 | const path = buildRefsPath(new URLSearchParams());
20 | expect(path).toEqual('/batch/references');
21 | });
22 |
23 | it('builds batch object with params', () => {
24 | const path = buildRefsPath(
25 | new URLSearchParams({
26 | consistency_level: 'ONE',
27 | })
28 | );
29 | expect(path).toEqual('/batch/references?consistency_level=ONE');
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/src/batch/path.ts:
--------------------------------------------------------------------------------
1 | export function buildObjectsPath(queryParams: any): string {
2 | const path = '/batch/objects';
3 | return buildPath(path, queryParams);
4 | }
5 |
6 | export function buildRefsPath(queryParams: any): string {
7 | const path = '/batch/references';
8 | return buildPath(path, queryParams);
9 | }
10 |
11 | function buildPath(path: string, queryParams: any): string {
12 | if (queryParams && queryParams.toString() != '') {
13 | path = `${path}?${queryParams.toString()}`;
14 | }
15 | return path;
16 | }
17 |
--------------------------------------------------------------------------------
/src/batch/referencePayloadBuilder.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { BatchReference } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { isValidStringProperty } from '../validation/string.js';
5 |
6 | export default class ReferencesBatcher extends CommandBase {
7 | private fromClassName?: string;
8 | private fromId?: string;
9 | private fromRefProp?: string;
10 | private toClassName?: string;
11 | private toId?: string;
12 |
13 | constructor(client: Connection) {
14 | super(client);
15 | }
16 |
17 | withFromId = (id: string) => {
18 | this.fromId = id;
19 | return this;
20 | };
21 |
22 | withToId = (id: string) => {
23 | this.toId = id;
24 | return this;
25 | };
26 |
27 | withFromClassName = (className: string) => {
28 | this.fromClassName = className;
29 | return this;
30 | };
31 |
32 | withFromRefProp = (refProp: string) => {
33 | this.fromRefProp = refProp;
34 | return this;
35 | };
36 |
37 | withToClassName(className: string) {
38 | this.toClassName = className;
39 | return this;
40 | }
41 |
42 | validateIsSet = (prop: string | undefined | null, name: string, setter: string): void => {
43 | if (prop == undefined || prop == null || prop.length == 0) {
44 | this.addError(`${name} must be set - set with ${setter}`);
45 | }
46 | };
47 |
48 | validate = (): void => {
49 | this.validateIsSet(this.fromId, 'fromId', '.withFromId(id)');
50 | this.validateIsSet(this.toId, 'toId', '.withToId(id)');
51 | this.validateIsSet(this.fromClassName, 'fromClassName', '.withFromClassName(className)');
52 | this.validateIsSet(this.fromRefProp, 'fromRefProp', '.withFromRefProp(refProp)');
53 | };
54 |
55 | payload = (): BatchReference => {
56 | this.validate();
57 | if (this.errors.length > 0) {
58 | throw new Error(this.errors.join(', '));
59 | }
60 |
61 | let beaconTo = `weaviate://localhost`;
62 | if (isValidStringProperty(this.toClassName)) {
63 | beaconTo = `${beaconTo}/${this.toClassName}`;
64 | }
65 |
66 | return {
67 | from: `weaviate://localhost/${this.fromClassName}/${this.fromId}/${this.fromRefProp}`,
68 | to: `${beaconTo}/${this.toId}`,
69 | };
70 | };
71 |
72 | do = (): Promise => {
73 | return Promise.reject(new Error('Should never be called'));
74 | };
75 | }
76 |
--------------------------------------------------------------------------------
/src/batch/referencesBatcher.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { ConsistencyLevel } from '../data/replication.js';
3 | import { BatchReference, BatchReferenceResponse } from '../openapi/types.js';
4 | import { BeaconPath } from '../utils/beaconPath.js';
5 | import { CommandBase } from '../validation/commandBase.js';
6 | import { buildRefsPath } from './path.js';
7 |
8 | export default class ReferencesBatcher extends CommandBase {
9 | private beaconPath: BeaconPath;
10 | private consistencyLevel?: ConsistencyLevel;
11 | public references: BatchReference[];
12 |
13 | constructor(client: Connection, beaconPath: BeaconPath) {
14 | super(client);
15 | this.beaconPath = beaconPath;
16 | this.references = [];
17 | }
18 |
19 | /**
20 | * can be called as:
21 | * - withReferences(...[ref1, ref2, ref3])
22 | * - withReferences(ref1, ref2, ref3)
23 | * - withReferences(ref1)
24 | * @param {...BatchReference[]} references
25 | */
26 | withReferences(...references: BatchReference[]) {
27 | let refs = references;
28 | if (references.length && Array.isArray(references[0])) {
29 | refs = references[0];
30 | }
31 | this.references = [...this.references, ...refs];
32 | return this;
33 | }
34 |
35 | withReference(reference: BatchReference) {
36 | return this.withReferences(reference);
37 | }
38 |
39 | withConsistencyLevel = (cl: ConsistencyLevel) => {
40 | this.consistencyLevel = cl;
41 | return this;
42 | };
43 |
44 | payload = (): BatchReference[] => this.references;
45 |
46 | validateReferenceCount = (): void => {
47 | if (this.references.length == 0) {
48 | this.addError('need at least one reference to send a request, add one with .withReference(obj)');
49 | }
50 | };
51 |
52 | validate = () => {
53 | this.validateReferenceCount();
54 | };
55 |
56 | do = (): Promise => {
57 | this.validate();
58 | if (this.errors.length > 0) {
59 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
60 | }
61 | const params = new URLSearchParams();
62 | if (this.consistencyLevel) {
63 | params.set('consistency_level', this.consistencyLevel);
64 | }
65 | const path = buildRefsPath(params);
66 | const payloadPromise = Promise.all(this.references.map((ref) => this.rebuildReferencePromise(ref)));
67 |
68 | return payloadPromise.then((payload) => this.client.postReturn(path, payload));
69 | };
70 |
71 | rebuildReferencePromise = (reference: BatchReference): Promise => {
72 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
73 | return this.beaconPath.rebuild(reference.to!).then((beaconTo: any) => ({
74 | from: reference.from,
75 | to: beaconTo,
76 | tenant: reference.tenant,
77 | }));
78 | };
79 | }
80 |
--------------------------------------------------------------------------------
/src/c11y/conceptsGetter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { C11yWordsResponse } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class ConceptsGetter extends CommandBase {
6 | private concept?: string;
7 |
8 | constructor(client: Connection) {
9 | super(client);
10 | }
11 |
12 | validateIsSet = (prop: string | undefined | null, name: string, setter: string) => {
13 | if (prop == undefined || prop == null || prop.length == 0) {
14 | this.addError(`${name} must be set - set with ${setter}`);
15 | }
16 | };
17 |
18 | withConcept = (concept: string) => {
19 | this.concept = concept;
20 | return this;
21 | };
22 |
23 | validate = (): void => {
24 | this.validateIsSet(this.concept, 'concept', 'withConcept(concept)');
25 | };
26 |
27 | do = (): Promise => {
28 | this.validate();
29 | if (this.errors.length > 0) {
30 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
31 | }
32 |
33 | const path = `/modules/text2vec-contextionary/concepts/${this.concept}`;
34 | return this.client.get(path);
35 | };
36 | }
37 |
--------------------------------------------------------------------------------
/src/c11y/extensionCreator.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { C11yExtension } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class ExtensionCreator extends CommandBase {
6 | private concept?: string;
7 | private definition?: string;
8 | private weight?: number;
9 |
10 | constructor(client: Connection) {
11 | super(client);
12 | }
13 |
14 | withConcept = (concept: string) => {
15 | this.concept = concept;
16 | return this;
17 | };
18 |
19 | withDefinition = (definition: string) => {
20 | this.definition = definition;
21 | return this;
22 | };
23 |
24 | withWeight = (weight: number) => {
25 | this.weight = weight;
26 | return this;
27 | };
28 |
29 | validateIsSet = (prop: string | undefined | null, name: string, setter: string): void => {
30 | if (prop == undefined || prop == null || prop.length == 0) {
31 | this.addError(`${name} must be set - set with ${setter}`);
32 | }
33 | };
34 |
35 | validate = (): void => {
36 | this.validateIsSet(this.concept, 'concept', 'withConcept(concept)');
37 | this.validateIsSet(this.definition, 'definition', 'withDefinition(definition)');
38 | this.validateIsSet(this.weight?.toString() || '', 'weight', 'withWeight(weight)');
39 | };
40 |
41 | payload = (): C11yExtension => ({
42 | concept: this.concept,
43 | definition: this.definition,
44 | weight: this.weight,
45 | });
46 |
47 | do = (): Promise => {
48 | this.validate();
49 | if (this.errors.length > 0) {
50 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
51 | }
52 |
53 | const path = `/modules/text2vec-contextionary/extensions`;
54 | return this.client.postReturn(path, this.payload());
55 | };
56 | }
57 |
--------------------------------------------------------------------------------
/src/c11y/index.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import ConceptsGetter from './conceptsGetter.js';
3 | import ExtensionCreator from './extensionCreator.js';
4 |
5 | export interface C11y {
6 | conceptsGetter: () => ConceptsGetter;
7 | extensionCreator: () => ExtensionCreator;
8 | }
9 |
10 | const c11y = (client: Connection): C11y => {
11 | return {
12 | conceptsGetter: () => new ConceptsGetter(client),
13 | extensionCreator: () => new ExtensionCreator(client),
14 | };
15 | };
16 |
17 | export default c11y;
18 | export { default as ConceptsGetter } from './conceptsGetter.js';
19 | export { default as ExtensionCreator } from './extensionCreator.js';
20 |
--------------------------------------------------------------------------------
/src/c11y/journey.test.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-non-null-assertion */
2 | import { C11yExtension, C11yWordsResponse } from '../openapi/types.js';
3 | import weaviate from '../v2/index.js';
4 |
5 | describe('c11y endpoints', () => {
6 | const client = weaviate.client({
7 | scheme: 'http',
8 | host: 'localhost:8080',
9 | });
10 |
11 | it('displays info about a concept', () => {
12 | return client.c11y
13 | .conceptsGetter()
14 | .withConcept('car')
15 | .do()
16 | .then((res: C11yWordsResponse) => {
17 | expect(res.individualWords![0].word!).toEqual('car');
18 | });
19 | });
20 |
21 | it('extends the c11y with a custom concept', () => {
22 | return client.c11y
23 | .extensionCreator()
24 | .withConcept('clientalmostdonehappyness')
25 | .withDefinition(
26 | 'the happyness you feel when the Weaviate TypeScript client ' +
27 | 'is almost complete and ready to be released'
28 | )
29 | .withWeight(1)
30 | .do()
31 | .then((res: C11yExtension) => {
32 | expect(res).toEqual({
33 | concept: 'clientalmostdonehappyness',
34 | definition:
35 | 'the happyness you feel when the Weaviate TypeScript client ' +
36 | 'is almost complete and ready to be released',
37 | weight: 1,
38 | });
39 | });
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/src/classifications/getter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Classification } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class ClassificationsGetter extends CommandBase {
6 | private id?: string;
7 |
8 | constructor(client: Connection) {
9 | super(client);
10 | }
11 |
12 | withId = (id: string) => {
13 | this.id = id;
14 | return this;
15 | };
16 |
17 | validateIsSet = (prop: string | undefined | null, name: string, setter: string): void => {
18 | if (prop == undefined || prop == null || prop.length == 0) {
19 | this.addError(`${name} must be set - set with ${setter}`);
20 | }
21 | };
22 |
23 | validateId = (): void => {
24 | this.validateIsSet(this.id, 'id', '.withId(id)');
25 | };
26 |
27 | validate = (): void => {
28 | this.validateId();
29 | };
30 |
31 | do = (): Promise => {
32 | this.validate();
33 | if (this.errors.length > 0) {
34 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
35 | }
36 |
37 | const path = `/classifications/${this.id}`;
38 | return this.client.get(path);
39 | };
40 | }
41 |
--------------------------------------------------------------------------------
/src/classifications/index.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import ClassificationsGetter from './getter.js';
3 | import ClassificationsScheduler from './scheduler.js';
4 |
5 | export interface Classifications {
6 | scheduler: () => ClassificationsScheduler;
7 | getter: () => ClassificationsGetter;
8 | }
9 |
10 | const data = (client: Connection): Classifications => {
11 | return {
12 | scheduler: () => new ClassificationsScheduler(client),
13 | getter: () => new ClassificationsGetter(client),
14 | };
15 | };
16 |
17 | export default data;
18 | export { default as ClassificationsGetter } from './getter.js';
19 | export { default as ClassificationsScheduler } from './scheduler.js';
20 |
--------------------------------------------------------------------------------
/src/cluster/index.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import NodesStatusGetter from './nodesStatusGetter.js';
3 |
4 | export type NodeStatus = 'HEALTHY' | 'UNHEALTHY' | 'UNAVAILABLE';
5 |
6 | export interface Cluster {
7 | nodesStatusGetter: () => NodesStatusGetter;
8 | }
9 |
10 | const cluster = (client: Connection): Cluster => {
11 | return {
12 | nodesStatusGetter: () => new NodesStatusGetter(client),
13 | };
14 | };
15 |
16 | export default cluster;
17 | export { default as NodesStatusGetter } from './nodesStatusGetter.js';
18 |
--------------------------------------------------------------------------------
/src/cluster/nodesStatusGetter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { NodesStatusResponse } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class NodesStatusGetter extends CommandBase {
6 | private className?: string;
7 | private output?: string;
8 |
9 | constructor(client: Connection) {
10 | super(client);
11 | }
12 |
13 | withClassName = (className: string) => {
14 | this.className = className;
15 | return this;
16 | };
17 |
18 | withOutput = (output: 'minimal' | 'verbose') => {
19 | this.output = output;
20 | return this;
21 | };
22 |
23 | validate() {
24 | // nothing to validate
25 | }
26 |
27 | do = (): Promise => {
28 | let path = '/nodes';
29 | if (this.className) {
30 | path = `${path}/${this.className}`;
31 | }
32 | if (this.output) {
33 | path = `${path}?output=${this.output}`;
34 | } else {
35 | path = `${path}?output=verbose`;
36 | }
37 | return this.client.get(path);
38 | };
39 | }
40 |
--------------------------------------------------------------------------------
/src/collections/backup/collection.ts:
--------------------------------------------------------------------------------
1 | import { Backend } from '../../backup/index.js';
2 | import Connection from '../../connection/index.js';
3 | import { WeaviateInvalidInputError } from '../../errors.js';
4 | import { backup } from './client.js';
5 | import { BackupReturn, BackupStatusArgs, BackupStatusReturn } from './types.js';
6 |
7 | /** The arguments required to create and restore backups. */
8 | export type BackupCollectionArgs = {
9 | /** The ID of the backup. */
10 | backupId: string;
11 | /** The backend to use for the backup. */
12 | backend: Backend;
13 | /** The collections to include in the backup. */
14 | waitForCompletion?: boolean;
15 | };
16 |
17 | export const backupCollection = (connection: Connection, name: string) => {
18 | const handler = backup(connection);
19 | return {
20 | create: (args: BackupCollectionArgs) =>
21 | handler.create({
22 | ...args,
23 | includeCollections: [name],
24 | }),
25 | getCreateStatus: handler.getCreateStatus,
26 | getRestoreStatus: handler.getRestoreStatus,
27 | restore: (args: BackupCollectionArgs) =>
28 | handler.restore({
29 | ...args,
30 | includeCollections: [name],
31 | }),
32 | };
33 | };
34 |
35 | export interface BackupCollection {
36 | /**
37 | * Create a backup of this collection.
38 | *
39 | * @param {BackupArgs} args The arguments for the request.
40 | * @returns {Promise} The response from Weaviate.
41 | * @throws {WeaviateInvalidInputError} If the input is invalid.
42 | * @throws {WeaviateBackupFailed} If the backup creation fails.
43 | * @throws {WeaviateBackupCanceled} If the backup creation is canceled.
44 | */
45 | create(args: BackupCollectionArgs): Promise;
46 | /**
47 | * Get the status of a backup.
48 | *
49 | * @param {BackupStatusArgs} args The arguments for the request.
50 | * @returns {Promise} The status of the backup.
51 | * @throws {WeaviateInvalidInputError} If the input is invalid.
52 | */
53 | getCreateStatus(args: BackupStatusArgs): Promise;
54 | /**
55 | * Get the status of a restore.
56 | *
57 | * @param {BackupStatusArgs} args The arguments for the request.
58 | * @returns {Promise} The status of the restore.
59 | * @throws {WeaviateInvalidInputError} If the input is invalid.
60 | */
61 | getRestoreStatus(args: BackupStatusArgs): Promise;
62 | /**
63 | * Restore a backup of this collection.
64 | *
65 | * @param {BackupArgs} args The arguments for the request.
66 | * @returns {Promise} The response from Weaviate.
67 | * @throws {WeaviateInvalidInputError} If the input is invalid.
68 | * @throws {WeaviateBackupFailed} If the backup restoration fails.
69 | * @throws {WeaviateBackupCanceled} If the backup restoration is canceled.
70 | */
71 | restore(args: BackupCollectionArgs): Promise;
72 | }
73 |
--------------------------------------------------------------------------------
/src/collections/backup/index.ts:
--------------------------------------------------------------------------------
1 | export type { Backup } from './client.js';
2 | export type { BackupCollection, BackupCollectionArgs } from './collection.js';
3 | export type { BackupArgs, BackupConfigCreate, BackupConfigRestore, BackupStatusArgs } from './types.js';
4 |
--------------------------------------------------------------------------------
/src/collections/backup/types.ts:
--------------------------------------------------------------------------------
1 | import { Backend, BackupCompressionLevel } from '../../index.js';
2 |
3 | /** The status of a backup operation */
4 | export type BackupStatus = 'STARTED' | 'TRANSFERRING' | 'TRANSFERRED' | 'SUCCESS' | 'FAILED' | 'CANCELED';
5 |
6 | /** The status of a backup operation */
7 | export type BackupStatusReturn = {
8 | /** The ID of the backup */
9 | id: string;
10 | /** The error message if the backup failed */
11 | error?: string;
12 | /** The path to the backup */
13 | path: string;
14 | /** The status of the backup */
15 | status: BackupStatus;
16 | };
17 |
18 | /** The return type of a backup creation or restoration operation */
19 | export type BackupReturn = BackupStatusReturn & {
20 | /** The backend to which the backup was created or restored */
21 | backend: Backend;
22 | /** The collections that were included in the backup */
23 | collections: string[];
24 | };
25 |
26 | /** Configuration options available when creating a backup */
27 | export type BackupConfigCreate = {
28 | /** The size of the chunks to use for the backup. */
29 | chunkSize?: number;
30 | /** The standard of compression to use for the backup. */
31 | compressionLevel?: BackupCompressionLevel;
32 | /** The percentage of CPU to use for the backup creation job. */
33 | cpuPercentage?: number;
34 | };
35 |
36 | /** Configuration options available when restoring a backup */
37 | export type BackupConfigRestore = {
38 | /** The percentage of CPU to use for the backuop restoration job. */
39 | cpuPercentage?: number;
40 | };
41 |
42 | /** The arguments required to create and restore backups. */
43 | export type BackupArgs = {
44 | /** The ID of the backup. */
45 | backupId: string;
46 | /** The backend to use for the backup. */
47 | backend: Backend;
48 | /** The collections to include in the backup. */
49 | includeCollections?: string[];
50 | /** The collections to exclude from the backup. */
51 | excludeCollections?: string[];
52 | /** Whether to wait for the backup to complete. */
53 | waitForCompletion?: boolean;
54 | /** The configuration options for the backup. */
55 | config?: C;
56 | };
57 |
58 | /** The arguments required to get the status of a backup. */
59 | export type BackupStatusArgs = {
60 | /** The ID of the backup. */
61 | backupId: string;
62 | /** The backend to use for the backup. */
63 | backend: Backend;
64 | };
65 |
66 | /** The arguments required to cancel a backup. */
67 | export type BackupCancelArgs = {
68 | /** The ID of the backup. */
69 | backupId: string;
70 | /** The backend to use for the backup. */
71 | backend: Backend;
72 | };
73 |
--------------------------------------------------------------------------------
/src/collections/cluster/index.ts:
--------------------------------------------------------------------------------
1 | import { NodesStatusGetter } from '../../cluster/index.js';
2 | import Connection from '../../connection/index.js';
3 | import { BatchStats, NodeShardStatus, NodeStats } from '../../openapi/types.js';
4 |
5 | export type Output = 'minimal' | 'verbose' | undefined;
6 |
7 | export type NodesOptions = {
8 | /** The name of the collection to get the status of. */
9 | collection?: string;
10 | /** Set the desired output verbosity level. Can be `minimal | verbose | undefined` with `undefined` defaulting to `minimal`. */
11 | output: O;
12 | };
13 |
14 | export type Node = {
15 | name: string;
16 | status: 'HEALTHY' | 'UNHEALTHY' | 'UNAVAILABLE';
17 | version: string;
18 | gitHash: string;
19 | stats: O extends 'minimal' | undefined ? undefined : Required;
20 | batchStats: Required;
21 | shards: O extends 'minimal' | undefined ? null : Required[];
22 | };
23 |
24 | const cluster = (connection: Connection) => {
25 | return {
26 | nodes: (opts?: NodesOptions): Promise[]> => {
27 | let builder = new NodesStatusGetter(connection).withOutput(opts?.output ? opts.output : 'minimal');
28 | if (opts?.collection) {
29 | builder = builder.withClassName(opts.collection);
30 | }
31 | return builder.do().then((res) => res.nodes) as Promise[]>;
32 | },
33 | };
34 | };
35 |
36 | export default cluster;
37 |
38 | export interface Cluster {
39 | /**
40 | * Get the status of all nodes in the cluster.
41 | *
42 | * @param {NodesOptions} [opts] The options for the request.
43 | * @returns {Promise[]>} The status of all nodes in the cluster.
44 | */
45 | nodes: (opts?: NodesOptions) => Promise[]>;
46 | }
47 |
--------------------------------------------------------------------------------
/src/collections/config/types/reranker.ts:
--------------------------------------------------------------------------------
1 | export type RerankerTransformersConfig = {};
2 |
3 | export type RerankerCohereConfig = {
4 | model?: 'rerank-english-v2.0' | 'rerank-multilingual-v2.0' | string;
5 | };
6 |
7 | export type RerankerVoyageAIConfig = {
8 | baseURL?: string;
9 | model?: 'rerank-lite-1' | string;
10 | };
11 |
12 | export type RerankerJinaAIConfig = {
13 | model?:
14 | | 'jina-reranker-v2-base-multilingual'
15 | | 'jina-reranker-v1-base-en'
16 | | 'jina-reranker-v1-turbo-en'
17 | | 'jina-reranker-v1-tiny-en'
18 | | 'jina-colbert-v1-en'
19 | | string;
20 | };
21 |
22 | export type RerankerNvidiaConfig = {
23 | baseURL?: string;
24 | model?: 'nvidia/rerank-qa-mistral-4b' | string;
25 | };
26 |
27 | export type RerankerConfig =
28 | | RerankerCohereConfig
29 | | RerankerJinaAIConfig
30 | | RerankerNvidiaConfig
31 | | RerankerTransformersConfig
32 | | RerankerVoyageAIConfig
33 | | Record
34 | | undefined;
35 |
36 | export type Reranker =
37 | | 'reranker-cohere'
38 | | 'reranker-jinaai'
39 | | 'reranker-nvidia'
40 | | 'reranker-transformers'
41 | | 'reranker-voyageai'
42 | | 'none'
43 | | string;
44 |
45 | export type RerankerConfigType = R extends 'reranker-cohere'
46 | ? RerankerCohereConfig
47 | : R extends 'reranker-jinaai'
48 | ? RerankerJinaAIConfig
49 | : R extends 'reranker-nvidia'
50 | ? RerankerNvidiaConfig
51 | : R extends 'reranker-transformers'
52 | ? RerankerTransformersConfig
53 | : R extends 'reranker-voyageai'
54 | ? RerankerVoyageAIConfig
55 | : R extends 'none'
56 | ? undefined
57 | : Record | undefined;
58 |
--------------------------------------------------------------------------------
/src/collections/config/types/vectorIndex.ts:
--------------------------------------------------------------------------------
1 | export type VectorIndexConfigHNSW = {
2 | cleanupIntervalSeconds: number;
3 | distance: VectorDistance;
4 | dynamicEfMin: number;
5 | dynamicEfMax: number;
6 | dynamicEfFactor: number;
7 | efConstruction: number;
8 | ef: number;
9 | filterStrategy: VectorIndexFilterStrategy;
10 | flatSearchCutoff: number;
11 | maxConnections: number;
12 | quantizer: PQConfig | BQConfig | SQConfig | undefined;
13 | skip: boolean;
14 | vectorCacheMaxObjects: number;
15 | type: 'hnsw';
16 | };
17 |
18 | export type VectorIndexConfigFlat = {
19 | distance: VectorDistance;
20 | vectorCacheMaxObjects: number;
21 | quantizer: BQConfig | undefined;
22 | type: 'flat';
23 | };
24 |
25 | export type VectorIndexConfigDynamic = {
26 | distance: VectorDistance;
27 | threshold: number;
28 | hnsw: VectorIndexConfigHNSW;
29 | flat: VectorIndexConfigFlat;
30 | type: 'dynamic';
31 | };
32 |
33 | export type VectorIndexConfigType = I extends 'hnsw'
34 | ? VectorIndexConfigHNSW
35 | : I extends 'flat'
36 | ? VectorIndexConfigFlat
37 | : I extends 'dynamic'
38 | ? VectorIndexConfigDynamic
39 | : I extends string
40 | ? Record
41 | : never;
42 |
43 | export type BQConfig = {
44 | cache: boolean;
45 | rescoreLimit: number;
46 | type: 'bq';
47 | };
48 |
49 | export type SQConfig = {
50 | rescoreLimit: number;
51 | trainingLimit: number;
52 | type: 'sq';
53 | };
54 |
55 | export type PQConfig = {
56 | bitCompression: boolean;
57 | centroids: number;
58 | encoder: PQEncoderConfig;
59 | segments: number;
60 | trainingLimit: number;
61 | type: 'pq';
62 | };
63 |
64 | export type PQEncoderConfig = {
65 | type: PQEncoderType;
66 | distribution: PQEncoderDistribution;
67 | };
68 |
69 | export type VectorDistance = 'cosine' | 'dot' | 'l2-squared' | 'hamming';
70 |
71 | export type PQEncoderType = 'kmeans' | 'tile';
72 | export type PQEncoderDistribution = 'log-normal' | 'normal';
73 |
74 | export type VectorIndexType = 'hnsw' | 'flat' | 'dynamic' | string;
75 |
76 | export type VectorIndexFilterStrategy = 'sweeping' | 'acorn';
77 |
78 | export type VectorIndexConfig = VectorIndexConfigHNSW | VectorIndexConfigFlat | VectorIndexConfigDynamic;
79 |
80 | export type QuantizerConfig = PQConfig | BQConfig | SQConfig;
81 |
--------------------------------------------------------------------------------
/src/collections/configure/parsing.ts:
--------------------------------------------------------------------------------
1 | import {
2 | BQConfigCreate,
3 | BQConfigUpdate,
4 | PQConfigCreate,
5 | PQConfigUpdate,
6 | SQConfigCreate,
7 | SQConfigUpdate,
8 | } from './types/index.js';
9 |
10 | type QuantizerConfig =
11 | | PQConfigCreate
12 | | PQConfigUpdate
13 | | BQConfigCreate
14 | | BQConfigUpdate
15 | | SQConfigCreate
16 | | SQConfigUpdate;
17 |
18 | export class QuantizerGuards {
19 | static isPQCreate(config?: QuantizerConfig): config is PQConfigCreate {
20 | return (config as PQConfigCreate)?.type === 'pq';
21 | }
22 | static isPQUpdate(config?: QuantizerConfig): config is PQConfigUpdate {
23 | return (config as PQConfigUpdate)?.type === 'pq';
24 | }
25 | static isBQCreate(config?: QuantizerConfig): config is BQConfigCreate {
26 | return (config as BQConfigCreate)?.type === 'bq';
27 | }
28 | static isBQUpdate(config?: QuantizerConfig): config is BQConfigUpdate {
29 | return (config as BQConfigUpdate)?.type === 'bq';
30 | }
31 | static isSQCreate(config?: QuantizerConfig): config is SQConfigCreate {
32 | return (config as SQConfigCreate)?.type === 'sq';
33 | }
34 | static isSQUpdate(config?: QuantizerConfig): config is SQConfigUpdate {
35 | return (config as SQConfigUpdate)?.type === 'sq';
36 | }
37 | }
38 |
39 | export function parseWithDefault(value: D | undefined, defaultValue: D): D {
40 | return value !== undefined ? value : defaultValue;
41 | }
42 |
--------------------------------------------------------------------------------
/src/collections/configure/types/index.ts:
--------------------------------------------------------------------------------
1 | export * from './base.js';
2 | export * from './generative.js';
3 | export * from './vectorIndex.js';
4 | export * from './vectorizer.js';
5 |
--------------------------------------------------------------------------------
/src/collections/filters/index.ts:
--------------------------------------------------------------------------------
1 | export { Filters } from './classes.js';
2 | export type {
3 | Filter,
4 | FilterByCount,
5 | FilterById,
6 | FilterByProperty,
7 | FilterByTime,
8 | FilterValue,
9 | GeoRangeFilter,
10 | Operator,
11 | } from './types.js';
12 |
13 | import { ExtractCrossReferenceType, NonRefKeys, RefKeys } from '../types/internal.js';
14 |
15 | import {
16 | FilterCount,
17 | FilterCreationTime,
18 | FilterId,
19 | FilterProperty,
20 | FilterRef,
21 | FilterUpdateTime,
22 | } from './classes.js';
23 | import { Filter } from './types.js';
24 |
25 | const filter = (): Filter => {
26 | return {
27 | byProperty: & string>(name: K, length = false) => {
28 | return new FilterProperty(name, length);
29 | },
30 | byRef: & string>(linkOn: K) => {
31 | return new FilterRef>({ type_: 'single', linkOn: linkOn });
32 | },
33 | byRefMultiTarget: & string>(linkOn: K, targetCollection: string) => {
34 | return new FilterRef>({
35 | type_: 'multi',
36 | linkOn: linkOn,
37 | targetCollection: targetCollection,
38 | });
39 | },
40 | byRefCount: & string>(linkOn: K) => {
41 | return new FilterCount(linkOn);
42 | },
43 | byId: () => {
44 | return new FilterId();
45 | },
46 | byCreationTime: () => {
47 | return new FilterCreationTime();
48 | },
49 | byUpdateTime: () => {
50 | return new FilterUpdateTime();
51 | },
52 | };
53 | };
54 |
55 | export default filter;
56 |
--------------------------------------------------------------------------------
/src/collections/filters/utils.ts:
--------------------------------------------------------------------------------
1 | import { CountRef, FilterTargetInternal, MultiTargetRef, SingleTargetRef } from './types.js';
2 |
3 | export class TargetGuards {
4 | public static isSingleTargetRef(target?: FilterTargetInternal): target is SingleTargetRef {
5 | if (!target) return false;
6 | return (target as SingleTargetRef).type_ === 'single';
7 | }
8 |
9 | public static isMultiTargetRef(target?: FilterTargetInternal): target is MultiTargetRef {
10 | if (!target) return false;
11 | return (target as MultiTargetRef).type_ === 'multi';
12 | }
13 |
14 | public static isCountRef(target?: FilterTargetInternal): target is CountRef {
15 | if (!target) return false;
16 | return (target as CountRef).type_ === 'count';
17 | }
18 |
19 | public static isProperty(target?: FilterTargetInternal): target is string {
20 | if (!target) return false;
21 | return typeof target === 'string';
22 | }
23 |
24 | public static isTargetRef(target?: FilterTargetInternal): target is SingleTargetRef | MultiTargetRef {
25 | if (!target) return false;
26 | return TargetGuards.isSingleTargetRef(target) || TargetGuards.isMultiTargetRef(target);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/collections/iterator/index.ts:
--------------------------------------------------------------------------------
1 | import { WeaviateDeserializationError } from '../../errors.js';
2 | import { WeaviateObject } from '../types/index.js';
3 |
4 | const ITERATOR_CACHE_SIZE = 100;
5 |
6 | export class Iterator {
7 | private cache: WeaviateObject[] = [];
8 | private last: string | undefined = undefined;
9 | constructor(private query: (limit: number, after?: string) => Promise[]>) {
10 | this.query = query;
11 | }
12 |
13 | [Symbol.asyncIterator]() {
14 | return {
15 | next: async (): Promise>> => {
16 | const objects = await this.query(ITERATOR_CACHE_SIZE, this.last);
17 | this.cache = objects;
18 | if (this.cache.length == 0) {
19 | return {
20 | done: true,
21 | value: undefined,
22 | };
23 | }
24 | const obj = this.cache.shift();
25 | if (obj === undefined) {
26 | throw new WeaviateDeserializationError('Object iterator returned an object that is undefined');
27 | }
28 | this.last = obj?.uuid;
29 | if (this.last === undefined) {
30 | throw new WeaviateDeserializationError('Object iterator returned an object without a UUID');
31 | }
32 | return {
33 | done: false,
34 | value: obj,
35 | };
36 | },
37 | };
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/collections/query/utils.ts:
--------------------------------------------------------------------------------
1 | import { MultiTargetVectorJoin } from '../index.js';
2 | import { Bm25OperatorOptions, Bm25OperatorOr, NearVectorInputType, TargetVectorInputType } from './types.js';
3 |
4 | export class NearVectorInputGuards {
5 | public static is1DArray(input: NearVectorInputType): input is number[] {
6 | return Array.isArray(input) && input.length > 0 && !Array.isArray(input[0]);
7 | }
8 |
9 | public static isObject(input: NearVectorInputType): input is Record {
10 | return !Array.isArray(input);
11 | }
12 | }
13 |
14 | export class ArrayInputGuards {
15 | public static is1DArray(input: U | T): input is T {
16 | return Array.isArray(input) && input.length > 0 && !Array.isArray(input[0]);
17 | }
18 | public static is2DArray(input: U | T): input is T {
19 | return Array.isArray(input) && input.length > 0 && Array.isArray(input[0]);
20 | }
21 | }
22 |
23 | export class TargetVectorInputGuards {
24 | public static isSingle(input: TargetVectorInputType): input is string {
25 | return typeof input === 'string';
26 | }
27 |
28 | public static isMulti(input: TargetVectorInputType): input is string[] {
29 | return Array.isArray(input);
30 | }
31 |
32 | public static isMultiJoin(input: TargetVectorInputType): input is MultiTargetVectorJoin {
33 | const i = input as MultiTargetVectorJoin;
34 | return i.combination !== undefined && i.targetVectors !== undefined;
35 | }
36 | }
37 |
38 | export class Bm25Operator {
39 | static and(): Bm25OperatorOptions {
40 | return { operator: 'And' };
41 | }
42 |
43 | static or(opts: Omit): Bm25OperatorOptions {
44 | return { ...opts, operator: 'Or' };
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/collections/references/classes.ts:
--------------------------------------------------------------------------------
1 | import { Properties, ReferenceInput, ReferenceToMultiTarget, WeaviateObject } from '../types/index.js';
2 | import { Beacon } from './types.js';
3 | import { uuidToBeacon } from './utils.js';
4 |
5 | export class ReferenceManager {
6 | public objects: WeaviateObject[];
7 | public targetCollection: string;
8 | public uuids?: string[];
9 |
10 | constructor(targetCollection: string, objects?: WeaviateObject[], uuids?: string[]) {
11 | this.objects = objects ?? [];
12 | this.targetCollection = targetCollection;
13 | this.uuids = uuids;
14 | }
15 |
16 | public toBeaconObjs(): Beacon[] {
17 | return this.uuids ? this.uuids.map((uuid) => uuidToBeacon(uuid, this.targetCollection)) : [];
18 | }
19 |
20 | public toBeaconStrings(): string[] {
21 | return this.uuids ? this.uuids.map((uuid) => uuidToBeacon(uuid, this.targetCollection).beacon) : [];
22 | }
23 |
24 | public isMultiTarget(): boolean {
25 | return this.targetCollection !== '';
26 | }
27 | }
28 |
29 | /**
30 | * A factory class to create references from objects to other objects.
31 | */
32 | export class Reference {
33 | /**
34 | * Create a single-target reference with given UUID(s).
35 | *
36 | * @param {string | string[]} uuids The UUID(s) of the target object(s).
37 | * @returns {ReferenceManager} The reference manager object.
38 | */
39 | public static to(
40 | uuids: string | string[]
41 | ): ReferenceManager {
42 | return new ReferenceManager('', undefined, Array.isArray(uuids) ? uuids : [uuids]);
43 | }
44 | /**
45 | * Create a multi-target reference with given UUID(s) pointing to a specific target collection.
46 | *
47 | * @param {string | string[]} uuids The UUID(s) of the target object(s).
48 | * @param {string} targetCollection The target collection name.
49 | * @returns {ReferenceManager} The reference manager object.
50 | */
51 | public static toMultiTarget(
52 | uuids: string | string[],
53 | targetCollection: string
54 | ): ReferenceManager {
55 | return new ReferenceManager(
56 | targetCollection,
57 | undefined,
58 | Array.isArray(uuids) ? uuids : [uuids]
59 | );
60 | }
61 | }
62 |
63 | export class ReferenceGuards {
64 | public static isReferenceManager(arg: ReferenceInput): arg is ReferenceManager {
65 | return arg instanceof ReferenceManager;
66 | }
67 |
68 | public static isUuid(arg: ReferenceInput): arg is string {
69 | return typeof arg === 'string';
70 | }
71 |
72 | public static isUuids(arg: ReferenceInput): arg is string[] {
73 | return Array.isArray(arg);
74 | }
75 |
76 | public static isMultiTarget(arg: ReferenceInput): arg is ReferenceToMultiTarget {
77 | return (arg as ReferenceToMultiTarget).targetCollection !== undefined;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/collections/references/index.ts:
--------------------------------------------------------------------------------
1 | export { Reference, ReferenceManager } from './classes.js';
2 | export type { Beacon, CrossReference, CrossReferenceDefault, CrossReferences, UnionOf } from './types.js';
3 |
--------------------------------------------------------------------------------
/src/collections/references/types.ts:
--------------------------------------------------------------------------------
1 | import { Properties, WeaviateNonGenericObject } from '../types/index.js';
2 | import { ReferenceManager } from './classes.js';
3 |
4 | export type CrossReference = ReferenceManager;
5 |
6 | export type CrossReferenceDefault = {
7 | objects: WeaviateNonGenericObject[];
8 | };
9 |
10 | export type CrossReferences = ReferenceManager>;
11 |
12 | export type UnionOf = T extends (infer U)[] ? U : never;
13 |
14 | export type Beacon = {
15 | beacon: string;
16 | };
17 |
--------------------------------------------------------------------------------
/src/collections/references/utils.ts:
--------------------------------------------------------------------------------
1 | import { ReferenceInput } from '../types/index.js';
2 | import { ReferenceGuards, ReferenceManager } from './classes.js';
3 | import { Beacon } from './types.js';
4 |
5 | export function uuidToBeacon(uuid: string, targetCollection?: string): Beacon {
6 | return {
7 | beacon: `weaviate://localhost/${targetCollection ? `${targetCollection}/` : ''}${uuid}`,
8 | };
9 | }
10 |
11 | export const referenceFromObjects = (
12 | objects: any[],
13 | targetCollection: string,
14 | uuids: string[]
15 | ): ReferenceManager => {
16 | return new ReferenceManager(targetCollection, objects, uuids);
17 | };
18 |
19 | export const referenceToBeacons = (ref: ReferenceInput): Beacon[] => {
20 | if (ReferenceGuards.isReferenceManager(ref)) {
21 | return ref.toBeaconObjs();
22 | } else if (ReferenceGuards.isUuid(ref)) {
23 | return [uuidToBeacon(ref)];
24 | } else if (ReferenceGuards.isUuids(ref)) {
25 | return ref.map((uuid) => uuidToBeacon(uuid));
26 | } else if (ReferenceGuards.isMultiTarget(ref)) {
27 | return typeof ref.uuids === 'string'
28 | ? [uuidToBeacon(ref.uuids, ref.targetCollection)]
29 | : ref.uuids.map((uuid) => uuidToBeacon(uuid, ref.targetCollection));
30 | }
31 | return [];
32 | };
33 |
--------------------------------------------------------------------------------
/src/collections/sort/classes.ts:
--------------------------------------------------------------------------------
1 | import { SortBy } from '../types/index.js';
2 | import { NonRefKeys } from '../types/internal.js';
3 |
4 | export class Sorting {
5 | public sorts: SortBy[];
6 |
7 | constructor() {
8 | this.sorts = [];
9 | }
10 |
11 | /** Sort by the objects' property. */
12 | public byProperty>(property: K, ascending = true) {
13 | this.sorts.push({ property, ascending });
14 | return this;
15 | }
16 |
17 | /** Sort by the objects' ID. */
18 | public byId(ascending = true) {
19 | this.sorts.push({ property: '_id', ascending });
20 | return this;
21 | }
22 |
23 | /** Sort by the objects' creation time. */
24 | public byCreationTime(ascending = true) {
25 | this.sorts.push({ property: '_creationTimeUnix', ascending });
26 | return this;
27 | }
28 |
29 | /** Sort by the objects' last update time. */
30 | public byUpdateTime(ascending = true) {
31 | this.sorts.push({ property: '_lastUpdateTimeUnix', ascending });
32 | return this;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/collections/sort/index.ts:
--------------------------------------------------------------------------------
1 | export type { Sort } from './types.js';
2 |
3 | import { NonRefKeys } from '../types/internal.js';
4 | import { Sorting } from './classes.js';
5 | import { Sort } from './types.js';
6 |
7 | const sort = (): Sort => {
8 | return {
9 | byProperty>(property: K, ascending = true) {
10 | return new Sorting().byProperty(property, ascending);
11 | },
12 | byId(ascending = true) {
13 | return new Sorting().byId(ascending);
14 | },
15 | byCreationTime(ascending = true) {
16 | return new Sorting().byCreationTime(ascending);
17 | },
18 | byUpdateTime(ascending = true) {
19 | return new Sorting().byUpdateTime(ascending);
20 | },
21 | };
22 | };
23 |
24 | export default sort;
25 |
26 | export { Sorting };
27 |
--------------------------------------------------------------------------------
/src/collections/sort/types.ts:
--------------------------------------------------------------------------------
1 | import { NonRefKeys } from '../types/internal.js';
2 | import { Sorting } from './classes.js';
3 |
4 | /**
5 | * Define how the query's sort operation should be performed using the available methods.
6 | */
7 | export interface Sort {
8 | /** Sort by an object property. */
9 | byProperty>(property: K, ascending?: boolean): Sorting;
10 | /** Sort by the objects' ID. */
11 | byId(ascending?: boolean): Sorting;
12 | /** Sort by the objects' creation time. */
13 | byCreationTime(ascending?: boolean): Sorting;
14 | /** Sort by the objects' last update time. */
15 | byUpdateTime(ascending?: boolean): Sorting;
16 | }
17 |
--------------------------------------------------------------------------------
/src/collections/tenants/types.ts:
--------------------------------------------------------------------------------
1 | /** The base type for a tenant. Only the name is required. */
2 | export type TenantBase = {
3 | /** The name of the tenant. */
4 | name: string;
5 | };
6 |
7 | /** The expected type when creating a tenant. */
8 | export type TenantCreate = TenantBase & {
9 | /** The activity status of the tenant. Defaults to 'ACTIVE' if not provided. */
10 | activityStatus?: 'ACTIVE' | 'INACTIVE';
11 | };
12 |
13 | /** The expected type when updating a tenant. */
14 | export type TenantUpdate = TenantBase & {
15 | /** The activity status of the tenant. Must be set to one of the options. */
16 | activityStatus: 'ACTIVE' | 'INACTIVE' | 'OFFLOADED';
17 | };
18 |
19 | /** The expected type when getting tenants. */
20 | export type TenantsGetOptions = {
21 | tenants?: string;
22 | };
23 |
24 | /**
25 | * The expected type returned by all tenant methods.
26 | */
27 | export type Tenant = TenantBase & {
28 | /** There are two statuses that are immutable: `OFFLOADED` and `ONLOADING, which are set by the server:
29 | * - `ONLOADING`, which means the tenant is transitioning from the `OFFLOADED` status to `ACTIVE/INACTIVE`.
30 | * - `OFFLOADING`, which means the tenant is transitioning from `ACTIVE/INACTIVE` to the `OFFLOADED` status.
31 | * The other three statuses are mutable within the `.create` and `.update`, methods:
32 | * - `ACTIVE`, which means loaded fully into memory and ready for use.
33 | * - `INACTIVE`, which means not loaded into memory with files stored on disk.
34 | * - `OFFLOADED`, which means not loaded into memory with files stored on the cloud.
35 | */
36 | activityStatus: 'ACTIVE' | 'INACTIVE' | 'OFFLOADED' | 'OFFLOADING' | 'ONLOADING';
37 | };
38 |
39 | /** This is the type of the Tenant as defined in Weaviate's OpenAPI schema. It is included here for Backwards Compatibility. */
40 | export type TenantBC = TenantBase & {
41 | activityStatus?: 'HOT' | 'COLD' | 'FROZEN';
42 | };
43 |
--------------------------------------------------------------------------------
/src/collections/types/batch.ts:
--------------------------------------------------------------------------------
1 | import { BatchReference } from '../../openapi/types.js';
2 | import { BatchObject as BatchObjectGRPC } from '../../proto/v1/batch.js';
3 | import { NonReferenceInputs, ReferenceInputs, Vectors } from '../index.js';
4 |
5 | export type BatchObjectsReturn = {
6 | allResponses: (string | ErrorObject)[];
7 | elapsedSeconds: number;
8 | errors: Record>;
9 | hasErrors: boolean;
10 | uuids: Record;
11 | };
12 |
13 | export type ErrorObject = {
14 | code?: number;
15 | message: string;
16 | object: BatchObject;
17 | originalUuid?: string;
18 | };
19 |
20 | export type BatchObject = {
21 | collection: string;
22 | properties?: NonReferenceInputs;
23 | references?: ReferenceInputs;
24 | id?: string;
25 | vectors?: number[] | Vectors;
26 | tenant?: string;
27 | };
28 |
29 | export type BatchObjects = {
30 | batch: BatchObject[];
31 | mapped: BatchObjectGRPC[];
32 | };
33 |
34 | export type ErrorReference = {
35 | message: string;
36 | reference: BatchReference;
37 | };
38 |
39 | export type BatchReferencesReturn = {
40 | elapsedSeconds: number;
41 | errors: Record;
42 | hasErrors: boolean;
43 | };
44 |
--------------------------------------------------------------------------------
/src/collections/types/data.ts:
--------------------------------------------------------------------------------
1 | import { NonReferenceInputs, ReferenceInputs } from './internal.js';
2 | import { Vectors } from './query.js';
3 |
4 | export type DataObject = {
5 | id?: string;
6 | properties?: NonReferenceInputs;
7 | references?: ReferenceInputs;
8 | vectors?: number[] | Vectors;
9 | };
10 |
11 | export type DeleteManyObject = {
12 | id: string;
13 | successful: boolean;
14 | error?: string;
15 | };
16 |
17 | export type DeleteManyReturn = {
18 | failed: number;
19 | matches: number;
20 | objects: V extends true ? DeleteManyObject[] : undefined;
21 | successful: number;
22 | };
23 |
24 | export type ReferenceToMultiTarget = {
25 | targetCollection: string;
26 | uuids: string | string[];
27 | };
28 |
--------------------------------------------------------------------------------
/src/collections/types/index.ts:
--------------------------------------------------------------------------------
1 | export * from '../config/types/index.js';
2 | export * from '../configure/types/index.js';
3 | export type { CollectionConfigCreate } from '../index.js';
4 | export * from './batch.js';
5 | export * from './data.js';
6 | export * from './generate.js';
7 | export type {
8 | IsEmptyType,
9 | IsNestedField,
10 | IsPrimitiveField,
11 | IsWeaviateField,
12 | NestedKeys,
13 | NonRefKeys,
14 | NonReferenceInputs,
15 | PrimitiveKeys,
16 | QueryNested,
17 | QueryProperty,
18 | QueryReference,
19 | RefKeys,
20 | ReferenceInput,
21 | ReferenceInputs,
22 | } from './internal.js';
23 | export * from './query.js';
24 |
25 | import {
26 | GeoCoordinate as GeoCoordinateGRPC,
27 | PhoneNumber as PhoneNumberGRPC,
28 | } from '../../proto/v1/properties.js';
29 |
30 | import { CrossReference } from '../references/index.js';
31 |
32 | // The order of type resolution is important here since object can be inferred as all other types
33 | // hence it should be the last type in the union
34 | export type DataType = T extends infer U | undefined
35 | ? U extends string
36 | ? 'text' | 'uuid' | 'blob'
37 | : U extends number
38 | ? 'number' | 'int'
39 | : U extends boolean
40 | ? 'boolean'
41 | : U extends Date
42 | ? 'date'
43 | : U extends string[]
44 | ? 'text[]' | 'uuid[]'
45 | : U extends number[]
46 | ? 'number[]' | 'int[]'
47 | : U extends boolean[]
48 | ? 'boolean[]'
49 | : U extends Date[]
50 | ? 'date[]'
51 | : U extends GeoCoordinate
52 | ? 'geoCoordinates'
53 | : U extends PhoneNumber
54 | ? 'phoneNumber'
55 | : U extends object[]
56 | ? 'object[]'
57 | : U extends object
58 | ? 'object'
59 | : never
60 | : never;
61 |
62 | export type GeoCoordinate = Required;
63 |
64 | export type PhoneNumber = Required;
65 |
66 | export type PrimitiveField =
67 | | string
68 | | string[]
69 | | boolean
70 | | boolean[]
71 | | number
72 | | number[]
73 | | Date
74 | | Date[]
75 | | Blob
76 | | GeoCoordinate
77 | | PhoneNumber
78 | | PhoneNumberInput
79 | | null;
80 |
81 | export type NestedField = NestedProperties | NestedProperties[];
82 |
83 | export type WeaviateField = PrimitiveField | NestedField;
84 |
85 | export type Property = WeaviateField | CrossReference | undefined;
86 |
87 | export interface Properties {
88 | [k: string]: Property;
89 | }
90 |
91 | export interface NestedProperties {
92 | [k: string]: WeaviateField;
93 | }
94 |
95 | export type PhoneNumberInput = {
96 | number: string;
97 | defaultCountry?: string;
98 | };
99 |
--------------------------------------------------------------------------------
/src/collections/vectors/multiTargetVector.ts:
--------------------------------------------------------------------------------
1 | /** The allowed combination methods for multi-target vector joins */
2 | export type MultiTargetVectorJoinCombination =
3 | | 'sum'
4 | | 'average'
5 | | 'minimum'
6 | | 'relative-score'
7 | | 'manual-weights';
8 |
9 | /** Weights for each target vector in a multi-target vector join */
10 | export type MultiTargetVectorWeights = Record;
11 |
12 | /** A multi-target vector join used when specifying a vector-based query */
13 | export type MultiTargetVectorJoin = {
14 | /** The combination method to use for the target vectors */
15 | combination: MultiTargetVectorJoinCombination;
16 | /** The target vectors to combine */
17 | targetVectors: string[];
18 | /** The weights to use for each target vector */
19 | weights?: MultiTargetVectorWeights;
20 | };
21 |
22 | export default () => {
23 | return {
24 | sum: (targetVectors: string[]): MultiTargetVectorJoin => {
25 | return { combination: 'sum' as MultiTargetVectorJoinCombination, targetVectors };
26 | },
27 | average: (targetVectors: string[]): MultiTargetVectorJoin => {
28 | return { combination: 'average' as MultiTargetVectorJoinCombination, targetVectors };
29 | },
30 | minimum: (targetVectors: string[]): MultiTargetVectorJoin => {
31 | return { combination: 'minimum' as MultiTargetVectorJoinCombination, targetVectors };
32 | },
33 | relativeScore: (weights: MultiTargetVectorWeights): MultiTargetVectorJoin => {
34 | return {
35 | combination: 'relative-score' as MultiTargetVectorJoinCombination,
36 | targetVectors: Object.keys(weights),
37 | weights,
38 | };
39 | },
40 | manualWeights: (weights: MultiTargetVectorWeights): MultiTargetVectorJoin => {
41 | return {
42 | combination: 'manual-weights' as MultiTargetVectorJoinCombination,
43 | targetVectors: Object.keys(weights),
44 | weights,
45 | };
46 | },
47 | };
48 | };
49 |
50 | export interface MultiTargetVector {
51 | /** Create a multi-target vector join that sums the vector scores over the target vectors */
52 | sum: (targetVectors: string[]) => MultiTargetVectorJoin;
53 | /** Create a multi-target vector join that averages the vector scores over the target vectors */
54 | average: (targetVectors: string[]) => MultiTargetVectorJoin;
55 | /** Create a multi-target vector join that takes the minimum vector score over the target vectors */
56 | minimum: (targetVectors: string[]) => MultiTargetVectorJoin;
57 | /** Create a multi-target vector join that uses relative weights for each target vector */
58 | relativeScore: (weights: MultiTargetVectorWeights) => MultiTargetVectorJoin;
59 | /** Create a multi-target vector join that uses manual weights for each target vector */
60 | manualWeights: (weights: MultiTargetVectorWeights) => MultiTargetVectorJoin;
61 | }
62 |
--------------------------------------------------------------------------------
/src/connection/gql.ts:
--------------------------------------------------------------------------------
1 | import { GraphQLClient as Client, Variables } from 'graphql-request';
2 | import ConnectionREST, { InternalConnectionParams } from './http.js';
3 |
4 | export default class ConnectionGQL extends ConnectionREST {
5 | private gql: GraphQLClient;
6 |
7 | constructor(params: InternalConnectionParams) {
8 | super(params);
9 | this.gql = gqlClient(params);
10 | }
11 |
12 | query = (query: any, variables?: V) => {
13 | if (this.authEnabled) {
14 | return this.login().then((token) => {
15 | const headers = { Authorization: `Bearer ${token}` };
16 | return this.gql.query(query, variables, headers);
17 | });
18 | }
19 | return this.gql.query(query, variables);
20 | };
21 |
22 | close = () => this.http.close();
23 | }
24 |
25 | export * from './auth.js';
26 |
27 | export type TQuery = any;
28 | export interface GraphQLClient {
29 | query: (
30 | query: TQuery,
31 | variables?: V,
32 | headers?: HeadersInit
33 | ) => Promise<{ data: T }>;
34 | }
35 |
36 | export const gqlClient = (config: InternalConnectionParams): GraphQLClient => {
37 | const version = '/v1/graphql';
38 | const baseUri = `${config.host}${version}`;
39 | const defaultHeaders = config.headers;
40 | return {
41 | // for backward compatibility with replaced graphql-client lib,
42 | // results are wrapped into { data: data }
43 | query: (query: TQuery, variables?: V, headers?: HeadersInit) => {
44 | return new Client(baseUri, {
45 | headers: {
46 | ...defaultHeaders,
47 | ...headers,
48 | },
49 | })
50 | .request(query, variables, headers)
51 | .then((data) => ({ data }));
52 | },
53 | };
54 | };
55 |
--------------------------------------------------------------------------------
/src/connection/helpers.test.ts:
--------------------------------------------------------------------------------
1 | import weaviate from '../index.js';
2 |
3 | const WCD_URL = 'https://piblpmmdsiknacjnm1ltla.c1.europe-west3.gcp.weaviate.cloud';
4 | const WCD_KEY = 'cy4ua772mBlMdfw3YnclqAWzFhQt0RLIN0sl';
5 |
6 | describe('Testing of the connection helper methods', () => {
7 | it('should connect to a WCS cluster', () => {
8 | return weaviate
9 | .connectToWeaviateCloud(WCD_URL, {
10 | authCredentials: new weaviate.ApiKey(WCD_KEY),
11 | })
12 | .then((client) => client.getMeta())
13 | .then((res: any) => {
14 | expect(res.version).toBeDefined();
15 | })
16 | .catch((e: any) => {
17 | throw new Error('it should not have errord: ' + e);
18 | });
19 | });
20 |
21 | it('should connect to a local cluster', () => {
22 | return weaviate
23 | .connectToLocal()
24 | .then((client) => client.getMeta())
25 | .then((res: any) => {
26 | expect(res.version).toBeDefined();
27 | })
28 | .catch((e: any) => {
29 | throw new Error('it should not have errord: ' + e);
30 | });
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/src/connection/index.ts:
--------------------------------------------------------------------------------
1 | import ConnectionGQL from './gql.js';
2 | import ConnectionGRPC from './grpc.js';
3 | import ConnectionREST from './http.js';
4 |
5 | export default ConnectionGQL;
6 |
7 | export type {
8 | ConnectToCustomOptions,
9 | ConnectToLocalOptions,
10 | ConnectToWCDOptions,
11 | ConnectToWCSOptions,
12 | ConnectToWeaviateCloudOptions,
13 | } from './helpers.js';
14 | export type { InternalConnectionParams } from './http.js';
15 | export { ConnectionGQL, ConnectionGRPC, ConnectionREST };
16 |
--------------------------------------------------------------------------------
/src/connection/integration.test.ts:
--------------------------------------------------------------------------------
1 | import { StartedWeaviateContainer, WeaviateContainer } from '@testcontainers/weaviate';
2 | import weaviate from '..';
3 | import { WeaviateStartUpError } from '../errors';
4 | import { Meta } from '../openapi/types';
5 | import { DbVersion } from '../utils/dbVersion';
6 |
7 | describe('Integration testing of the ConnectionGRPC class', () => {
8 | let container: StartedWeaviateContainer;
9 |
10 | const getVersion = () =>
11 | fetch(`http://${container.getHost()}:${container.getMappedPort(8080)}/v1/meta`)
12 | .then((res) => res.json() as Promise)
13 | .then((meta) => DbVersion.fromString(meta.version!));
14 |
15 | beforeAll(async () => {
16 | container = await new WeaviateContainer(`semitechnologies/weaviate:${process.env.WEAVIATE_VERSION}`)
17 | .withExposedPorts(8080, 50051)
18 | .withEnvironment({
19 | GRPC_MAX_MESSAGE_SIZE: '1',
20 | })
21 | .start();
22 | expect(container).toBeDefined();
23 | });
24 | afterAll(async () => {
25 | await container.stop();
26 | });
27 | it('should fail to startup due to message-size limit', async () => {
28 | const dbVersion = await getVersion();
29 | try {
30 | await weaviate.connectToLocal({
31 | host: container.getHost(),
32 | port: container.getMappedPort(8080),
33 | grpcPort: container.getMappedPort(50051),
34 | });
35 | expect(dbVersion.isLowerThan(1, 27, 1)).toBe(true);
36 | } catch (err) {
37 | expect(err).toBeInstanceOf(WeaviateStartUpError);
38 | expect((err as WeaviateStartUpError).message).toContain(
39 | 'RESOURCE_EXHAUSTED: Attempted to send message with a size larger than 1'
40 | );
41 | expect(dbVersion.isAtLeast(1, 27, 1)).toBe(true);
42 | }
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/src/connection/proxy.test.ts:
--------------------------------------------------------------------------------
1 | import weaviate from '../index.js';
2 |
3 | describe('Testing of the client connecting to a proxied Weaviate instance', () => {
4 | // Skip because Envoy Proxy in CI is too flaky with strange error:
5 | // ClientError: /grpc.health.v1.Health/Check INTERNAL: Received RST_STREAM with code 2 triggered by internal client error: Protocol error
6 | it.skip('should connect to a local instance using simultaneous http and grpc proxies', async () => {
7 | const client = await weaviate.connectToCustom({
8 | httpHost: 'localhost',
9 | httpPath: '/http',
10 | httpPort: 10000,
11 | httpSecure: false,
12 | grpcHost: 'weaviate-proxy',
13 | grpcPort: 8021,
14 | proxies: {
15 | grpc: 'http://localhost:10001',
16 | },
17 | });
18 | expect(client).toBeDefined();
19 | return client.collections
20 | .delete('Test')
21 | .then(() =>
22 | client.collections.create({
23 | name: 'Test',
24 | })
25 | )
26 | .then(async (collection) => {
27 | await collection.data.insert();
28 | return collection;
29 | })
30 | .then((collection) => collection.query.fetchObjects())
31 | .then((res) => expect(res.objects).toHaveLength(1));
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/src/data/checker.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { CommandBase } from '../validation/commandBase.js';
3 | import { ObjectsPath } from './path.js';
4 | import { ConsistencyLevel } from './replication.js';
5 |
6 | export default class Checker extends CommandBase {
7 | private className!: string;
8 | private consistencyLevel?: ConsistencyLevel;
9 | private id!: string;
10 | private tenant?: string;
11 | private objectsPath: ObjectsPath;
12 |
13 | constructor(client: Connection, objectsPath: ObjectsPath) {
14 | super(client);
15 | this.objectsPath = objectsPath;
16 | }
17 |
18 | withId = (id: string) => {
19 | this.id = id;
20 | return this;
21 | };
22 |
23 | withClassName = (className: string) => {
24 | this.className = className;
25 | return this;
26 | };
27 |
28 | withTenant = (tenant: string) => {
29 | this.tenant = tenant;
30 | return this;
31 | };
32 |
33 | withConsistencyLevel = (consistencyLevel: ConsistencyLevel) => {
34 | this.consistencyLevel = consistencyLevel;
35 | return this;
36 | };
37 |
38 | buildPath = () => {
39 | return this.objectsPath.buildCheck(this.id, this.className, this.consistencyLevel, this.tenant);
40 | };
41 |
42 | validateIsSet = (prop: string | undefined | null, name: string, setter: string) => {
43 | if (prop == undefined || prop == null || prop.length == 0) {
44 | this.addError(`${name} must be set - set with ${setter}`);
45 | }
46 | };
47 |
48 | validateId = () => {
49 | this.validateIsSet(this.id, 'id', '.withId(id)');
50 | };
51 |
52 | validate = () => {
53 | this.validateId();
54 | };
55 |
56 | do = (): Promise => {
57 | if (this.errors.length > 0) {
58 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
59 | }
60 | this.validate();
61 |
62 | return this.buildPath().then((path: string) => this.client.head(path, undefined));
63 | };
64 | }
65 |
--------------------------------------------------------------------------------
/src/data/creator.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Properties, WeaviateObject } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { isValidStringProperty } from '../validation/string.js';
5 | import { ObjectsPath } from './path.js';
6 | import { ConsistencyLevel } from './replication.js';
7 |
8 | export default class Creator extends CommandBase {
9 | private className?: string;
10 | private consistencyLevel?: ConsistencyLevel;
11 | private id?: string;
12 | private objectsPath: ObjectsPath;
13 | private properties?: Properties;
14 | private vector?: number[];
15 | private vectors?: Record;
16 | private tenant?: string;
17 |
18 | constructor(client: Connection, objectsPath: ObjectsPath) {
19 | super(client);
20 | this.objectsPath = objectsPath;
21 | }
22 |
23 | withVector = (vector: number[]) => {
24 | this.vector = vector;
25 | return this;
26 | };
27 |
28 | withVectors = (vectors: Record) => {
29 | this.vectors = vectors;
30 | return this;
31 | };
32 |
33 | withClassName = (className: string) => {
34 | this.className = className;
35 | return this;
36 | };
37 |
38 | withProperties = (properties: Properties) => {
39 | this.properties = properties;
40 | return this;
41 | };
42 |
43 | withId = (id: string) => {
44 | this.id = id;
45 | return this;
46 | };
47 |
48 | withConsistencyLevel = (cl: ConsistencyLevel) => {
49 | this.consistencyLevel = cl;
50 | return this;
51 | };
52 |
53 | withTenant = (tenant: string) => {
54 | this.tenant = tenant;
55 | return this;
56 | };
57 |
58 | validateClassName = () => {
59 | if (!isValidStringProperty(this.className)) {
60 | this.addError('className must be set - set with .withClassName(className)');
61 | }
62 | };
63 |
64 | // as Record required below because server uses swagger object as interface{} in Go to perform type switching
65 | // actual types are []number and [][]number but unions don't work in go-swagger
66 | payload = (): WeaviateObject => ({
67 | tenant: this.tenant,
68 | vector: this.vector,
69 | properties: this.properties,
70 | class: this.className,
71 | id: this.id,
72 | vectors: this.vectors as Record,
73 | });
74 |
75 | validate = () => {
76 | this.validateClassName();
77 | };
78 |
79 | do = (): Promise => {
80 | this.validate();
81 | if (this.errors.length > 0) {
82 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
83 | }
84 |
85 | return this.objectsPath
86 | .buildCreate(this.consistencyLevel)
87 | .then((path: string) => this.client.postReturn(path, this.payload()));
88 | };
89 | }
90 |
--------------------------------------------------------------------------------
/src/data/deleter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { CommandBase } from '../validation/commandBase.js';
3 | import { ObjectsPath } from './path.js';
4 | import { ConsistencyLevel } from './replication.js';
5 |
6 | export default class Deleter extends CommandBase {
7 | private className!: string;
8 | private consistencyLevel?: ConsistencyLevel;
9 | private id!: string;
10 | private tenant?: string;
11 | private objectsPath: ObjectsPath;
12 |
13 | constructor(client: Connection, objectsPath: ObjectsPath) {
14 | super(client);
15 | this.objectsPath = objectsPath;
16 | }
17 |
18 | withId = (id: string) => {
19 | this.id = id;
20 | return this;
21 | };
22 |
23 | withClassName = (className: string) => {
24 | this.className = className;
25 | return this;
26 | };
27 |
28 | withConsistencyLevel = (cl: ConsistencyLevel) => {
29 | this.consistencyLevel = cl;
30 | return this;
31 | };
32 |
33 | withTenant = (tenant: string) => {
34 | this.tenant = tenant;
35 | return this;
36 | };
37 |
38 | validateIsSet = (prop: string | undefined | null, name: string, setter: string) => {
39 | if (prop == undefined || prop == null || prop.length == 0) {
40 | this.addError(`${name} must be set - set with ${setter}`);
41 | }
42 | };
43 |
44 | validateId = () => {
45 | this.validateIsSet(this.id, 'id', '.withId(id)');
46 | };
47 |
48 | validate = () => {
49 | this.validateId();
50 | };
51 |
52 | do = () => {
53 | if (this.errors.length > 0) {
54 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
55 | }
56 | this.validate();
57 |
58 | return this.objectsPath
59 | .buildDelete(this.id, this.className, this.consistencyLevel, this.tenant)
60 | .then((path: string) => {
61 | return this.client.delete(path, undefined, false);
62 | });
63 | };
64 | }
65 |
--------------------------------------------------------------------------------
/src/data/getter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { WeaviateObjectsList } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { ObjectsPath } from './path.js';
5 |
6 | export default class Getter extends CommandBase {
7 | private additional: string[];
8 | private after!: string;
9 | private className?: string;
10 | private limit?: number;
11 | private tenant?: string;
12 | private objectsPath: ObjectsPath;
13 |
14 | constructor(client: Connection, objectsPath: ObjectsPath) {
15 | super(client);
16 | this.objectsPath = objectsPath;
17 | this.additional = [];
18 | }
19 |
20 | withClassName = (className: string) => {
21 | this.className = className;
22 | return this;
23 | };
24 |
25 | withAfter = (id: string) => {
26 | this.after = id;
27 | return this;
28 | };
29 |
30 | withLimit = (limit: number) => {
31 | this.limit = limit;
32 | return this;
33 | };
34 |
35 | withTenant = (tenant: string) => {
36 | this.tenant = tenant;
37 | return this;
38 | };
39 |
40 | extendAdditional = (prop: string) => {
41 | this.additional = [...this.additional, prop];
42 | return this;
43 | };
44 |
45 | withAdditional = (additionalFlag: any) => this.extendAdditional(additionalFlag);
46 |
47 | withVector = () => this.extendAdditional('vector');
48 |
49 | validate() {
50 | // nothing to validate
51 | }
52 |
53 | do = (): Promise => {
54 | if (this.errors.length > 0) {
55 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
56 | }
57 |
58 | return this.objectsPath
59 | .buildGet(this.className, this.limit, this.additional, this.after, this.tenant)
60 | .then((path: string) => {
61 | return this.client.get(path);
62 | });
63 | };
64 | }
65 |
--------------------------------------------------------------------------------
/src/data/getterById.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { WeaviateObject } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { ObjectsPath } from './path.js';
5 | import { ConsistencyLevel } from './replication.js';
6 |
7 | export default class GetterById extends CommandBase {
8 | private additional: string[];
9 | private className!: string;
10 | private id!: string;
11 | private consistencyLevel?: ConsistencyLevel;
12 | private nodeName?: string;
13 | private tenant?: string;
14 | private objectsPath: ObjectsPath;
15 |
16 | constructor(client: Connection, objectsPath: ObjectsPath) {
17 | super(client);
18 | this.objectsPath = objectsPath;
19 | this.additional = [];
20 | }
21 |
22 | withId = (id: string) => {
23 | this.id = id;
24 | return this;
25 | };
26 |
27 | withClassName = (className: string) => {
28 | this.className = className;
29 | return this;
30 | };
31 |
32 | withTenant = (tenant: string) => {
33 | this.tenant = tenant;
34 | return this;
35 | };
36 |
37 | extendAdditional = (prop: string) => {
38 | this.additional = [...this.additional, prop];
39 | return this;
40 | };
41 |
42 | withAdditional = (additionalFlag: string) => this.extendAdditional(additionalFlag);
43 |
44 | withVector = () => this.extendAdditional('vector');
45 |
46 | withConsistencyLevel = (cl: ConsistencyLevel) => {
47 | this.consistencyLevel = cl;
48 | return this;
49 | };
50 |
51 | withNodeName = (nodeName: string) => {
52 | this.nodeName = nodeName;
53 | return this;
54 | };
55 |
56 | validateId = () => {
57 | if (this.id == undefined || this.id == null || this.id.length == 0) {
58 | this.addError('id must be set - initialize with getterById(id)');
59 | }
60 | };
61 |
62 | validate = () => {
63 | this.validateId();
64 | };
65 |
66 | buildPath = (): Promise => {
67 | return this.objectsPath.buildGetOne(
68 | this.id,
69 | this.className,
70 | this.additional,
71 | this.consistencyLevel,
72 | this.nodeName,
73 | this.tenant
74 | );
75 | };
76 |
77 | do = (): Promise => {
78 | this.validate();
79 | if (this.errors.length > 0) {
80 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
81 | }
82 |
83 | return this.buildPath().then((path) => {
84 | return this.client.get(path);
85 | });
86 | };
87 | }
88 |
--------------------------------------------------------------------------------
/src/data/index.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { BeaconPath } from '../utils/beaconPath.js';
3 | import { DbVersionSupport } from '../utils/dbVersion.js';
4 | import Checker from './checker.js';
5 | import Creator from './creator.js';
6 | import Deleter from './deleter.js';
7 | import Getter from './getter.js';
8 | import GetterById from './getterById.js';
9 | import Merger from './merger.js';
10 | import { ObjectsPath, ReferencesPath } from './path.js';
11 | import ReferenceCreator from './referenceCreator.js';
12 | import ReferenceDeleter from './referenceDeleter.js';
13 | import ReferencePayloadBuilder from './referencePayloadBuilder.js';
14 | import ReferenceReplacer from './referenceReplacer.js';
15 | import Updater from './updater.js';
16 | import Validator from './validator.js';
17 |
18 | export interface Data {
19 | creator: () => Creator;
20 | validator: () => Validator;
21 | updater: () => Updater;
22 | merger: () => Merger;
23 | getter: () => Getter;
24 | getterById: () => GetterById;
25 | deleter: () => Deleter;
26 | checker: () => Checker;
27 | referenceCreator: () => ReferenceCreator;
28 | referenceReplacer: () => ReferenceReplacer;
29 | referenceDeleter: () => ReferenceDeleter;
30 | referencePayloadBuilder: () => ReferencePayloadBuilder;
31 | }
32 |
33 | const data = (client: Connection, dbVersionSupport: DbVersionSupport): Data => {
34 | const objectsPath = new ObjectsPath(dbVersionSupport);
35 | const referencesPath = new ReferencesPath(dbVersionSupport);
36 | const beaconPath = new BeaconPath(dbVersionSupport);
37 |
38 | return {
39 | creator: () => new Creator(client, objectsPath),
40 | validator: () => new Validator(client),
41 | updater: () => new Updater(client, objectsPath),
42 | merger: () => new Merger(client, objectsPath),
43 | getter: () => new Getter(client, objectsPath),
44 | getterById: () => new GetterById(client, objectsPath),
45 | deleter: () => new Deleter(client, objectsPath),
46 | checker: () => new Checker(client, objectsPath),
47 | referenceCreator: () => new ReferenceCreator(client, referencesPath, beaconPath),
48 | referenceReplacer: () => new ReferenceReplacer(client, referencesPath, beaconPath),
49 | referenceDeleter: () => new ReferenceDeleter(client, referencesPath, beaconPath),
50 | referencePayloadBuilder: () => new ReferencePayloadBuilder(client),
51 | };
52 | };
53 |
54 | export default data;
55 | export { default as Checker } from './checker.js';
56 | export { default as Creator } from './creator.js';
57 | export { default as Deleter } from './deleter.js';
58 | export { default as Getter } from './getter.js';
59 | export { default as GetterById } from './getterById.js';
60 | export { default as Merger } from './merger.js';
61 | export { default as ReferenceCreator } from './referenceCreator.js';
62 | export { default as ReferenceDeleter } from './referenceDeleter.js';
63 | export { default as ReferencePayloadBuilder } from './referencePayloadBuilder.js';
64 | export { default as ReferenceReplacer } from './referenceReplacer.js';
65 | export { default as Updater } from './updater.js';
66 | export { default as Validator } from './validator.js';
67 |
68 | export type { ConsistencyLevel } from './replication.js';
69 |
--------------------------------------------------------------------------------
/src/data/merger.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Properties, WeaviateObject } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { isValidStringProperty } from '../validation/string.js';
5 | import { ObjectsPath } from './path.js';
6 | import { ConsistencyLevel } from './replication.js';
7 |
8 | export default class Merger extends CommandBase {
9 | private className!: string;
10 | private consistencyLevel?: ConsistencyLevel;
11 | private id!: string;
12 | private objectsPath: ObjectsPath;
13 | private properties?: Properties;
14 | private tenant?: string;
15 |
16 | constructor(client: Connection, objectsPath: ObjectsPath) {
17 | super(client);
18 | this.objectsPath = objectsPath;
19 | }
20 |
21 | withProperties = (properties: Properties) => {
22 | this.properties = properties;
23 | return this;
24 | };
25 |
26 | withClassName = (className: string) => {
27 | this.className = className;
28 | return this;
29 | };
30 |
31 | withId = (id: string) => {
32 | this.id = id;
33 | return this;
34 | };
35 |
36 | withConsistencyLevel = (cl: ConsistencyLevel) => {
37 | this.consistencyLevel = cl;
38 | return this;
39 | };
40 |
41 | withTenant = (tenant: string) => {
42 | this.tenant = tenant;
43 | return this;
44 | };
45 |
46 | validateClassName = () => {
47 | if (!isValidStringProperty(this.className)) {
48 | this.addError('className must be set - set with withClassName(className)');
49 | }
50 | };
51 |
52 | validateId = () => {
53 | if (this.id == undefined || this.id == null || this.id.length == 0) {
54 | this.addError('id must be set - set with withId(id)');
55 | }
56 | };
57 |
58 | payload = (): WeaviateObject => ({
59 | tenant: this.tenant,
60 | properties: this.properties,
61 | class: this.className,
62 | id: this.id,
63 | });
64 |
65 | validate = () => {
66 | this.validateClassName();
67 | this.validateId();
68 | };
69 |
70 | do = () => {
71 | this.validate();
72 |
73 | if (this.errors.length > 0) {
74 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
75 | }
76 |
77 | return this.objectsPath
78 | .buildMerge(this.id, this.className, this.consistencyLevel)
79 | .then((path: string) => this.client.patch(path, this.payload()));
80 | };
81 | }
82 |
--------------------------------------------------------------------------------
/src/data/path.test.ts:
--------------------------------------------------------------------------------
1 | import { TestDbVersionProvider } from '../../test/dbVersionProvider.js';
2 | import { DbVersionSupport } from '../utils/dbVersion.js';
3 | import { ObjectsPath, ReferencesPath } from './path.js';
4 |
5 | // This can be anything > 1.14.2, to support class-namespaced urls.
6 | // The actual value is not used for anything else
7 | const version = '1.18.0';
8 |
9 | const objectsPathBuilder = new ObjectsPath(new DbVersionSupport(new TestDbVersionProvider(version)));
10 |
11 | const refsPathBuilder = new ReferencesPath(new DbVersionSupport(new TestDbVersionProvider(version)));
12 |
13 | describe('paths', () => {
14 | it('builds object create', () => {
15 | return objectsPathBuilder
16 | .buildCreate('ONE')
17 | .then((path) => expect(path).toEqual('/objects?consistency_level=ONE'))
18 | .catch((e) => fail(`unexpected error: ${e}`));
19 | });
20 |
21 | it('builds object delete', () => {
22 | return objectsPathBuilder
23 | .buildDelete('123456', 'SomeClass', 'ALL')
24 | .then((path) => expect(path).toEqual('/objects/SomeClass/123456?consistency_level=ALL'))
25 | .catch((e) => fail(`unexpected error: ${e}`));
26 | });
27 |
28 | it('builds object merge', () => {
29 | return objectsPathBuilder
30 | .buildMerge('123456', 'SomeClass', 'QUORUM')
31 | .then((path) => expect(path).toEqual('/objects/SomeClass/123456?consistency_level=QUORUM'))
32 | .catch((e) => fail(`unexpected error: ${e}`));
33 | });
34 |
35 | it('builds object update', () => {
36 | return objectsPathBuilder
37 | .buildUpdate('123456', 'SomeClass', 'ONE')
38 | .then((path) => expect(path).toEqual('/objects/SomeClass/123456?consistency_level=ONE'))
39 | .catch((e) => fail(`unexpected error: ${e}`));
40 | });
41 |
42 | it('builds references', () => {
43 | return refsPathBuilder
44 | .build('123456', 'SomeClass', 'SomeProp', 'ALL')
45 | .then((path) =>
46 | expect(path).toEqual('/objects/SomeClass/123456/references/SomeProp?consistency_level=ALL')
47 | )
48 | .catch((e) => fail(`unexpected error: ${e}`));
49 | });
50 | });
51 |
52 | describe('paths with tenantKey', () => {
53 | it('builds object delete', () => {
54 | return objectsPathBuilder
55 | .buildDelete('123456', 'SomeClass', 'ALL', 'tenantA')
56 | .then((path) => expect(path).toEqual('/objects/SomeClass/123456?consistency_level=ALL&tenant=tenantA'))
57 | .catch((e) => fail(`unexpected error: ${e}`));
58 | });
59 |
60 | it('builds references', () => {
61 | return refsPathBuilder
62 | .build('123456', 'SomeClass', 'SomeProp', 'ALL', 'tenantA')
63 | .then((path) =>
64 | expect(path).toEqual(
65 | '/objects/SomeClass/123456/references/SomeProp?consistency_level=ALL&tenant=tenantA'
66 | )
67 | )
68 | .catch((e) => fail(`unexpected error: ${e}`));
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/src/data/referenceCreator.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Reference } from '../openapi/types.js';
3 | import { BeaconPath } from '../utils/beaconPath.js';
4 | import { CommandBase } from '../validation/commandBase.js';
5 | import { ReferencesPath } from './path.js';
6 | import { ConsistencyLevel } from './replication.js';
7 |
8 | export default class ReferenceCreator extends CommandBase {
9 | private beaconPath: BeaconPath;
10 | private className!: string;
11 | private consistencyLevel?: ConsistencyLevel;
12 | private id!: string;
13 | private reference!: Reference;
14 | private referencesPath: ReferencesPath;
15 | private refProp!: string;
16 | private tenant?: string;
17 |
18 | constructor(client: Connection, referencesPath: ReferencesPath, beaconPath: BeaconPath) {
19 | super(client);
20 | this.referencesPath = referencesPath;
21 | this.beaconPath = beaconPath;
22 | }
23 |
24 | withId = (id: string) => {
25 | this.id = id;
26 | return this;
27 | };
28 |
29 | withClassName(className: string) {
30 | this.className = className;
31 | return this;
32 | }
33 |
34 | withReference = (ref: Reference) => {
35 | this.reference = ref;
36 | return this;
37 | };
38 |
39 | withReferenceProperty = (refProp: string) => {
40 | this.refProp = refProp;
41 | return this;
42 | };
43 |
44 | withConsistencyLevel = (cl: ConsistencyLevel) => {
45 | this.consistencyLevel = cl;
46 | return this;
47 | };
48 |
49 | withTenant = (tenant: string) => {
50 | this.tenant = tenant;
51 | return this;
52 | };
53 |
54 | validateIsSet = (prop: string | undefined | null, name: string, setter: string) => {
55 | if (prop == undefined || prop == null || prop.length == 0) {
56 | this.addError(`${name} must be set - set with ${setter}`);
57 | }
58 | };
59 |
60 | validate = () => {
61 | this.validateIsSet(this.id, 'id', '.withId(id)');
62 | this.validateIsSet(this.refProp, 'referenceProperty', '.withReferenceProperty(refProp)');
63 | };
64 |
65 | payload = () => this.reference;
66 |
67 | do = () => {
68 | this.validate();
69 | if (this.errors.length > 0) {
70 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
71 | }
72 |
73 | if (!this.reference.beacon) {
74 | throw new Error('reference beacon must be set');
75 | }
76 |
77 | return Promise.all([
78 | this.referencesPath.build(this.id, this.className, this.refProp, this.consistencyLevel, this.tenant),
79 | this.beaconPath.rebuild(this.reference.beacon),
80 | ]).then((results) => {
81 | const path = results[0];
82 | const beacon = results[1];
83 | return this.client.postEmpty(path, { beacon });
84 | });
85 | };
86 | }
87 |
--------------------------------------------------------------------------------
/src/data/referenceDeleter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Reference } from '../openapi/types.js';
3 | import { BeaconPath } from '../utils/beaconPath.js';
4 | import { CommandBase } from '../validation/commandBase.js';
5 | import { ReferencesPath } from './path.js';
6 | import { ConsistencyLevel } from './replication.js';
7 |
8 | export default class ReferenceDeleter extends CommandBase {
9 | private beaconPath: BeaconPath;
10 | private className!: string;
11 | private consistencyLevel?: ConsistencyLevel;
12 | private id!: string;
13 | private reference!: Reference;
14 | private referencesPath: ReferencesPath;
15 | private refProp!: string;
16 | private tenant?: string;
17 |
18 | constructor(client: Connection, referencesPath: ReferencesPath, beaconPath: BeaconPath) {
19 | super(client);
20 | this.referencesPath = referencesPath;
21 | this.beaconPath = beaconPath;
22 | }
23 |
24 | withId = (id: string) => {
25 | this.id = id;
26 | return this;
27 | };
28 |
29 | withClassName(className: string) {
30 | this.className = className;
31 | return this;
32 | }
33 |
34 | withReference = (ref: Reference) => {
35 | this.reference = ref;
36 | return this;
37 | };
38 |
39 | withReferenceProperty = (refProp: string) => {
40 | this.refProp = refProp;
41 | return this;
42 | };
43 |
44 | withConsistencyLevel = (cl: ConsistencyLevel) => {
45 | this.consistencyLevel = cl;
46 | return this;
47 | };
48 |
49 | withTenant = (tenant: string) => {
50 | this.tenant = tenant;
51 | return this;
52 | };
53 |
54 | validateIsSet = (prop: string | undefined | null, name: string, setter: string) => {
55 | if (prop == undefined || prop == null || prop.length == 0) {
56 | this.addError(`${name} must be set - set with ${setter}`);
57 | }
58 | };
59 |
60 | validate = () => {
61 | this.validateIsSet(this.id, 'id', '.withId(id)');
62 | this.validateIsSet(this.refProp, 'referenceProperty', '.withReferenceProperty(refProp)');
63 | };
64 |
65 | payload = () => this.reference;
66 |
67 | do = () => {
68 | this.validate();
69 | if (this.errors.length > 0) {
70 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
71 | }
72 |
73 | if (!this.reference.beacon) {
74 | throw new Error('reference beacon must be set');
75 | }
76 |
77 | return Promise.all([
78 | this.referencesPath.build(this.id, this.className, this.refProp, this.consistencyLevel, this.tenant),
79 | this.beaconPath.rebuild(this.reference.beacon),
80 | ]).then((results) => {
81 | const path = results[0];
82 | const beacon = results[1];
83 | return this.client.delete(path, { beacon }, false);
84 | });
85 | };
86 | }
87 |
--------------------------------------------------------------------------------
/src/data/referencePayloadBuilder.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Reference } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { isValidStringProperty } from '../validation/string.js';
5 |
6 | export default class ReferencePayloadBuilder extends CommandBase {
7 | private className?: string;
8 | private id?: string;
9 |
10 | constructor(client: Connection) {
11 | super(client);
12 | }
13 |
14 | withId = (id: string) => {
15 | this.id = id;
16 | return this;
17 | };
18 |
19 | withClassName(className: string) {
20 | this.className = className;
21 | return this;
22 | }
23 |
24 | validateIsSet = (prop: string | undefined | null, name: string, setter: string) => {
25 | if (prop == undefined || prop == null || prop.length == 0) {
26 | this.addError(`${name} must be set - set with ${setter}`);
27 | }
28 | };
29 |
30 | validate = () => {
31 | this.validateIsSet(this.id, 'id', '.withId(id)');
32 | };
33 |
34 | payload = (): Reference => {
35 | this.validate();
36 | if (this.errors.length > 0) {
37 | throw new Error(this.errors.join(', '));
38 | }
39 |
40 | let beacon = `weaviate://localhost`;
41 | if (isValidStringProperty(this.className)) {
42 | beacon = `${beacon}/${this.className}`;
43 | }
44 | return {
45 | beacon: `${beacon}/${this.id}`,
46 | };
47 | };
48 |
49 | do(): Promise {
50 | return Promise.reject(new Error('Should never be called'));
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/data/referenceReplacer.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Reference } from '../openapi/types.js';
3 | import { BeaconPath } from '../utils/beaconPath.js';
4 | import { CommandBase } from '../validation/commandBase.js';
5 | import { ReferencesPath } from './path.js';
6 | import { ConsistencyLevel } from './replication.js';
7 |
8 | export default class ReferenceReplacer extends CommandBase {
9 | private beaconPath: BeaconPath;
10 | private className!: string;
11 | private consistencyLevel?: ConsistencyLevel;
12 | private id!: string;
13 | private references!: Reference[];
14 | private referencesPath: ReferencesPath;
15 | private refProp!: string;
16 | private tenant?: string;
17 |
18 | constructor(client: Connection, referencesPath: ReferencesPath, beaconPath: BeaconPath) {
19 | super(client);
20 | this.beaconPath = beaconPath;
21 | this.referencesPath = referencesPath;
22 | }
23 |
24 | withId = (id: string) => {
25 | this.id = id;
26 | return this;
27 | };
28 |
29 | withClassName(className: string) {
30 | this.className = className;
31 | return this;
32 | }
33 |
34 | withReferences = (refs: any) => {
35 | this.references = refs;
36 | return this;
37 | };
38 |
39 | withReferenceProperty = (refProp: string) => {
40 | this.refProp = refProp;
41 | return this;
42 | };
43 |
44 | withConsistencyLevel = (cl: ConsistencyLevel) => {
45 | this.consistencyLevel = cl;
46 | return this;
47 | };
48 |
49 | withTenant = (tenant: string) => {
50 | this.tenant = tenant;
51 | return this;
52 | };
53 |
54 | validateIsSet = (prop: string | undefined | null, name: string, setter: string) => {
55 | if (prop == undefined || prop == null || prop.length == 0) {
56 | this.addError(`${name} must be set - set with ${setter}`);
57 | }
58 | };
59 |
60 | validate = () => {
61 | this.validateIsSet(this.id, 'id', '.withId(id)');
62 | this.validateIsSet(this.refProp, 'referenceProperty', '.withReferenceProperty(refProp)');
63 | };
64 |
65 | payload = () => this.references;
66 |
67 | do = () => {
68 | this.validate();
69 | if (this.errors.length > 0) {
70 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
71 | }
72 |
73 | const payloadPromise = Array.isArray(this.references)
74 | ? Promise.all(this.references.map((ref) => this.rebuildReferencePromise(ref)))
75 | : Promise.resolve([]);
76 |
77 | return Promise.all([
78 | this.referencesPath.build(this.id, this.className, this.refProp, this.consistencyLevel, this.tenant),
79 | payloadPromise,
80 | ]).then((results) => {
81 | const path = results[0];
82 | const payload = results[1];
83 | return this.client.put(path, payload, false);
84 | });
85 | };
86 |
87 | rebuildReferencePromise(reference: any) {
88 | return this.beaconPath.rebuild(reference.beacon).then((beacon: any) => ({ beacon }));
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/data/replication.ts:
--------------------------------------------------------------------------------
1 | export type ConsistencyLevel = 'ALL' | 'ONE' | 'QUORUM';
2 |
--------------------------------------------------------------------------------
/src/data/updater.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Properties, WeaviateObject } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { isValidStringProperty } from '../validation/string.js';
5 | import { ObjectsPath } from './path.js';
6 | import { ConsistencyLevel } from './replication.js';
7 |
8 | export default class Updater extends CommandBase {
9 | private className!: string;
10 | private consistencyLevel?: ConsistencyLevel;
11 | private id!: string;
12 | private objectsPath: ObjectsPath;
13 | private properties?: Properties;
14 | private tenant?: string;
15 | private vector?: number[];
16 | private vectors?: Record;
17 |
18 | constructor(client: Connection, objectsPath: ObjectsPath) {
19 | super(client);
20 | this.objectsPath = objectsPath;
21 | }
22 |
23 | withVector = (vector: number[]) => {
24 | this.vector = vector;
25 | return this;
26 | };
27 |
28 | withVectors = (vectors: Record) => {
29 | this.vectors = vectors;
30 | return this;
31 | };
32 |
33 | withProperties = (properties: Properties) => {
34 | this.properties = properties;
35 | return this;
36 | };
37 |
38 | withId = (id: string) => {
39 | this.id = id;
40 | return this;
41 | };
42 |
43 | withClassName = (className: string) => {
44 | this.className = className;
45 | return this;
46 | };
47 |
48 | withTenant = (tenant: string) => {
49 | this.tenant = tenant;
50 | return this;
51 | };
52 |
53 | validateClassName = () => {
54 | if (!isValidStringProperty(this.className)) {
55 | this.addError('className must be set - use withClassName(className)');
56 | }
57 | };
58 |
59 | validateId = () => {
60 | if (this.id == undefined || this.id == null || this.id.length == 0) {
61 | this.addError('id must be set - initialize with updater(id)');
62 | }
63 | };
64 |
65 | withConsistencyLevel = (cl: ConsistencyLevel) => {
66 | this.consistencyLevel = cl;
67 | return this;
68 | };
69 |
70 | // as Record required below because server uses swagger object as interface{} in Go to perform type switching
71 | // actual types are []number and [][]number but unions don't work in go-swagger
72 | payload = (): WeaviateObject => ({
73 | tenant: this.tenant,
74 | properties: this.properties,
75 | class: this.className,
76 | id: this.id,
77 | vector: this.vector,
78 | vectors: this.vectors as Record,
79 | });
80 |
81 | validate = () => {
82 | this.validateClassName();
83 | this.validateId();
84 | };
85 |
86 | do = () => {
87 | this.validate();
88 |
89 | if (this.errors.length > 0) {
90 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
91 | }
92 |
93 | return this.objectsPath
94 | .buildUpdate(this.id, this.className, this.consistencyLevel)
95 | .then((path: string) => this.client.put(path, this.payload()));
96 | };
97 | }
98 |
--------------------------------------------------------------------------------
/src/data/validator.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Properties } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { isValidStringProperty } from '../validation/string.js';
5 |
6 | export default class Validator extends CommandBase {
7 | private className?: string;
8 | private id?: string;
9 | private properties?: Properties;
10 |
11 | constructor(client: Connection) {
12 | super(client);
13 | }
14 |
15 | withClassName = (className: string) => {
16 | this.className = className;
17 | return this;
18 | };
19 |
20 | withProperties = (properties: Properties) => {
21 | this.properties = properties;
22 | return this;
23 | };
24 |
25 | withId = (id: string) => {
26 | this.id = id;
27 | return this;
28 | };
29 |
30 | validateClassName = () => {
31 | if (!isValidStringProperty(this.className)) {
32 | this.addError('className must be set - set with .withClassName(className)');
33 | }
34 | };
35 |
36 | payload = () => ({
37 | properties: this.properties,
38 | class: this.className,
39 | id: this.id,
40 | });
41 |
42 | validate = () => {
43 | this.validateClassName();
44 | };
45 |
46 | do = () => {
47 | this.validate();
48 | if (this.errors.length > 0) {
49 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
50 | }
51 | const path = `/objects/validate`;
52 | return this.client.postEmpty(path, this.payload()).then(() => true);
53 | };
54 | }
55 |
--------------------------------------------------------------------------------
/src/graphql/ask.ts:
--------------------------------------------------------------------------------
1 | export interface AskArgs {
2 | autocorrect?: boolean;
3 | certainty?: number;
4 | distance?: number;
5 | properties?: string[];
6 | question?: string;
7 | rerank?: boolean;
8 | }
9 |
10 | export default class GraphQLAsk {
11 | private autocorrect?: boolean;
12 | private certainty?: number;
13 | private distance?: number;
14 | private properties?: string[];
15 | private question?: string;
16 | private rerank?: boolean;
17 |
18 | constructor(args: AskArgs) {
19 | this.autocorrect = args.autocorrect;
20 | this.certainty = args.certainty;
21 | this.distance = args.distance;
22 | this.properties = args.properties;
23 | this.question = args.question;
24 | this.rerank = args.rerank;
25 | }
26 |
27 | toString(wrap = true) {
28 | this.validate();
29 |
30 | let args: any[] = [];
31 |
32 | if (this.question) {
33 | args = [...args, `question:${JSON.stringify(this.question)}`];
34 | }
35 |
36 | if (this.properties) {
37 | args = [...args, `properties:${JSON.stringify(this.properties)}`];
38 | }
39 |
40 | if (this.certainty) {
41 | args = [...args, `certainty:${this.certainty}`];
42 | }
43 |
44 | if (this.distance) {
45 | args = [...args, `distance:${this.distance}`];
46 | }
47 |
48 | if (this.autocorrect !== undefined) {
49 | args = [...args, `autocorrect:${this.autocorrect}`];
50 | }
51 |
52 | if (this.rerank !== undefined) {
53 | args = [...args, `rerank:${this.rerank}`];
54 | }
55 |
56 | if (!wrap) {
57 | return `${args.join(',')}`;
58 | }
59 | return `{${args.join(',')}}`;
60 | }
61 |
62 | validate() {
63 | if (!this.question) {
64 | throw new Error('ask filter: question needs to be set');
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/graphql/bm25.ts:
--------------------------------------------------------------------------------
1 | export interface Bm25Args {
2 | properties?: string[];
3 | query: string;
4 | }
5 |
6 | export default class GraphQLBm25 {
7 | private properties?: string[];
8 | private query: string;
9 |
10 | constructor(args: Bm25Args) {
11 | this.properties = args.properties;
12 | this.query = args.query;
13 | }
14 |
15 | toString() {
16 | let args = [`query:${JSON.stringify(this.query)}`]; // query must always be set
17 |
18 | if (this.properties !== undefined) {
19 | args = [...args, `properties:${JSON.stringify(this.properties)}`];
20 | }
21 |
22 | return `{${args.join(',')}}`;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/graphql/generate.ts:
--------------------------------------------------------------------------------
1 | export interface GenerateArgs {
2 | groupedTask?: string;
3 | groupedProperties?: string[];
4 | singlePrompt?: string;
5 | }
6 |
7 | export interface GenerateParts {
8 | singleResult?: string;
9 | groupedResult?: string;
10 | results: string[];
11 | }
12 |
13 | export class GraphQLGenerate {
14 | private groupedTask?: string;
15 | private groupedProperties?: string[];
16 | private singlePrompt?: string;
17 |
18 | constructor(args: GenerateArgs) {
19 | this.groupedTask = args.groupedTask;
20 | this.groupedProperties = args.groupedProperties;
21 | this.singlePrompt = args.singlePrompt;
22 | }
23 |
24 | toString(): string {
25 | this.validate();
26 |
27 | let str = 'generate(';
28 | const results = ['error'];
29 | if (this.singlePrompt) {
30 | str += `singleResult:{prompt:"${this.singlePrompt.replace(/[\n\r]+/g, '')}"}`;
31 | results.push('singleResult');
32 | }
33 | if (this.groupedTask || (this.groupedProperties !== undefined && this.groupedProperties.length > 0)) {
34 | const args: string[] = [];
35 | if (this.groupedTask) {
36 | args.push(`task:"${this.groupedTask.replace(/[\n\r]+/g, '')}"`);
37 | }
38 | if (this.groupedProperties !== undefined && this.groupedProperties.length > 0) {
39 | args.push(`properties:${JSON.stringify(this.groupedProperties)}`);
40 | }
41 | str += `groupedResult:{${args.join(',')}}`;
42 | results.push('groupedResult');
43 | }
44 | str += `){${results.join(' ')}}`;
45 | return str;
46 | }
47 |
48 | private validate() {
49 | if (!this.groupedTask && !this.singlePrompt) {
50 | throw new Error('must provide at least one of `singlePrompt` or `groupTask`');
51 | }
52 | if (this.groupedTask !== undefined && this.groupedTask == '') {
53 | throw new Error('groupedTask must not be empty');
54 | }
55 | if (this.singlePrompt !== undefined && this.singlePrompt == '') {
56 | throw new Error('singlePrompt must not be empty');
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/graphql/group.ts:
--------------------------------------------------------------------------------
1 | export interface GroupArgs {
2 | type: string;
3 | force: number;
4 | }
5 |
6 | export default class GraphQLGroup {
7 | private args: GroupArgs;
8 |
9 | constructor(args: GroupArgs) {
10 | this.args = args;
11 | }
12 |
13 | toString() {
14 | let parts: any[] = [];
15 |
16 | if (this.args.type) {
17 | // value is a graphQL enum, so doesn't need to be quoted
18 | parts = [...parts, `type:${this.args.type}`];
19 | }
20 |
21 | if (this.args.force) {
22 | parts = [...parts, `force:${this.args.force}`];
23 | }
24 |
25 | return `{${parts.join(',')}}`;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/graphql/groupBy.ts:
--------------------------------------------------------------------------------
1 | export interface GroupByArgs {
2 | path: string[];
3 | groups: number;
4 | objectsPerGroup: number;
5 | }
6 |
7 | export default class GraphQLGroupBy {
8 | private args: GroupByArgs;
9 |
10 | constructor(args: GroupByArgs) {
11 | this.args = args;
12 | }
13 |
14 | toString() {
15 | let parts: string[] = [];
16 |
17 | if (this.args.path) {
18 | parts = [...parts, `path:${JSON.stringify(this.args.path)}`];
19 | }
20 |
21 | if (this.args.groups) {
22 | parts = [...parts, `groups:${this.args.groups}`];
23 | }
24 |
25 | if (this.args.objectsPerGroup) {
26 | parts = [...parts, `objectsPerGroup:${this.args.objectsPerGroup}`];
27 | }
28 |
29 | return `{${parts.join(',')}}`;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/graphql/index.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import Aggregator from './aggregator.js';
3 | import Explorer from './explorer.js';
4 | import GraphQLGetter from './getter.js';
5 | import Raw from './raw.js';
6 |
7 | export interface GraphQL {
8 | get: () => GraphQLGetter;
9 | aggregate: () => Aggregator;
10 | explore: () => Explorer;
11 | raw: () => Raw;
12 | }
13 |
14 | const graphql = (client: Connection): GraphQL => {
15 | return {
16 | get: () => new GraphQLGetter(client),
17 | aggregate: () => new Aggregator(client),
18 | explore: () => new Explorer(client),
19 | raw: () => new Raw(client),
20 | };
21 | };
22 |
23 | export default graphql;
24 | export { default as Aggregator } from './aggregator.js';
25 | export { default as Explorer } from './explorer.js';
26 | export { FusionType, default as GraphQLGetter } from './getter.js';
27 | export { default as Raw } from './raw.js';
28 |
--------------------------------------------------------------------------------
/src/graphql/nearImage.ts:
--------------------------------------------------------------------------------
1 | import { NearMediaBase } from './nearMedia.js';
2 |
3 | export interface NearImageArgs extends NearMediaBase {
4 | image?: string;
5 | targetVectors?: string[];
6 | }
7 |
8 | export default class GraphQLNearImage {
9 | private certainty?: number;
10 | private distance?: number;
11 | private image?: string;
12 | private targetVectors?: string[];
13 |
14 | constructor(args: NearImageArgs) {
15 | this.certainty = args.certainty;
16 | this.distance = args.distance;
17 | this.image = args.image;
18 | this.targetVectors = args.targetVectors;
19 | }
20 |
21 | toString(wrap = true) {
22 | this.validate();
23 |
24 | let args: string[] = [];
25 |
26 | if (this.image) {
27 | let img = this.image;
28 | if (img.startsWith('data:')) {
29 | const base64part = ';base64,';
30 | img = img.substring(img.indexOf(base64part) + base64part.length);
31 | }
32 | args = [...args, `image:${JSON.stringify(img)}`];
33 | }
34 |
35 | if (this.certainty) {
36 | args = [...args, `certainty:${this.certainty}`];
37 | }
38 |
39 | if (this.distance) {
40 | args = [...args, `distance:${this.distance}`];
41 | }
42 |
43 | if (this.targetVectors && this.targetVectors.length > 0) {
44 | args = [...args, `targetVectors:${JSON.stringify(this.targetVectors)}`];
45 | }
46 |
47 | if (!wrap) {
48 | return `${args.join(',')}`;
49 | }
50 | return `{${args.join(',')}}`;
51 | }
52 |
53 | validate() {
54 | if (!this.image) {
55 | throw new Error('nearImage filter: image field must be present');
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/graphql/nearMedia.ts:
--------------------------------------------------------------------------------
1 | export interface NearMediaBase {
2 | certainty?: number;
3 | distance?: number;
4 | targetVectors?: string[];
5 | }
6 | export interface NearMediaArgs extends NearMediaBase {
7 | media: string;
8 | type: NearMediaType;
9 | }
10 | export interface NearImageArgs extends NearMediaBase {
11 | image: string;
12 | }
13 | export interface NearAudioArgs extends NearMediaBase {
14 | audio: string;
15 | }
16 | export interface NearVideoArgs extends NearMediaBase {
17 | video: string;
18 | }
19 | export interface NearThermalArgs extends NearMediaBase {
20 | thermal: string;
21 | }
22 | export interface NearDepthArgs extends NearMediaBase {
23 | depth: string;
24 | }
25 | export interface NearIMUArgs extends NearMediaBase {
26 | imu: string;
27 | }
28 |
29 | export enum NearMediaType {
30 | Image = 'Image',
31 | Audio = 'Audio',
32 | Video = 'Video',
33 | Thermal = 'Thermal',
34 | Depth = 'Depth',
35 | IMU = 'IMU',
36 | }
37 |
38 | export default class GraphQLNearMedia {
39 | private certainty?: number;
40 | private distance?: number;
41 | private media: string;
42 | private type: NearMediaType;
43 | private targetVectors?: string[];
44 |
45 | constructor(args: NearMediaArgs) {
46 | this.certainty = args.certainty;
47 | this.distance = args.distance;
48 | this.media = args.media;
49 | this.type = args.type;
50 | this.targetVectors = args.targetVectors;
51 | }
52 |
53 | toString(wrap = true) {
54 | let args: string[] = [];
55 |
56 | if (this.media.startsWith('data:')) {
57 | const base64part = ';base64,';
58 | this.media = this.media.substring(this.media.indexOf(base64part) + base64part.length);
59 | }
60 | args = [...args, `${this.type.toLowerCase()}:${JSON.stringify(this.media)}`];
61 |
62 | if (this.certainty) {
63 | args = [...args, `certainty:${this.certainty}`];
64 | }
65 |
66 | if (this.distance) {
67 | args = [...args, `distance:${this.distance}`];
68 | }
69 |
70 | if (this.targetVectors && this.targetVectors.length > 0) {
71 | args = [...args, `targetVectors:${JSON.stringify(this.targetVectors)}`];
72 | }
73 |
74 | if (!wrap) {
75 | return `${args.join(',')}`;
76 | }
77 | return `{${args.join(',')}}`;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/graphql/nearObject.ts:
--------------------------------------------------------------------------------
1 | export interface NearObjectArgs {
2 | beacon?: string;
3 | certainty?: number;
4 | distance?: number;
5 | id?: string;
6 | targetVectors?: string[];
7 | }
8 |
9 | export default class GraphQLNearObject {
10 | private beacon?: string;
11 | private certainty?: number;
12 | private distance?: number;
13 | private id?: string;
14 | private targetVectors?: string[];
15 |
16 | constructor(args: NearObjectArgs) {
17 | this.beacon = args.beacon;
18 | this.certainty = args.certainty;
19 | this.distance = args.distance;
20 | this.id = args.id;
21 | this.targetVectors = args.targetVectors;
22 | }
23 |
24 | toString(wrap = true) {
25 | this.validate();
26 |
27 | let args: any[] = [];
28 |
29 | if (this.id) {
30 | args = [...args, `id:${JSON.stringify(this.id)}`];
31 | }
32 |
33 | if (this.beacon) {
34 | args = [...args, `beacon:${JSON.stringify(this.beacon)}`];
35 | }
36 |
37 | if (this.certainty) {
38 | args = [...args, `certainty:${this.certainty}`];
39 | }
40 |
41 | if (this.distance) {
42 | args = [...args, `distance:${this.distance}`];
43 | }
44 |
45 | if (this.targetVectors && this.targetVectors.length > 0) {
46 | args = [...args, `targetVectors:${JSON.stringify(this.targetVectors)}`];
47 | }
48 |
49 | if (!wrap) {
50 | return `${args.join(',')}`;
51 | }
52 | return `{${args.join(',')}}`;
53 | }
54 |
55 | validate() {
56 | if (!this.id && !this.beacon) {
57 | throw new Error('nearObject filter: id or beacon needs to be set');
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/graphql/nearVector.ts:
--------------------------------------------------------------------------------
1 | export interface NearVectorArgs {
2 | certainty?: number;
3 | distance?: number;
4 | vector: number[];
5 | targetVectors?: string[];
6 | }
7 |
8 | export default class GraphQLNearVector {
9 | private certainty?: number;
10 | private distance?: number;
11 | private vector: number[];
12 | private targetVectors?: string[];
13 |
14 | constructor(args: NearVectorArgs) {
15 | this.certainty = args.certainty;
16 | this.distance = args.distance;
17 | this.vector = args.vector;
18 | this.targetVectors = args.targetVectors;
19 | }
20 |
21 | toString(wrap = true) {
22 | let args = [`vector:${JSON.stringify(this.vector)}`]; // vector must always be set
23 |
24 | if (this.certainty) {
25 | args = [...args, `certainty:${this.certainty}`];
26 | }
27 |
28 | if (this.distance) {
29 | args = [...args, `distance:${this.distance}`];
30 | }
31 |
32 | if (this.targetVectors && this.targetVectors.length > 0) {
33 | args = [...args, `targetVectors:${JSON.stringify(this.targetVectors)}`];
34 | }
35 |
36 | if (!wrap) {
37 | return `${args.join(',')}`;
38 | }
39 | return `{${args.join(',')}}`;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/graphql/raw.test.ts:
--------------------------------------------------------------------------------
1 | import Raw from './raw.js';
2 |
3 | test('a simple raw query', () => {
4 | const mockClient: any = {
5 | query: jest.fn(),
6 | };
7 |
8 | const expectedQuery = `{Get{Person{name}}}`;
9 |
10 | new Raw(mockClient).withQuery(expectedQuery).do();
11 |
12 | expect(mockClient.query).toHaveBeenCalledWith(expectedQuery);
13 | });
14 |
15 | test('reject empty raw query', () => {
16 | const mockClient: any = {
17 | query: jest.fn(),
18 | };
19 |
20 | new Raw(mockClient).do().catch((err: Error) => {
21 | expect(err.message).toEqual('invalid usage: query must be set - set with .raw().withQuery(query)');
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/src/graphql/raw.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { CommandBase } from '../validation/commandBase.js';
3 |
4 | export default class RawGraphQL extends CommandBase {
5 | private query?: string;
6 |
7 | constructor(client: Connection) {
8 | super(client);
9 | }
10 |
11 | withQuery = (query: string) => {
12 | this.query = query;
13 | return this;
14 | };
15 |
16 | validateIsSet = (prop: string | undefined | null, name: string, setter: string) => {
17 | if (prop == undefined || prop == null || prop.length == 0) {
18 | this.addError(`${name} must be set - set with ${setter}`);
19 | }
20 | };
21 |
22 | validate = () => {
23 | this.validateIsSet(this.query, 'query', '.raw().withQuery(query)');
24 | };
25 |
26 | do = (): Promise => {
27 | const params = '';
28 |
29 | this.validate();
30 | if (this.errors.length > 0) {
31 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
32 | }
33 |
34 | if (this.query) {
35 | return this.client.query(this.query);
36 | }
37 |
38 | return Promise.resolve(undefined);
39 | };
40 | }
41 |
--------------------------------------------------------------------------------
/src/graphql/sort.ts:
--------------------------------------------------------------------------------
1 | export interface SortArgs {
2 | path: string[];
3 | order?: string;
4 | }
5 |
6 | export type SortOrder = 'asc' | 'desc';
7 |
8 | export default class GraphQLSort {
9 | private args: SortArgs[];
10 |
11 | constructor(args: SortArgs[]) {
12 | this.args = args;
13 | }
14 |
15 | toString(): string {
16 | const parts: string[] = [];
17 |
18 | for (const arg of this.args) {
19 | let part = `{path:${JSON.stringify(arg.path)}`;
20 | if (arg.order) {
21 | part = part.concat(`,order:${arg.order}}`);
22 | } else {
23 | part = part.concat('}');
24 | }
25 | parts.push(part);
26 | }
27 |
28 | return parts.join(',');
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/grpc/base.ts:
--------------------------------------------------------------------------------
1 | import { ConsistencyLevel } from '../data/index.js';
2 |
3 | import { Metadata } from 'nice-grpc';
4 | import { RetryOptions } from 'nice-grpc-client-middleware-retry';
5 | import { ConsistencyLevel as ConsistencyLevelGRPC } from '../proto/v1/base.js';
6 | import { WeaviateClient } from '../proto/v1/weaviate.js';
7 |
8 | export default class Base {
9 | protected connection: WeaviateClient;
10 | protected collection: string;
11 | protected timeout: number;
12 | protected consistencyLevel?: ConsistencyLevelGRPC;
13 | protected tenant?: string;
14 | protected metadata?: Metadata;
15 |
16 | protected constructor(
17 | connection: WeaviateClient,
18 | collection: string,
19 | metadata: Metadata,
20 | timeout: number,
21 | consistencyLevel?: ConsistencyLevel,
22 | tenant?: string
23 | ) {
24 | this.connection = connection;
25 | this.collection = collection;
26 | this.metadata = metadata;
27 | this.timeout = timeout;
28 | this.consistencyLevel = this.mapConsistencyLevel(consistencyLevel);
29 | this.tenant = tenant;
30 | }
31 |
32 | private mapConsistencyLevel(consistencyLevel?: ConsistencyLevel): ConsistencyLevelGRPC {
33 | switch (consistencyLevel) {
34 | case 'ALL':
35 | return ConsistencyLevelGRPC.CONSISTENCY_LEVEL_ALL;
36 | case 'QUORUM':
37 | return ConsistencyLevelGRPC.CONSISTENCY_LEVEL_QUORUM;
38 | case 'ONE':
39 | return ConsistencyLevelGRPC.CONSISTENCY_LEVEL_ONE;
40 | default:
41 | return ConsistencyLevelGRPC.CONSISTENCY_LEVEL_UNSPECIFIED;
42 | }
43 | }
44 |
45 | protected sendWithTimeout = (send: (signal: AbortSignal) => Promise): Promise => {
46 | const controller = new AbortController();
47 | const timeoutId = setTimeout(() => controller.abort(), this.timeout * 1000);
48 | return send(controller.signal).finally(() => clearTimeout(timeoutId));
49 | };
50 | }
51 |
--------------------------------------------------------------------------------
/src/grpc/retry.ts:
--------------------------------------------------------------------------------
1 | import { ClientError, Status } from 'nice-grpc';
2 | import { RetryOptions } from 'nice-grpc-client-middleware-retry';
3 |
4 | export const retryOptions: RetryOptions = {
5 | retry: true,
6 | retryMaxAttempts: 5,
7 | retryableStatuses: [Status.UNAVAILABLE],
8 | onRetryableError(error: ClientError, attempt: number, delayMs: number) {
9 | console.warn(error, `Attempt ${attempt} failed. Retrying in ${delayMs}ms.`);
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/src/grpc/tenantsManager.ts:
--------------------------------------------------------------------------------
1 | import { isAbortError } from 'abort-controller-x';
2 | import { Metadata, ServerError, Status } from 'nice-grpc';
3 | import { RetryOptions } from 'nice-grpc-client-middleware-retry';
4 | import {
5 | WeaviateInsufficientPermissionsError,
6 | WeaviateRequestTimeoutError,
7 | WeaviateTenantsGetError,
8 | } from '../errors.js';
9 | import { TenantsGetReply, TenantsGetRequest } from '../proto/v1/tenants.js';
10 | import { WeaviateClient } from '../proto/v1/weaviate.js';
11 | import Base from './base.js';
12 | import { retryOptions } from './retry.js';
13 |
14 | export type TenantsGetArgs = {
15 | names?: string[];
16 | };
17 |
18 | export interface Tenants {
19 | withGet: (args: TenantsGetArgs) => Promise;
20 | }
21 |
22 | export default class TenantsManager extends Base implements Tenants {
23 | public static use(
24 | connection: WeaviateClient,
25 | collection: string,
26 | metadata: Metadata,
27 | timeout: number
28 | ): Tenants {
29 | return new TenantsManager(connection, collection, metadata, timeout);
30 | }
31 |
32 | public withGet = (args: TenantsGetArgs) =>
33 | this.call(TenantsGetRequest.fromPartial({ names: args.names ? { values: args.names } : undefined }));
34 |
35 | private call(message: TenantsGetRequest) {
36 | return this.sendWithTimeout((signal: AbortSignal) =>
37 | this.connection
38 | .tenantsGet(
39 | {
40 | ...message,
41 | collection: this.collection,
42 | },
43 | {
44 | metadata: this.metadata,
45 | signal,
46 | ...retryOptions,
47 | }
48 | )
49 | .catch((err) => {
50 | if (err instanceof ServerError && err.code === Status.PERMISSION_DENIED) {
51 | throw new WeaviateInsufficientPermissionsError(7, err.message);
52 | }
53 | if (isAbortError(err)) {
54 | throw new WeaviateRequestTimeoutError(`timed out after ${this.timeout}ms`);
55 | }
56 | throw new WeaviateTenantsGetError(err.message);
57 | })
58 | );
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/integration.test.ts:
--------------------------------------------------------------------------------
1 | import weaviate from './index.js';
2 |
3 | describe('Integration testing of the client methods', () => {
4 | it('should connect using connectToLocal defaults', () => {
5 | return weaviate.connectToLocal();
6 | });
7 |
8 | it('should connect using connectToLocal with schema-ed host', () => {
9 | const logSpy = jest.spyOn(console, 'warn');
10 | return weaviate
11 | .connectToLocal({
12 | host: 'http://localhost',
13 | })
14 | .then(() => expect(logSpy).toHaveBeenCalledTimes(2));
15 | });
16 |
17 | it('should connect using connectToLocal with non-schema-ed host', () => {
18 | return weaviate.connectToLocal({
19 | host: 'localhost',
20 | });
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/src/misc/index.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { DbVersionProvider } from '../utils/dbVersion.js';
3 | import LiveChecker from './liveChecker.js';
4 | import MetaGetter from './metaGetter.js';
5 | import OpenidConfigurationGetter from './openidConfigurationGetter.js';
6 | import ReadyChecker from './readyChecker.js';
7 |
8 | export interface Misc {
9 | liveChecker: () => LiveChecker;
10 | readyChecker: () => ReadyChecker;
11 | metaGetter: () => MetaGetter;
12 | openidConfigurationGetter: () => OpenidConfigurationGetter;
13 | }
14 |
15 | const misc = (client: Connection, dbVersionProvider: DbVersionProvider): Misc => {
16 | return {
17 | liveChecker: () => new LiveChecker(client, dbVersionProvider),
18 | readyChecker: () => new ReadyChecker(client, dbVersionProvider),
19 | metaGetter: () => new MetaGetter(client),
20 | openidConfigurationGetter: () => new OpenidConfigurationGetter(client.http),
21 | };
22 | };
23 |
24 | export default misc;
25 | export { default as LiveChecker } from './liveChecker.js';
26 | export { default as MetaGetter } from './metaGetter.js';
27 | export { default as OpenidConfigurationGetter } from './openidConfigurationGetter.js';
28 | export { default as ReadyChecker } from './readyChecker.js';
29 |
--------------------------------------------------------------------------------
/src/misc/journey.test.ts:
--------------------------------------------------------------------------------
1 | import weaviate from '../v2/index.js';
2 |
3 | describe('misc endpoints', () => {
4 | const client = weaviate.client({
5 | scheme: 'http',
6 | host: 'localhost:8080',
7 | });
8 |
9 | const authClient = weaviate.client({
10 | scheme: 'http',
11 | host: 'localhost:8085',
12 | });
13 |
14 | it('reports as live', () => {
15 | return client.misc
16 | .liveChecker()
17 | .do()
18 | .then((res: any) => expect(res).toEqual(true))
19 | .catch((e: any) => {
20 | throw new Error('it should not have errord: ' + e);
21 | });
22 | });
23 |
24 | it('reports as not live with a broken url', () => {
25 | const brokenClient = weaviate.client({
26 | scheme: 'http',
27 | host: 'localhost:12345', // note the incorrect port
28 | });
29 |
30 | return brokenClient.misc
31 | .liveChecker()
32 | .do()
33 | .then((res: any) => expect(res).toEqual(false))
34 | .catch((e: any) => {
35 | throw new Error('it should not have errord: ' + e);
36 | });
37 | });
38 |
39 | it('reports as ready', () => {
40 | return client.misc
41 | .readyChecker()
42 | .do()
43 | .then((res: any) => expect(res).toEqual(true))
44 | .catch((e: any) => {
45 | throw new Error('it should not have errord: ' + e);
46 | });
47 | });
48 |
49 | it('reports as not ready with a broken url', () => {
50 | const brokenClient = weaviate.client({
51 | scheme: 'http',
52 | host: 'localhost:12345', // note the incorrect port
53 | });
54 |
55 | return brokenClient.misc
56 | .readyChecker()
57 | .do()
58 | .then((res: any) => expect(res).toEqual(false))
59 | .catch((e: any) => {
60 | throw new Error('it should not have errord: ' + e);
61 | });
62 | });
63 |
64 | it('displays meta info', () => {
65 | return client.misc
66 | .metaGetter()
67 | .do()
68 | .then((res: any) => {
69 | expect(res.version).toBeDefined();
70 | expect(res.modules['text2vec-contextionary'].wordCount).toBeDefined();
71 | expect(res.modules['text2vec-contextionary'].wordCount).toBeGreaterThan(100);
72 | })
73 | .catch((e: any) => {
74 | throw new Error('it should not have errord: ' + e);
75 | });
76 | });
77 |
78 | it('shows oidc config as undefined when not set', () => {
79 | return client.misc
80 | .openidConfigurationGetter()
81 | .do()
82 | .then((res: any) => {
83 | expect(res).toBeUndefined();
84 | })
85 | .catch((e: any) => {
86 | throw new Error('it should not have errord: ' + e);
87 | });
88 | });
89 |
90 | it('shows oidc config when set', () => {
91 | return authClient.misc
92 | .openidConfigurationGetter()
93 | .do()
94 | .then((res: any) => {
95 | expect(res.clientId).toEqual('wcs');
96 | expect(res.href).toContain('.well-known/openid-configuration');
97 | expect(res.scopes).toEqual(['openid', 'email']);
98 | });
99 | });
100 | });
101 |
--------------------------------------------------------------------------------
/src/misc/liveChecker.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { DbVersionProvider } from '../utils/dbVersion.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class LiveChecker extends CommandBase {
6 | private dbVersionProvider: DbVersionProvider;
7 |
8 | constructor(client: Connection, dbVersionProvider: DbVersionProvider) {
9 | super(client);
10 | this.dbVersionProvider = dbVersionProvider;
11 | }
12 |
13 | validate() {
14 | // nothing to validate
15 | }
16 |
17 | do = () => {
18 | return this.client
19 | .get('/.well-known/live', false)
20 | .then(() => {
21 | setTimeout(() => this.dbVersionProvider.refresh());
22 | return Promise.resolve(true);
23 | })
24 | .catch(() => Promise.resolve(false));
25 | };
26 | }
27 |
--------------------------------------------------------------------------------
/src/misc/metaGetter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Meta } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class MetaGetter extends CommandBase {
6 | constructor(client: Connection) {
7 | super(client);
8 | }
9 |
10 | validate() {
11 | // nothing to validate
12 | }
13 |
14 | do = (): Promise => {
15 | return this.client.get('/meta', true);
16 | };
17 | }
18 |
--------------------------------------------------------------------------------
/src/misc/openidConfigurationGetter.ts:
--------------------------------------------------------------------------------
1 | import { HttpClient } from '../connection/http.js';
2 |
3 | export default class OpenidConfigurationGetterGetter {
4 | private client: HttpClient;
5 | constructor(client: HttpClient) {
6 | this.client = client;
7 | }
8 |
9 | do = () => {
10 | return this.client
11 | .getRaw('/.well-known/openid-configuration')
12 | .then((res: { status: number; json: () => any }) => {
13 | if (res.status < 400) {
14 | return res.json();
15 | }
16 |
17 | if (res.status == 404) {
18 | // OIDC is not configured
19 | return Promise.resolve(undefined);
20 | }
21 |
22 | return Promise.reject(new Error(`unexpected status code: ${res.status}`));
23 | });
24 | };
25 | }
26 |
--------------------------------------------------------------------------------
/src/misc/readyChecker.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { DbVersionProvider } from '../utils/dbVersion.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class ReadyChecker extends CommandBase {
6 | private dbVersionProvider: DbVersionProvider;
7 |
8 | constructor(client: Connection, dbVersionProvider: DbVersionProvider) {
9 | super(client);
10 | this.dbVersionProvider = dbVersionProvider;
11 | }
12 |
13 | validate() {
14 | // nothing to validate
15 | }
16 |
17 | do = () => {
18 | return this.client
19 | .get('/.well-known/ready', false)
20 | .then(() => {
21 | setTimeout(() => this.dbVersionProvider.refresh());
22 | return Promise.resolve(true);
23 | })
24 | .catch(() => Promise.resolve(false));
25 | };
26 | }
27 |
--------------------------------------------------------------------------------
/src/roles/types.ts:
--------------------------------------------------------------------------------
1 | import { Action, WeaviateUserType } from '../openapi/types.js';
2 |
3 | export type BackupsAction = Extract;
4 | export type ClusterAction = Extract;
5 | export type CollectionsAction = Extract<
6 | Action,
7 | | 'create_collections'
8 | | 'delete_collections'
9 | | 'read_collections'
10 | | 'update_collections'
11 | | 'manage_collections'
12 | >;
13 | export type DataAction = Extract<
14 | Action,
15 | 'create_data' | 'delete_data' | 'read_data' | 'update_data' | 'manage_data'
16 | >;
17 | export type NodesAction = Extract;
18 | export type RolesAction = Extract;
19 | export type TenantsAction = Extract<
20 | Action,
21 | 'create_tenants' | 'delete_tenants' | 'read_tenants' | 'update_tenants'
22 | >;
23 | export type UsersAction = Extract;
24 |
25 | export type UserAssignment = {
26 | id: string;
27 | userType: WeaviateUserType;
28 | };
29 |
30 | export type BackupsPermission = {
31 | collection: string;
32 | actions: BackupsAction[];
33 | };
34 |
35 | export type ClusterPermission = {
36 | actions: ClusterAction[];
37 | };
38 |
39 | export type CollectionsPermission = {
40 | collection: string;
41 | actions: CollectionsAction[];
42 | };
43 |
44 | export type DataPermission = {
45 | collection: string;
46 | tenant: string;
47 | actions: DataAction[];
48 | };
49 |
50 | export type NodesPermission = {
51 | collection: string;
52 | verbosity: 'verbose' | 'minimal';
53 | actions: NodesAction[];
54 | };
55 |
56 | export type RolesPermission = {
57 | role: string;
58 | actions: RolesAction[];
59 | };
60 |
61 | export type TenantsPermission = {
62 | collection: string;
63 | tenant: string;
64 | actions: TenantsAction[];
65 | };
66 |
67 | export type UsersPermission = {
68 | users: string;
69 | actions: UsersAction[];
70 | };
71 |
72 | export type Role = {
73 | name: string;
74 | backupsPermissions: BackupsPermission[];
75 | clusterPermissions: ClusterPermission[];
76 | collectionsPermissions: CollectionsPermission[];
77 | dataPermissions: DataPermission[];
78 | nodesPermissions: NodesPermission[];
79 | rolesPermissions: RolesPermission[];
80 | tenantsPermissions: TenantsPermission[];
81 | usersPermissions: UsersPermission[];
82 | };
83 |
84 | export type Permission =
85 | | BackupsPermission
86 | | ClusterPermission
87 | | CollectionsPermission
88 | | DataPermission
89 | | NodesPermission
90 | | RolesPermission
91 | | TenantsPermission
92 | | UsersPermission;
93 |
94 | export type PermissionsInput = Permission | Permission[] | Permission[][] | (Permission | Permission[])[];
95 |
--------------------------------------------------------------------------------
/src/schema/classCreator.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { WeaviateClass } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class ClassCreator extends CommandBase {
6 | private class!: WeaviateClass;
7 |
8 | constructor(client: Connection) {
9 | super(client);
10 | }
11 |
12 | withClass = (classObj: object) => {
13 | this.class = classObj;
14 | return this;
15 | };
16 |
17 | validateClass = () => {
18 | if (this.class == undefined || this.class == null) {
19 | this.addError('class object must be set - set with .withClass(class)');
20 | }
21 | };
22 |
23 | validate() {
24 | this.validateClass();
25 | }
26 |
27 | do = (): Promise => {
28 | this.validateClass();
29 | if (this.errors.length > 0) {
30 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
31 | }
32 | const path = `/schema`;
33 | return this.client.postReturn(path, this.class);
34 | };
35 | }
36 |
--------------------------------------------------------------------------------
/src/schema/classDeleter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { CommandBase } from '../validation/commandBase.js';
3 | import { isValidStringProperty } from '../validation/string.js';
4 |
5 | export default class ClassDeleter extends CommandBase {
6 | private className?: string;
7 |
8 | constructor(client: Connection) {
9 | super(client);
10 | }
11 |
12 | withClassName = (className: string) => {
13 | this.className = className;
14 | return this;
15 | };
16 |
17 | validateClassName = () => {
18 | if (!isValidStringProperty(this.className)) {
19 | this.addError('className must be set - set with .withClassName(className)');
20 | }
21 | };
22 |
23 | validate = () => {
24 | this.validateClassName();
25 | };
26 |
27 | do = (): Promise => {
28 | this.validate();
29 | if (this.errors.length > 0) {
30 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
31 | }
32 | const path = `/schema/${this.className}`;
33 | return this.client.delete(path, undefined, false);
34 | };
35 | }
36 |
--------------------------------------------------------------------------------
/src/schema/classExists.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { WeaviateSchema } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { isValidStringProperty } from '../validation/string.js';
5 |
6 | export default class ClassExists extends CommandBase {
7 | private className?: string;
8 |
9 | constructor(client: Connection) {
10 | super(client);
11 | }
12 |
13 | withClassName = (className: string) => {
14 | this.className = className;
15 | return this;
16 | };
17 |
18 | validateClassName = () => {
19 | if (!isValidStringProperty(this.className)) {
20 | this.addError('className must be set - set with .withClassName(className)');
21 | }
22 | };
23 |
24 | validate = () => {
25 | this.validateClassName();
26 | };
27 |
28 | do = (): Promise => {
29 | this.validate();
30 | if (this.errors.length > 0) {
31 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
32 | }
33 | const path = `/schema`;
34 | return this.client
35 | .get(path)
36 | .then((res) => (res.classes ? res.classes.some((c) => c.class === this.className) : false));
37 | };
38 | }
39 |
--------------------------------------------------------------------------------
/src/schema/classGetter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { WeaviateClass } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { isValidStringProperty } from '../validation/string.js';
5 |
6 | export default class ClassGetter extends CommandBase {
7 | private className?: string;
8 |
9 | constructor(client: Connection) {
10 | super(client);
11 | }
12 |
13 | withClassName = (className: string) => {
14 | this.className = className;
15 | return this;
16 | };
17 |
18 | validateClassName = () => {
19 | if (!isValidStringProperty(this.className)) {
20 | this.addError('className must be set - set with .withClassName(className)');
21 | }
22 | };
23 |
24 | validate = () => {
25 | this.validateClassName();
26 | };
27 |
28 | do = (): Promise => {
29 | this.validate();
30 | if (this.errors.length > 0) {
31 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
32 | }
33 | const path = `/schema/${this.className}`;
34 | return this.client.get(path);
35 | };
36 | }
37 |
--------------------------------------------------------------------------------
/src/schema/classUpdater.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { WeaviateClass } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class ClassUpdater extends CommandBase {
6 | private class!: WeaviateClass;
7 |
8 | constructor(client: Connection) {
9 | super(client);
10 | }
11 |
12 | withClass = (classObj: WeaviateClass) => {
13 | this.class = classObj;
14 | return this;
15 | };
16 |
17 | validateClass = () => {
18 | if (this.class == undefined || this.class == null) {
19 | this.addError('class object must be set - set with .withClass(class)');
20 | }
21 | };
22 |
23 | validate() {
24 | this.validateClass();
25 | }
26 |
27 | do = (): Promise => {
28 | this.validateClass();
29 | if (this.errors.length > 0) {
30 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
31 | }
32 | const path = `/schema/${this.class.class}`;
33 | return this.client.put(path, this.class, false);
34 | };
35 | }
36 |
--------------------------------------------------------------------------------
/src/schema/deleteAll.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import ClassDeleter from './classDeleter.js';
3 | import SchemaGetter from './getter.js';
4 |
5 | export default async (client: Connection) => {
6 | const getter = new SchemaGetter(client);
7 | const schema = await getter.do();
8 | await Promise.all(
9 | schema.classes
10 | ? schema.classes.map((c) => {
11 | const deleter = new ClassDeleter(client);
12 | return deleter.withClassName(c.class as string).do();
13 | })
14 | : []
15 | );
16 | };
17 |
--------------------------------------------------------------------------------
/src/schema/getter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { WeaviateSchema } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class SchemaGetter extends CommandBase {
6 | constructor(client: Connection) {
7 | super(client);
8 | }
9 |
10 | validate() {
11 | // nothing to validate
12 | }
13 |
14 | do = (): Promise => {
15 | if (this.errors.length > 0) {
16 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
17 | }
18 | const path = `/schema`;
19 | return this.client.get(path);
20 | };
21 | }
22 |
--------------------------------------------------------------------------------
/src/schema/propertyCreator.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Property } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { isValidStringProperty } from '../validation/string.js';
5 |
6 | export default class PropertyCreator extends CommandBase {
7 | private className!: string;
8 | private property!: Property;
9 |
10 | constructor(client: Connection) {
11 | super(client);
12 | }
13 |
14 | withClassName = (className: string) => {
15 | this.className = className;
16 | return this;
17 | };
18 |
19 | withProperty = (property: Property) => {
20 | this.property = property;
21 | return this;
22 | };
23 |
24 | validateClassName = () => {
25 | if (!isValidStringProperty(this.className)) {
26 | this.addError('className must be set - set with .withClassName(className)');
27 | }
28 | };
29 |
30 | validateProperty = () => {
31 | if (this.property == undefined || this.property == null) {
32 | this.addError('property must be set - set with .withProperty(property)');
33 | }
34 | };
35 |
36 | validate = () => {
37 | this.validateClassName();
38 | this.validateProperty();
39 | };
40 |
41 | do = (): Promise => {
42 | this.validate();
43 | if (this.errors.length > 0) {
44 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
45 | }
46 | const path = `/schema/${this.className}/properties`;
47 | return this.client.postReturn(path, this.property);
48 | };
49 | }
50 |
--------------------------------------------------------------------------------
/src/schema/shardUpdater.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { CommandBase } from '../validation/commandBase.js';
3 | import { isValidStringProperty } from '../validation/string.js';
4 |
5 | export default class ShardUpdater extends CommandBase {
6 | private className!: string;
7 | private shardName!: string;
8 | private status!: string;
9 |
10 | constructor(client: Connection) {
11 | super(client);
12 | }
13 |
14 | withClassName = (className: string) => {
15 | this.className = className;
16 | return this;
17 | };
18 |
19 | validateClassName = () => {
20 | if (!isValidStringProperty(this.className)) {
21 | this.addError('className must be set - set with .withClassName(className)');
22 | }
23 | };
24 |
25 | withShardName = (shardName: string) => {
26 | this.shardName = shardName;
27 | return this;
28 | };
29 |
30 | validateShardName = () => {
31 | if (!isValidStringProperty(this.shardName)) {
32 | this.addError('shardName must be set - set with .withShardName(shardName)');
33 | }
34 | };
35 |
36 | withStatus = (status: string) => {
37 | this.status = status;
38 | return this;
39 | };
40 |
41 | validateStatus = () => {
42 | if (!isValidStringProperty(this.status)) {
43 | this.addError('status must be set - set with .withStatus(status)');
44 | }
45 | };
46 |
47 | validate = () => {
48 | this.validateClassName();
49 | this.validateShardName();
50 | this.validateStatus();
51 | };
52 |
53 | do = () => {
54 | this.validate();
55 | if (this.errors.length > 0) {
56 | return Promise.reject(new Error(`invalid usage: ${this.errors.join(', ')}`));
57 | }
58 |
59 | return updateShard(this.client, this.className, this.shardName, this.status);
60 | };
61 | }
62 |
63 | export function updateShard(client: Connection, className: string, shardName: string, status: string) {
64 | const path = `/schema/${className}/shards/${shardName}`;
65 | return client.put(path, { status: status }, true);
66 | }
67 |
--------------------------------------------------------------------------------
/src/schema/shardsGetter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { ShardStatusList } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { isValidStringProperty } from '../validation/string.js';
5 |
6 | export default class ShardsGetter extends CommandBase {
7 | private className?: string;
8 | private tenant?: string;
9 |
10 | constructor(client: Connection) {
11 | super(client);
12 | }
13 |
14 | withClassName = (className: string) => {
15 | this.className = className;
16 | return this;
17 | };
18 |
19 | withTenant = (tenant: string) => {
20 | this.tenant = tenant;
21 | return this;
22 | };
23 |
24 | validateClassName = () => {
25 | if (!isValidStringProperty(this.className)) {
26 | this.addError('className must be set - set with .withClassName(className)');
27 | }
28 | };
29 |
30 | validate = () => {
31 | this.validateClassName();
32 | };
33 |
34 | do = (): Promise => {
35 | this.validate();
36 | if (this.errors.length > 0) {
37 | return Promise.reject(new Error(`invalid usage: ${this.errors.join(', ')}`));
38 | }
39 |
40 | return getShards(this.client, this.className, this.tenant);
41 | };
42 | }
43 |
44 | export function getShards(client: Connection, className: any, tenant?: string) {
45 | const path = `/schema/${className}/shards${tenant ? `?tenant=${tenant}` : ''}`;
46 | return client.get(path);
47 | }
48 |
--------------------------------------------------------------------------------
/src/schema/shardsUpdater.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { ShardStatusList } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { isValidStringProperty } from '../validation/string.js';
5 | import { updateShard } from './shardUpdater.js';
6 | import { getShards } from './shardsGetter.js';
7 |
8 | export default class ShardsUpdater extends CommandBase {
9 | private className!: string;
10 | private shards: ShardStatusList;
11 | private status!: string;
12 |
13 | constructor(client: Connection) {
14 | super(client);
15 | this.shards = [];
16 | }
17 |
18 | withClassName = (className: string) => {
19 | this.className = className;
20 | return this;
21 | };
22 |
23 | validateClassName = () => {
24 | if (!isValidStringProperty(this.className)) {
25 | this.addError('className must be set - set with .withClassName(className)');
26 | }
27 | };
28 |
29 | withStatus = (status: string) => {
30 | this.status = status;
31 | return this;
32 | };
33 |
34 | validateStatus = () => {
35 | if (!isValidStringProperty(this.status)) {
36 | this.addError('status must be set - set with .withStatus(status)');
37 | }
38 | };
39 |
40 | validate = () => {
41 | this.validateClassName();
42 | this.validateStatus();
43 | };
44 |
45 | updateShards = async () => {
46 | const payload: any = await Promise.all(
47 | Array.from({ length: this.shards.length }, (_, i) =>
48 | updateShard(this.client, this.className, this.shards[i].name || '', this.status)
49 | .then((res: any) => {
50 | return { name: this.shards[i].name, status: res.status };
51 | })
52 | .catch((err: any) => this.addError(err.toString()))
53 | )
54 | );
55 |
56 | if (this.errors.length > 0) {
57 | return Promise.reject(new Error(`failed to update shards: ${this.errors.join(', ')}`));
58 | }
59 |
60 | return Promise.resolve(payload);
61 | };
62 |
63 | do = (): Promise => {
64 | this.validate();
65 | if (this.errors.length > 0) {
66 | return Promise.reject(new Error(`invalid usage: ${this.errors.join(', ')}`));
67 | }
68 |
69 | return getShards(this.client, this.className)
70 | .then((shards: ShardStatusList) => (this.shards = shards))
71 | .then(() => {
72 | return this.updateShards();
73 | })
74 | .then((payload: ShardStatusList) => {
75 | return payload;
76 | })
77 | .catch((err: any) => {
78 | return Promise.reject(err);
79 | });
80 | };
81 | }
82 |
--------------------------------------------------------------------------------
/src/schema/tenantsCreator.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Tenant } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class TenantsCreator extends CommandBase {
6 | private className: string;
7 | private tenants: Array;
8 |
9 | constructor(client: Connection, className: string, tenants: Array) {
10 | super(client);
11 | this.className = className;
12 | this.tenants = tenants;
13 | }
14 |
15 | validate = () => {
16 | // nothing to validate
17 | };
18 |
19 | do = (): Promise> => {
20 | return this.client.postReturn(`/schema/${this.className}/tenants`, this.tenants);
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/src/schema/tenantsDeleter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { CommandBase } from '../validation/commandBase.js';
3 |
4 | export default class TenantsDeleter extends CommandBase {
5 | private className: string;
6 | private tenants: Array;
7 |
8 | constructor(client: Connection, className: string, tenants: Array) {
9 | super(client);
10 | this.className = className;
11 | this.tenants = tenants;
12 | }
13 |
14 | validate = () => {
15 | // nothing to validate
16 | };
17 |
18 | do = (): Promise => {
19 | return this.client.delete(`/schema/${this.className}/tenants`, this.tenants, false);
20 | };
21 | }
22 |
--------------------------------------------------------------------------------
/src/schema/tenantsExists.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { CommandBase } from '../validation/commandBase.js';
3 |
4 | export default class TenantsExists extends CommandBase {
5 | private className: string;
6 | private tenant: string;
7 |
8 | constructor(client: Connection, className: string, tenant: string) {
9 | super(client);
10 | this.className = className;
11 | this.tenant = tenant;
12 | }
13 |
14 | validate = () => {
15 | // nothing to validate
16 | };
17 |
18 | do = (): Promise => {
19 | return this.client.head(`/schema/${this.className}/tenants/${this.tenant}`, undefined);
20 | };
21 | }
22 |
--------------------------------------------------------------------------------
/src/schema/tenantsGetter.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Tenant } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class TenantsGetter extends CommandBase {
6 | private className: string;
7 |
8 | constructor(client: Connection, className: string) {
9 | super(client);
10 | this.className = className;
11 | }
12 |
13 | validate = () => {
14 | // nothing to validate
15 | };
16 |
17 | do = (): Promise> => {
18 | return this.client.get(`/schema/${this.className}/tenants`);
19 | };
20 | }
21 |
--------------------------------------------------------------------------------
/src/schema/tenantsUpdater.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { Tenant } from '../openapi/types.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 |
5 | export default class TenantsUpdater extends CommandBase {
6 | private className: string;
7 | private tenants: Array;
8 |
9 | constructor(client: Connection, className: string, tenants: Array) {
10 | super(client);
11 | this.className = className;
12 | this.tenants = tenants;
13 | }
14 |
15 | validate = () => {
16 | // nothing to validate
17 | };
18 |
19 | do = (): Promise> => {
20 | return this.client.put(`/schema/${this.className}/tenants`, this.tenants);
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/src/schema/vectorAdder.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 | import { VectorConfig } from '../index.js';
3 | import { CommandBase } from '../validation/commandBase.js';
4 | import { isValidStringProperty } from '../validation/string.js';
5 | import ClassGetter from './classGetter.js';
6 |
7 | export default class VectorAdder extends CommandBase {
8 | private className!: string;
9 | private vectors!: Record;
10 |
11 | constructor(client: Connection) {
12 | super(client);
13 | }
14 |
15 | withClassName = (className: string) => {
16 | this.className = className;
17 | return this;
18 | };
19 | withVectors = (vectors: Record) => {
20 | this.vectors = vectors;
21 | return this;
22 | };
23 |
24 | validateClassName = () => {
25 | if (!isValidStringProperty(this.className)) {
26 | this.addError('className must be set - set with .withClassName(className)');
27 | }
28 | };
29 |
30 | validate = () => {
31 | this.validateClassName();
32 | };
33 |
34 | do = (): Promise => {
35 | this.validate();
36 | if (this.errors.length > 0) {
37 | return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
38 | }
39 |
40 | return new ClassGetter(this.client)
41 | .withClassName(this.className)
42 | .do()
43 | .then(async (schema) => {
44 | if (schema.vectorConfig === undefined) {
45 | schema.vectorConfig = {};
46 | }
47 |
48 | for (const [key, value] of Object.entries(this.vectors)) {
49 | if (schema.vectorConfig[key] !== undefined) {
50 | continue;
51 | }
52 | schema.vectorConfig![key] = { ...value };
53 | }
54 |
55 | const path = `/schema/${this.className}`;
56 | await this.client.put(path, schema);
57 | });
58 | };
59 | }
60 |
--------------------------------------------------------------------------------
/src/users/types.ts:
--------------------------------------------------------------------------------
1 | import { WeaviateUserTypeDB as UserTypeDB, WeaviateUserTypeInternal } from '../openapi/types.js';
2 | import { Role } from '../roles/types.js';
3 |
4 | export type User = {
5 | id: string;
6 | roles?: Role[];
7 | };
8 |
9 | export type UserDB = {
10 | userType: UserTypeDB;
11 | id: string;
12 | roleNames: string[];
13 | active: boolean;
14 |
15 | createdAt?: Date;
16 | lastUsedAt?: Date;
17 | apiKeyFirstLetters?: string;
18 | };
19 |
20 | /** Optional arguments to /user/{type}/{username} enpoint. */
21 | export type GetAssignedRolesOptions = {
22 | includePermissions?: boolean;
23 | };
24 |
25 | /** Optional arguments to /assign and /revoke endpoints. */
26 | export type AssignRevokeOptions = { userType?: WeaviateUserTypeInternal };
27 |
28 | /** Optional arguments to /deactivate endpoint. */
29 | export type DeactivateOptions = { revokeKey?: boolean };
30 |
31 | /** Optional arguments to /users and /users/ endpoints. */
32 | export type GetUserOptions = { includeLastUsedTime?: boolean };
33 |
--------------------------------------------------------------------------------
/src/utils/base64.test.ts:
--------------------------------------------------------------------------------
1 | import { httpClient } from '../connection/http.js';
2 | import { downloadImageFromURLAsBase64 } from './base64.js';
3 |
4 | jest.mock('../connection/http.js');
5 |
6 | describe('downloadImageFromURLAsBase64()', () => {
7 | const mockHttpClient = {
8 | externalGet: jest.fn(),
9 | };
10 |
11 | beforeEach(() => {
12 | jest.clearAllMocks();
13 | (httpClient as jest.Mock).mockReturnValue(mockHttpClient);
14 | });
15 |
16 | it('should convert a downloaded image to base64', async () => {
17 | const mockUrl = 'https://example.com/image.jpg';
18 | const mockImageData = Buffer.from('image binary data');
19 |
20 | mockHttpClient.externalGet.mockResolvedValue(mockImageData);
21 |
22 | const result = await downloadImageFromURLAsBase64(mockUrl);
23 |
24 | expect(result).toBe(mockImageData.toString('base64'));
25 | expect(httpClient).toHaveBeenCalledWith({ headers: { 'Content-Type': 'image/*' }, host: '' });
26 | expect(mockHttpClient.externalGet).toHaveBeenCalledWith(mockUrl);
27 | });
28 |
29 | it('should throw an error if the URL is invalid', async () => {
30 | const invalidUrl = 'invalid-url';
31 |
32 | await expect(downloadImageFromURLAsBase64(invalidUrl)).rejects.toThrow('Invalid URL');
33 | });
34 |
35 | it('should throw an error if the image download fails', async () => {
36 | const mockUrl = 'https://example.com/image.jpg';
37 |
38 | mockHttpClient.externalGet.mockRejectedValue(new Error('Network error'));
39 |
40 | await expect(downloadImageFromURLAsBase64(mockUrl)).rejects.toThrow('Failed to download image from URL');
41 | expect(httpClient).toHaveBeenCalledWith({ headers: { 'Content-Type': 'image/*' }, host: '' });
42 | expect(mockHttpClient.externalGet).toHaveBeenCalledWith(mockUrl);
43 | });
44 |
45 | it('should handle empty response data gracefully', async () => {
46 | const mockUrl = 'https://example.com/image.jpg';
47 |
48 | mockHttpClient.externalGet.mockResolvedValue(Buffer.alloc(0));
49 |
50 | const result = await downloadImageFromURLAsBase64(mockUrl);
51 |
52 | expect(result).toBe('');
53 | expect(httpClient).toHaveBeenCalledWith({ headers: { 'Content-Type': 'image/*' }, host: '' });
54 | expect(mockHttpClient.externalGet).toHaveBeenCalledWith(mockUrl);
55 | });
56 |
57 | it('should throw an error if the response is not a buffer', async () => {
58 | const mockUrl = 'wrong-url.com';
59 |
60 | mockHttpClient.externalGet.mockResolvedValue('not a buffer');
61 |
62 | await expect(downloadImageFromURLAsBase64(mockUrl)).rejects.toThrow('Invalid URL');
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/src/utils/base64.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import { httpClient } from '../connection/http.js';
3 |
4 | const isFilePromise = (file: string | Buffer): Promise =>
5 | new Promise((resolve, reject) => {
6 | if (file instanceof Buffer) {
7 | resolve(false);
8 | }
9 | fs.stat(file, (err, stats) => {
10 | if (err) {
11 | if (err.code == 'ENAMETOOLONG') {
12 | resolve(false);
13 | return;
14 | }
15 | reject(err);
16 | return;
17 | }
18 | if (stats === undefined) {
19 | resolve(false);
20 | return;
21 | }
22 | resolve(stats.isFile());
23 | });
24 | });
25 |
26 | const isUrl = (file: string): file is string => {
27 | if (typeof file !== 'string') return false;
28 | try {
29 | const url = new URL(file);
30 | return !!url;
31 | } catch {
32 | return false;
33 | }
34 | };
35 |
36 | export const downloadImageFromURLAsBase64 = async (url: string): Promise => {
37 | if (!isUrl(url)) {
38 | throw new Error('Invalid URL');
39 | }
40 |
41 | try {
42 | const client = httpClient({
43 | headers: { 'Content-Type': 'image/*' },
44 | host: '',
45 | });
46 |
47 | const response = await client.externalGet(url);
48 |
49 | if (!Buffer.isBuffer(response)) {
50 | throw new Error('Response is not a buffer');
51 | }
52 |
53 | return response.toString('base64');
54 | } catch (error) {
55 | throw new Error(`Failed to download image from URL: ${url}`);
56 | }
57 | };
58 |
59 | const isBuffer = (file: string | Buffer): file is Buffer => file instanceof Buffer;
60 |
61 | const fileToBase64 = (file: string | Buffer): Promise =>
62 | isFilePromise(file).then((isFile) =>
63 | isFile
64 | ? new Promise((resolve, reject) => {
65 | fs.readFile(file, (err, data) => {
66 | if (err) {
67 | reject(err);
68 | }
69 | resolve(data.toString('base64'));
70 | });
71 | })
72 | : isBuffer(file)
73 | ? Promise.resolve(file.toString('base64'))
74 | : isUrl(file)
75 | ? downloadImageFromURLAsBase64(file)
76 | : Promise.resolve(file)
77 | );
78 |
79 | /**
80 | * This function converts a file buffer into a base64 string so that it can be
81 | * sent to Weaviate and stored as a media field.
82 | *
83 | * @param {string | Buffer} file The media to convert either as a base64 string, a file path string, an url, or as a buffer. If you passed a base64 string, the function does nothing and returns the string as is.
84 | * @returns {string} The base64 string
85 | */
86 | export const toBase64FromMedia = (media: string | Buffer): Promise => fileToBase64(media);
87 |
--------------------------------------------------------------------------------
/src/utils/beaconPath.ts:
--------------------------------------------------------------------------------
1 | import { isValidStringProperty } from '../validation/string.js';
2 | import { isValidWeaviateVersion } from '../validation/version.js';
3 | import { DbVersionSupport } from './dbVersion.js';
4 |
5 | const beaconPathPrefix = 'weaviate://localhost';
6 |
7 | export class BeaconPath {
8 | private dbVersionSupport: DbVersionSupport;
9 | private beaconRegExp: RegExp;
10 |
11 | constructor(dbVersionSupport: DbVersionSupport) {
12 | this.dbVersionSupport = dbVersionSupport;
13 | // matches
14 | // weaviate://localhost/class/id => match[2] = class, match[4] = id
15 | // weaviate://localhost/class/id/ => match[2] = class, match[4] = id
16 | // weaviate://localhost/id => match[2] = id, match[4] = undefined
17 | // weaviate://localhost/id/ => match[2] = id, match[4] = undefined
18 | this.beaconRegExp = /^weaviate:\/\/localhost(\/([^\\/]+))?(\/([^\\/]+))?[\\/]?$/gi;
19 | }
20 |
21 | async rebuild(beacon: string) {
22 | const support = await this.dbVersionSupport.supportsClassNameNamespacedEndpointsPromise();
23 | const match = new RegExp(this.beaconRegExp).exec(beacon);
24 | if (!match) {
25 | return beacon;
26 | }
27 | let className;
28 | let id;
29 | if (match[4] !== undefined) {
30 | id = match[4];
31 | className = match[2];
32 | } else {
33 | id = match[2];
34 | }
35 | let beaconPath = beaconPathPrefix;
36 | if (support.supports) {
37 | if (isValidStringProperty(className)) {
38 | beaconPath = `${beaconPath}/${className}`;
39 | } else {
40 | support.warns.deprecatedNonClassNameNamespacedEndpointsForBeacons();
41 | }
42 | } else {
43 | support.warns.notSupportedClassNamespacedEndpointsForBeacons();
44 | }
45 | if (support.version) {
46 | if (!isValidWeaviateVersion(support.version)) {
47 | support.warns.deprecatedWeaviateTooOld();
48 | }
49 | }
50 | if (isValidStringProperty(id)) {
51 | beaconPath = `${beaconPath}/${id}`;
52 | }
53 | return beaconPath;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/utils/uuid.ts:
--------------------------------------------------------------------------------
1 | import { v5 as uuid5 } from 'uuid';
2 |
3 | // Generates UUIDv5, used to consistently generate the same UUID for
4 | // a specific identifier and namespace
5 | export function generateUuid5(identifier: string | number, namespace: string | number = ''): string {
6 | const stringified = identifier.toString() + namespace.toString();
7 | return uuid5(stringified, uuid5.DNS).toString();
8 | }
9 |
--------------------------------------------------------------------------------
/src/validation/commandBase.ts:
--------------------------------------------------------------------------------
1 | import Connection from '../connection/index.js';
2 |
3 | export interface ICommandBase {
4 | /**
5 | * The client's connection
6 | */
7 | client: Connection;
8 | /**
9 | * An array of validation errors
10 | */
11 | errors: string[];
12 | /**
13 | * Execute the command
14 | */
15 | do: () => Promise;
16 | /**
17 | * Optional method to build the payload of an actual call
18 | */
19 | payload?: () => any;
20 | /**
21 | * validate that all the required parameters were feed to the builder
22 | */
23 | validate: () => void;
24 | }
25 |
26 | export abstract class CommandBase implements ICommandBase {
27 | private _errors: string[];
28 | public readonly client: Connection;
29 |
30 | protected constructor(client: Connection) {
31 | this.client = client;
32 | this._errors = [];
33 | }
34 |
35 | public get errors(): string[] {
36 | return this._errors;
37 | }
38 |
39 | addError(error: string) {
40 | this._errors = [...this.errors, error];
41 | }
42 |
43 | addErrors(errors: string[]) {
44 | this._errors = [...this.errors, ...errors];
45 | }
46 |
47 | abstract do(): Promise;
48 |
49 | abstract validate(): void;
50 | }
51 |
--------------------------------------------------------------------------------
/src/validation/number.ts:
--------------------------------------------------------------------------------
1 | export function isValidIntProperty(input: any) {
2 | return Number.isInteger(input);
3 | }
4 |
5 | export function isValidPositiveIntProperty(input: any) {
6 | return isValidIntProperty(input) && input >= 0;
7 | }
8 |
9 | export function isValidNumber(input: any) {
10 | return typeof input == 'number';
11 | }
12 |
13 | export function isValidNumberArray(input: any) {
14 | if (Array.isArray(input)) {
15 | for (const i in input) {
16 | if (!isValidNumber(input[i])) {
17 | return false;
18 | }
19 | }
20 | return true;
21 | }
22 | return false;
23 | }
24 |
--------------------------------------------------------------------------------
/src/validation/string.ts:
--------------------------------------------------------------------------------
1 | export function isValidStringProperty(input: any) {
2 | return typeof input == 'string' && input.length > 0;
3 | }
4 |
5 | export function isValidStringArray(input: any) {
6 | if (Array.isArray(input)) {
7 | for (const i in input) {
8 | if (!isValidStringProperty(input[i])) {
9 | return false;
10 | }
11 | }
12 | return true;
13 | }
14 | return false;
15 | }
16 |
--------------------------------------------------------------------------------
/src/validation/version.ts:
--------------------------------------------------------------------------------
1 | export function isValidWeaviateVersion(version: string) {
2 | if (typeof version === 'string') {
3 | const versionNumbers = version.split('.');
4 | if (versionNumbers.length >= 2) {
5 | const major = parseInt(versionNumbers[0], 10);
6 | const minor = parseInt(versionNumbers[1], 10);
7 | return !(major <= 1 && minor < 16);
8 | }
9 | }
10 | return true;
11 | }
12 |
--------------------------------------------------------------------------------
/test/dbVersionProvider.ts:
--------------------------------------------------------------------------------
1 | import { DbVersion, VersionProvider } from '../src/utils/dbVersion.js';
2 |
3 | export class TestDbVersionProvider implements VersionProvider {
4 | private version: string;
5 |
6 | constructor(version: string) {
7 | this.version = version;
8 | }
9 |
10 | getVersionString(): Promise {
11 | return Promise.resolve(this.version);
12 | }
13 |
14 | getVersion(): Promise {
15 | return Promise.resolve(DbVersion.fromString(this.version));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/server.ts:
--------------------------------------------------------------------------------
1 | import bodyParser from '@curveball/bodyparser';
2 | import { Application } from '@curveball/core';
3 | import { IncomingMessage, Server, ServerResponse } from 'http';
4 |
5 | export interface IServerCache {
6 | server: Server;
7 | app: Application;
8 | lastRequest: () => any;
9 | port: number;
10 | url: string;
11 | close: () => Promise;
12 | }
13 |
14 | const port = 40101;
15 | let serverCache: IServerCache | null = null;
16 |
17 | export function testServer() {
18 | if (serverCache) {
19 | return serverCache;
20 | }
21 |
22 | let lastRequest: any = null;
23 | const app = new Application();
24 |
25 | app.use((bodyParser as any)());
26 | app.use((ctx, next) => {
27 | lastRequest = ctx.request;
28 | return next();
29 | });
30 | app.use(getLocalOidcConfig, getRemoteOidcConfig, issueToken, mockGetEndpoint, mockGraphQLResponse);
31 | const server = app.listen(port);
32 |
33 | serverCache = {
34 | server,
35 | app,
36 | lastRequest: () => lastRequest,
37 | port,
38 | url: 'http://localhost:' + port,
39 | close: () => {
40 | return new Promise((res: any) => {
41 | server.close(() => res());
42 | });
43 | },
44 | };
45 |
46 | return serverCache;
47 | }
48 |
49 | const mockGetEndpoint = (ctx: any, next: any) => {
50 | if (ctx.path !== '/v1/testEndpoint') {
51 | return next();
52 | }
53 |
54 | ctx.response.status = 200;
55 | ctx.response.body = { message: 'test endpoint' };
56 | };
57 |
58 | const mockGraphQLResponse = (ctx: any, next: any) => {
59 | if (ctx.path !== '/v1/graphql') {
60 | return next();
61 | }
62 |
63 | ctx.response.status = 200;
64 | ctx.response.body = {
65 | data: {
66 | someField: 'someValue',
67 | },
68 | };
69 | };
70 |
71 | const getLocalOidcConfig = (ctx: any, next: any) => {
72 | if (ctx.path !== '/v1/.well-known/openid-configuration') {
73 | return next();
74 | }
75 |
76 | ctx.response.type = 'application/json';
77 | ctx.response.body = {
78 | clientId: 'client123',
79 | href: 'http://localhost:' + port + '/remote-openid-configuration',
80 | };
81 | };
82 |
83 | const getRemoteOidcConfig = (ctx: any, next: any) => {
84 | if (ctx.path !== '/remote-openid-configuration') {
85 | return next();
86 | }
87 |
88 | ctx.response.type = 'application/json';
89 | ctx.response.body = {
90 | token_endpoint: 'http://localhost:' + port + '/token',
91 | grant_types_supported: ['refresh_token', 'password'],
92 | };
93 | };
94 |
95 | const issueToken = (ctx: any, next: any) => {
96 | if (ctx.path !== '/token') {
97 | return next();
98 | }
99 |
100 | ctx.response.type = 'application/json';
101 | ctx.response.body = {
102 | access_token: 'access_token_000',
103 | refresh_token: 'refresh_token_000',
104 | expires_in: 3600,
105 | };
106 | };
107 |
--------------------------------------------------------------------------------
/test/version.ts:
--------------------------------------------------------------------------------
1 | import { DbVersion } from '../src/utils/dbVersion';
2 |
3 | const version = DbVersion.fromString(`v${process.env.WEAVIATE_VERSION!}`);
4 |
5 | /** Run the suite / test only for Weaviate version above this. */
6 | export const requireAtLeast = (...semver: [...Parameters]) =>
7 | version.isAtLeast(...semver) ? describe : describe.skip;
8 |
--------------------------------------------------------------------------------
/tools/health.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2015 The gRPC Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // The canonical version of this proto can be found at
16 | // https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto
17 |
18 | syntax = "proto3";
19 |
20 | package grpc.health.v1;
21 |
22 | option csharp_namespace = "Grpc.Health.V1";
23 | option go_package = "google.golang.org/grpc/health/grpc_health_v1";
24 | option java_multiple_files = true;
25 | option java_outer_classname = "HealthProto";
26 | option java_package = "io.grpc.health.v1";
27 |
28 | message HealthCheckRequest {
29 | string service = 1;
30 | }
31 |
32 | message HealthCheckResponse {
33 | enum ServingStatus {
34 | UNKNOWN = 0;
35 | SERVING = 1;
36 | NOT_SERVING = 2;
37 | SERVICE_UNKNOWN = 3; // Used only by the Watch method.
38 | }
39 | ServingStatus status = 1;
40 | }
41 |
42 | service Health {
43 | // If the requested service is unknown, the call will fail with status
44 | // NOT_FOUND.
45 | rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
46 |
47 | // Performs a watch for the serving status of the requested service.
48 | // The server will immediately send back a message indicating the current
49 | // serving status. It will then subsequently send a new message whenever
50 | // the service's serving status changes.
51 | //
52 | // If the requested service is unknown when the call is received, the
53 | // server will send a message setting the serving status to
54 | // SERVICE_UNKNOWN but will *not* terminate the call. If at some
55 | // future point, the serving status of the service becomes known, the
56 | // server will send a new message with the service's serving status.
57 | //
58 | // If the call terminates with status UNIMPLEMENTED, then clients
59 | // should assume this method is not supported and should not retry the
60 | // call. If the call terminates with any other status (including OK),
61 | // clients should retry the call with appropriate exponential backoff.
62 | rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
63 | }
--------------------------------------------------------------------------------
/tools/prepare_release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -euo pipefail
4 |
5 | VERSION=${1-}
6 | REQUIRED_TOOLS="jq git"
7 |
8 | if test -z "$VERSION"; then
9 | echo "Missing version parameter. Usage: $0 VERSION"
10 | exit 1
11 | fi
12 |
13 | if case $VERSION in v*) false;; esac; then
14 | VERSION="v$VERSION"
15 | fi
16 |
17 | for tool in $REQUIRED_TOOLS; do
18 | if ! hash "$tool" 2>/dev/null; then
19 | echo "This script requires '$tool', but it is not installed."
20 | exit 1
21 | fi
22 | done
23 |
24 | if git rev-parse "$VERSION" >/dev/null 2>&1; then
25 | echo "Cannot prepare release, a release for $VERSION already exists"
26 | exit 1
27 | fi
28 |
29 | npm version "${VERSION/v}"
30 |
--------------------------------------------------------------------------------
/tools/refresh_protos.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | branchOrTag="${1:-main}"
4 | dir="tools"
5 | mkdir -p ${dir}
6 | curl -LkSs https://api.github.com/repos/weaviate/weaviate/tarball/${branchOrTag} -o ${dir}/weaviate.tar.gz
7 | tar --strip-components=3 -C ${dir} -xvf ${dir}/weaviate.tar.gz $(tar -tf ${dir}/weaviate.tar.gz | grep '^weaviate-weaviate-[^/]\+/grpc/proto/v1')
8 |
9 | ./node_modules/.bin/grpc_tools_node_protoc -I ${dir} \
10 | --ts_proto_out=./src/proto \
11 | --ts_proto_opt=forceLong==bigint \
12 | --ts_proto_opt=esModuleInterop=true \
13 | --ts_proto_opt=outputServices=nice-grpc,outputServices=generic-definitions,useExactTypes=false \
14 | ${dir}/v1/*.proto
15 |
16 | ./node_modules/.bin/grpc_tools_node_protoc -I ${dir} \
17 | --ts_proto_out=./src/proto/google/health/v1 \
18 | --ts_proto_opt=forceLong==bigint \
19 | --ts_proto_opt=esModuleInterop=true \
20 | --ts_proto_opt=outputServices=nice-grpc,outputServices=generic-definitions,useExactTypes=false \
21 | ${dir}/health.proto
22 |
23 | rm ${dir}/weaviate.tar.gz
24 |
25 | sed -i '' 's/\"protobufjs\/minimal\"/\"protobufjs\/minimal.js\"/g' src/proto/v1/*.ts
26 | sed -i '' 's/\"protobufjs\/minimal\"/\"protobufjs\/minimal.js\"/g' src/proto/google/protobuf/struct.ts
27 | sed -i '' 's/\"protobufjs\/minimal\"/\"protobufjs\/minimal.js\"/g' src/proto/google/health/v1/health.ts
28 |
29 | sed -i '' 's/google\/protobuf\/struct"/google\/protobuf\/struct.js"/g' src/proto/v1/*.ts
30 |
31 | # replace import paths
32 | for filepath in ${dir}/v1/*; do # loops through known protos
33 | filename=${filepath##*/} # extract filename from path
34 | file=${filename%.*} # remove extension
35 | sed -i '' "s/\".\/${file}\"/\".\/${file}.js\"/g" src/proto/v1/*.ts # replace import paths
36 | # e.g. import { Vectors } from "./base"; => import { Vectors } from "./base.js";
37 | done
38 |
39 | rm -rf ${dir}/v1
40 |
41 | echo "done"
42 |
--------------------------------------------------------------------------------
/tools/refresh_schema.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -euo pipefail
4 |
5 | branchOrTag="${1:-main}"
6 | npx openapi-typescript https://raw.githubusercontent.com/weaviate/weaviate/${branchOrTag}/openapi-specs/schema.json -o ./src/openapi/schema.ts
7 | npx prettier --write --no-error-on-unmatched-pattern './src/openapi/schema.ts'
8 |
--------------------------------------------------------------------------------
/tsconfig-test.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES6",
4 | "strict": true,
5 | "noImplicitAny": true,
6 | "noImplicitThis": true,
7 | "strictFunctionTypes": true,
8 | "module": "NodeNext",
9 | "moduleResolution": "NodeNext",
10 | "forceConsistentCasingInFileNames": true,
11 | "allowSyntheticDefaultImports": true,
12 | "outDir": "./dist"
13 | },
14 | "include": ["./test/**/*.ts", "./src/**/*.ts"],
15 | "exclude": ["node_modules", "examples"]
16 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES6",
4 | "strict": true,
5 | "preserveConstEnums": true,
6 | "alwaysStrict": true,
7 | "noImplicitAny": true,
8 | "noImplicitThis": true,
9 | "strictFunctionTypes": true,
10 | "module": "NodeNext",
11 | "moduleResolution": "NodeNext",
12 | "skipLibCheck": true,
13 | "forceConsistentCasingInFileNames": true,
14 | "esModuleInterop": true,
15 | "outDir": "./dist/node",
16 | "declaration": true,
17 | "rootDir": "./src",
18 | "types": ["node", "uuid", "jest"]
19 | },
20 | "include": ["./src/**/*"],
21 | "exclude": ["**/*.test.ts"]
22 | }
23 |
--------------------------------------------------------------------------------
/tsup.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'tsup';
2 |
3 | export default defineConfig([
4 | {
5 | entry: [
6 | 'src/v2/index.ts',
7 | '!src/index.ts',
8 | '!src/**/*.test.ts',
9 | '!src/collections/**/*.ts',
10 | '!src/connection/grpc.ts',
11 | '!src/connection/helpers.ts',
12 | '!src/proto/**/*.ts',
13 | '!src/grpc',
14 | ],
15 | format: ['cjs', 'esm'],
16 | outDir: 'dist/web',
17 | clean: true,
18 | platform: 'browser',
19 | minify: true,
20 | dts: true,
21 | splitting: true,
22 | treeshake: true,
23 | },
24 | // {
25 | // entry: {
26 | // index: 'src/index.ts',
27 | // },
28 | // format: ['cjs'],
29 | // outDir: 'dist/node/cjs',
30 | // dts: true,
31 | // target: 'node16',
32 | // platform: 'node',
33 | // },
34 | ]);
35 |
--------------------------------------------------------------------------------