Compare commits

..

13 Commits

Author SHA1 Message Date
5b08121507 Clean up package.json canary side effect (#1964) 2023-07-25 17:13:53 -05:00
2a65740d62 [Backport 8.9] Changelog for 8.9.0 (#1962)
Co-authored-by: Josh Mock <joshua.mock@elastic.co>
2023-07-25 16:46:42 -05:00
ab764ae5c7 Codegen for 8.9 (#1956) 2023-07-25 13:02:04 -05:00
29dfffef9f [Backport 8.9] Add docs for bulk helper improvement (#1958)
Co-authored-by: Josh Mock <joshua.mock@elastic.co>
2023-07-25 11:40:39 -05:00
3ccd149249 [Backport 8.9] Update user agent format (#1959)
Co-authored-by: Josh Mock <joshua.mock@elastic.co>
2023-07-25 11:13:56 -05:00
e88999f144 [Backport 8.9] Allow document to be overwritten in onDocument iteratee of bulk helper (#1732)Co-authored-by: Josh Mock <joshua.mock@elastic.co> (#1953)
Co-authored-by: Robert Da Silva <mail@robdasilva.com>
2023-07-20 15:46:52 -05:00
485e57a375 [Backport 8.9] [DOCS] Restructures repo README (#1950)
Co-authored-by: István Zoltán Szabó <szabosteve@gmail.com>
2023-07-19 15:19:15 -05:00
b92146c708 [Backport 8.9] [DOCS] Changes getting started button link on landing page (#1935)
Co-authored-by: István Zoltán Szabó <szabosteve@gmail.com>
2023-07-05 13:51:25 -05:00
111d126d8c [DOCS] Adds getting started content based on the template (#1929) (#1931)
Co-authored-by: Josh Mock <joshua.mock@elastic.co>
Co-authored-by: István Zoltán Szabó <szabosteve@gmail.com>
2023-07-05 16:47:51 +02:00
135abcb850 Fix version in package.json 2023-06-28 16:07:06 -05:00
1641930396 Canary version bump 2023-06-23 16:46:20 -05:00
2b7d96e1e2 Canary version bump + missing file 2023-06-23 16:45:44 -05:00
642f8309e9 Update APIs to latest 8.9.0 2023-06-23 16:42:22 -05:00
3877 changed files with 49333 additions and 118942 deletions

View File

@ -3,14 +3,12 @@ FROM node:$NODE_VERSION
# Install required tools
RUN apt-get clean -y && \
apt-get -qy update && \
apt-get -y install zip && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
apt-get -qy update && \
apt-get -y install zip && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . .
RUN npm install --production=false

View File

@ -1,30 +0,0 @@
ARG NODE_JS_VERSION=${NODE_JS_VERSION:-18}
FROM node:${NODE_JS_VERSION}
ARG BUILDER_UID=1000
ARG BUILDER_GID=1000
ENV BUILDER_USER elastic
ENV BUILDER_GROUP elastic
# install zip util
RUN apt-get clean -y && \
apt-get update -y && \
apt-get install -y zip
# Set user permissions and directory
RUN (id -g ${BUILDER_GID} || groupadd --system -g ${BUILDER_GID} ${BUILDER_GROUP}) \
&& (id -u ${BUILDER_UID} || useradd --system --shell /bin/bash -u ${BUILDER_UID} -g ${BUILDER_GID} -m elastic) \
&& mkdir -p /usr/src/elasticsearch-js \
&& chown -R ${BUILDER_UID}:${BUILDER_GID} /usr/src/
WORKDIR /usr/src/elasticsearch-js
# run remainder of commands as non-root user
USER ${BUILDER_UID}:${BUILDER_GID}
# install dependencies
COPY package.json .
RUN npm install
# copy project files
COPY . .

View File

@ -2,7 +2,7 @@
#
# Shared cleanup routines between different steps
#
# Please source .buildkite/functions/imports.sh as a whole not just this file
# Please source .ci/functions/imports.sh as a whole not just this file
#
# Version 1.0.0
# - Initial version after refactor

View File

@ -2,7 +2,7 @@
#
# Exposes a routine scripts can call to wait for a container if that container set up a health command
#
# Please source .buildkite/functions/imports.sh as a whole not just this file
# Please source .ci/functions/imports.sh as a whole not just this file
#
# Version 1.0.1
# - Initial version after refactor

View File

@ -1,4 +1,3 @@
---
steps:
- label: ":elasticsearch: :javascript: ES JavaScript ({{ matrix.nodejs }}) Test Suite: {{ matrix.suite }}"
agents:
@ -6,16 +5,16 @@ steps:
env:
NODE_VERSION: "{{ matrix.nodejs }}"
TEST_SUITE: "{{ matrix.suite }}"
STACK_VERSION: 8.16.0
STACK_VERSION: 8.8.0-SNAPSHOT
matrix:
setup:
suite:
- "free"
- "platinum"
nodejs:
- "16"
- "18"
- "20"
- "22"
command: ./.buildkite/run-tests.sh
artifact_paths: "./junit-output/junit-*.xml"
- wait: ~
@ -25,8 +24,8 @@ steps:
provider: "gcp"
image: family/core-ubuntu-2204
plugins:
- junit-annotate#v2.6.0:
- junit-annotate#v2.4.1:
artifacts: "junit-output/junit-*.xml"
job-uuid-file-pattern: "junit-(.*).xml"
job-uuid-file-pattern: 'junit-(.*).xml'
fail-build-on-error: true
failure-format: file

View File

@ -9,6 +9,7 @@
"\\.md$",
"\\.asciidoc$",
"^docs\\/",
"^\\.ci\\/",
"^scripts\\/",
"^catalog-info\\.yaml$",
"^test\\/unit\\/",

15
.ci/Dockerfile Normal file
View File

@ -0,0 +1,15 @@
ARG NODE_JS_VERSION=18
FROM node:${NODE_JS_VERSION}
# Create app directory
WORKDIR /usr/src/app
RUN apt-get clean -y
RUN apt-get update -y
RUN apt-get install -y zip
# Install app dependencies
COPY package*.json ./
RUN npm install
COPY . .

View File

@ -1,6 +1,20 @@
/*
* Copyright Elasticsearch B.V. and contributors
* SPDX-License-Identifier: Apache-2.0
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* global $ argv */
@ -14,11 +28,6 @@ import assert from 'assert'
import { join } from 'desm'
import semver from 'semver'
// xz/globals loads minimist-parsed args as a global `argv`, but it
// interprets args like '8.10' as numbers and shortens them to '8.1'.
// so we have to import and configure minimist ourselves.
import minimist from 'minimist'
const argv = minimist(process.argv.slice(2), { string: ['_', 'task'] })
assert(typeof argv.task === 'string', 'Missing task parameter')
switch (argv.task) {
@ -60,15 +69,14 @@ async function release (args) {
async function bump (args) {
assert(args.length === 1, 'Bump task expects one parameter')
let [version] = args
const [version] = args
const packageJson = JSON.parse(await readFile(
join(import.meta.url, '..', 'package.json'),
'utf8'
))
if (version.split('.').length === 2) version = `${version}.0`
const cleanVersion = semver.clean(version.includes('SNAPSHOT') ? version.split('-')[0] : version)
assert(semver.valid(cleanVersion), `${cleanVersion} is not seen as a valid semver version. raw version: ${version}`)
assert(semver.valid(cleanVersion))
packageJson.version = cleanVersion
packageJson.versionCanary = `${cleanVersion}-canary.0`
@ -78,10 +86,10 @@ async function bump (args) {
'utf8'
)
const pipeline = await readFile(join(import.meta.url, '..', '.buildkite', 'pipeline.yml'), 'utf8')
const pipeline = await readFile(join(import.meta.url, '..', '.buildkite', 'pipeline.yml'))
await writeFile(
join(import.meta.url, '..', '.buildkite', 'pipeline.yml'),
pipeline.replace(/STACK_VERSION: [0-9]+[0-9\.]*[0-9](?:\-SNAPSHOT)?/, `STACK_VERSION: ${cleanVersion}`),
pipeline.replace(/STACK_VERSION: [0-9]+[0-9\.]*[0-9](?:\-SNAPSHOT)?/, `STACK_VERSION: ${cleanVersion}-SNAPSHOT`), // eslint-disable-line
'utf8'
)
}
@ -109,15 +117,8 @@ async function codegen (args) {
await $`rm -rf ${join(import.meta.url, '..', 'src', 'api')}`
await $`mkdir ${join(import.meta.url, '..', 'src', 'api')}`
await $`cp -R ${join(import.meta.url, '..', '..', 'elastic-client-generator-js', 'output')}/* ${join(import.meta.url, '..', 'src', 'api')}`
await $`mv ${join(import.meta.url, '..', 'src', 'api', 'reference.md')} ${join(import.meta.url, '..', 'docs', 'reference', 'api-reference.md')}`
await $`mv ${join(import.meta.url, '..', 'src', 'api', 'reference.asciidoc')} ${join(import.meta.url, '..', 'docs', 'reference.asciidoc')}`
await $`npm run build`
// run docs example generation
if (version === 'main') {
await $`node ./scripts/generate-docs-examples.js`
} else {
await $`node ./scripts/generate-docs-examples.js ${version.split('.').slice(0, 2).join('.')}`
}
}
function onError (err) {

187
.ci/make.sh Executable file
View File

@ -0,0 +1,187 @@
#!/usr/bin/env bash
# ------------------------------------------------------- #
#
# Build entry script for elasticsearch-js
#
# Must be called: ./.ci/make.sh <target> <params>
#
# Version: 1.1.0
#
# Targets:
# ---------------------------
# assemble <VERSION> : build client artifacts with version
# bump <VERSION> : bump client internals to version
# bumpmatrix <VERSION> : bump stack version in test matrix to version
# codegen : generate endpoints
# docsgen <VERSION> : generate documentation
# examplegen : generate the doc examples
# clean : clean workspace
#
# ------------------------------------------------------- #
# ------------------------------------------------------- #
# Bootstrap
# ------------------------------------------------------- #
script_path=$(dirname "$(realpath -s "$0")")
repo=$(realpath "$script_path/../")
generator=$(realpath "$script_path/../../elastic-client-generator-js")
# shellcheck disable=SC1090
CMD=$1
TASK=$1
TASK_ARGS=()
VERSION=$2
STACK_VERSION=$VERSION
set -euo pipefail
product="elastic/elasticsearch-js"
output_folder=".ci/output"
codegen_folder=".ci/output"
OUTPUT_DIR="$repo/${output_folder}"
# REPO_BINDING="${OUTPUT_DIR}:/sln/${output_folder}"
NODE_JS_VERSION=18
WORKFLOW=${WORKFLOW-staging}
mkdir -p "$OUTPUT_DIR"
echo -e "\033[34;1mINFO:\033[0m PRODUCT ${product}\033[0m"
echo -e "\033[34;1mINFO:\033[0m VERSION ${STACK_VERSION}\033[0m"
echo -e "\033[34;1mINFO:\033[0m OUTPUT_DIR ${OUTPUT_DIR}\033[0m"
case $CMD in
clean)
echo -e "\033[36;1mTARGET: clean workspace $output_folder\033[0m"
rm -rf "$output_folder"
echo -e "\033[32;1mdone.\033[0m"
exit 0
;;
assemble)
if [ -v $VERSION ]; then
echo -e "\033[31;1mTARGET: assemble -> missing version parameter\033[0m"
exit 1
fi
echo -e "\033[36;1mTARGET: assemble artefact $VERSION\033[0m"
TASK=release
TASK_ARGS=("$VERSION" "$output_folder")
;;
codegen)
if [ -v $VERSION ]; then
echo -e "\033[31;1mTARGET: codegen -> missing version parameter\033[0m"
exit 1
fi
echo -e "\033[36;1mTARGET: codegen API v$VERSION\033[0m"
TASK=codegen
# VERSION is BRANCH here for now
TASK_ARGS=("$VERSION")
;;
docsgen)
if [ -v $VERSION ]; then
echo -e "\033[31;1mTARGET: docsgen -> missing version parameter\033[0m"
exit 1
fi
echo -e "\033[36;1mTARGET: generate docs for $VERSION\033[0m"
TASK=codegen
# VERSION is BRANCH here for now
TASK_ARGS=("$VERSION" "$codegen_folder")
;;
examplesgen)
echo -e "\033[36;1mTARGET: generate examples\033[0m"
TASK=codegen
# VERSION is BRANCH here for now
TASK_ARGS=("$VERSION" "$codegen_folder")
;;
bump)
if [ -v $VERSION ]; then
echo -e "\033[31;1mTARGET: bump -> missing version parameter\033[0m"
exit 1
fi
echo -e "\033[36;1mTARGET: bump to version $VERSION\033[0m"
TASK=bump
# VERSION is BRANCH here for now
TASK_ARGS=("$VERSION")
;;
bumpmatrix)
if [ -v $VERSION ]; then
echo -e "\033[31;1mTARGET: bumpmatrix -> missing version parameter\033[0m"
exit 1
fi
echo -e "\033[36;1mTARGET: bump stack in test matrix to version $VERSION\033[0m"
TASK=bumpmatrix
TASK_ARGS=("$VERSION")
;;
*)
echo -e "\n'$CMD' is not supported right now\n"
echo -e "\nUsage:"
echo -e "\t $0 release \$VERSION\n"
echo -e "\t $0 bump \$VERSION"
echo -e "\t $0 codegen \$VERSION"
exit 1
esac
# ------------------------------------------------------- #
# Build Container
# ------------------------------------------------------- #
echo -e "\033[34;1mINFO: building $product container\033[0m"
docker build \
--file .ci/Dockerfile \
--tag "$product" \
--build-arg NODE_JS_VERSION="$NODE_JS_VERSION" \
.
# ------------------------------------------------------- #
# Run the Container
# ------------------------------------------------------- #
echo -e "\033[34;1mINFO: running $product container\033[0m"
docker run \
--volume "$repo:/usr/src/app" \
--volume "$generator:/usr/src/elastic-client-generator-js" \
--volume /usr/src/app/node_modules \
-u "$(id -u):$(id -g)" \
--env "WORKFLOW=$WORKFLOW" \
--name make-elasticsearch-js \
--rm \
$product \
node .ci/make.mjs --task $TASK ${TASK_ARGS[*]}
# ------------------------------------------------------- #
# Post Command tasks & checks
# ------------------------------------------------------- #
if [[ "$CMD" == "assemble" ]]; then
if compgen -G ".ci/output/*" > /dev/null; then
echo -e "\033[32;1mTARGET: successfully assembled client v$VERSION\033[0m"
else
echo -e "\033[31;1mTARGET: assemble failed, empty workspace!\033[0m"
exit 1
fi
fi
if [[ "$CMD" == "bump" ]]; then
if [ -n "$(git status --porcelain)" ]; then
echo -e "\033[32;1mTARGET: successfully bumped client v$VERSION\033[0m"
else
echo -e "\033[31;1mTARGET: failed bumped client v$VERSION\033[0m"
exit 1
fi
fi
if [[ "$CMD" == "codegen" ]]; then
if [ -n "$(git status --porcelain)" ]; then
echo -e "\033[32;1mTARGET: successfully generated client v$VERSION\033[0m"
else
echo -e "\033[31;1mTARGET: failed generating client v$VERSION\033[0m"
exit 1
fi
fi
if [[ "$CMD" == "docsgen" ]]; then
echo "TODO"
fi
if [[ "$CMD" == "examplesgen" ]]; then
echo "TODO"
fi

View File

@ -3,6 +3,3 @@ npm-debug.log
test/benchmarks
elasticsearch
.git
lib
junit-output
.tap

49
.github/ISSUE_TEMPLATE/bug.md vendored Normal file
View File

@ -0,0 +1,49 @@
---
name: 🐛 Bug report
about: Create a report to help us improve
---
It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/elasticsearch-js/issues) at first before submitting a new one.
**Please read this entire template before posting any issue. If you ignore these instructions
and post an issue here that does not follow the instructions, your issue might be closed,
locked, and assigned the `not reproducible` label.**
## 🐛 Bug Report
A clear and concise description of what the bug is.
## To Reproduce
Steps to reproduce the behavior:
Paste your code here:
```js
```
<!--
In some cases, it might be challenging to reproduce the bug in a few lines of code.
You can fork the following repository, which contains all the configuration needed
to spin up a three nodes Elasticsearch cluster with security enabled.
The repository also contains a preconfigured client instance that you can use to reproduce the issue.
https://github.com/delvedor/es-reproduce-issue
--->
## Expected behavior
A clear and concise description of what you expected to happen.
Paste the results here:
```js
```
## Your Environment
- *node version*: 6,8,10
- `@elastic/elasticsearch` *version*: >=7.0.0
- *os*: Mac, Windows, Linux
- *any other relevant information*

View File

@ -1,66 +0,0 @@
---
name: 🐛 Bug report
description: Create a report to help us improve
labels: ["Category: Bug"]
body:
- type: markdown
attributes:
value: |
It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/elasticsearch-js/issues) at first before submitting a new one.
**Please read this entire template before posting any issue. If you ignore these instructions
and post an issue here that does not follow the instructions, your issue might be closed,
locked, and assigned the `Category: Not an issue` label.**
- type: textarea
id: bug-report
attributes:
label: 🐛 Bug report
description: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: To reproduce
description: Steps to reproduce the behavior
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
validations:
required: true
- type: input
id: node-js-version
attributes:
label: Node.js version
placeholder: 18.x, 20.x, etc.
validations:
required: true
- type: input
id: client-version
attributes:
label: "@elastic/elasticsearch version"
placeholder: 7.17.0, 8.14.1, etc.
validations:
required: true
- type: input
id: os
attributes:
label: Operating system
placeholder: Ubuntu 22.04, macOS, etc.
validations:
required: true
- type: input
id: env-info
attributes:
label: Any other relevant environment information

22
.github/ISSUE_TEMPLATE/feature.md vendored Normal file
View File

@ -0,0 +1,22 @@
---
name: 🚀 Feature Proposal
about: Submit a proposal for a new feature
---
It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/elasticsearch-js/issues) at first before submitting a new one.
**Please read this entire template before posting any issue. If you ignore these instructions
and post an issue here that does not follow the instructions, your issue might be closed,
locked, and assigned the `invalid` label.**
## 🚀 Feature Proposal
A clear and concise description of what the feature is.
## Motivation
Please outline the motivation for the proposal.
## Example
Please provide an example for how this feature would be used.

View File

@ -1,33 +0,0 @@
---
name: 🚀 Feature Proposal
description: Submit a proposal for a new feature
labels: ["Category: Feature"]
body:
- type: markdown
attributes:
value: |
It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/elasticsearch-js/issues) at first before submitting a new one.
**Please read this entire template before posting any issue. If you ignore these instructions
and post an issue here that does not follow the instructions, your issue might be closed,
locked, and assigned the `Category: Not an issue` label.**
- type: textarea
id: feature-proposal
attributes:
label: 🚀 Feature Proposal
description: A clear and concise description of what the feature is.
validations:
required: true
- type: textarea
id: motivation
attributes:
label: Motivation
description: Please outline the motivation for the proposal.
- type: textarea
id: example
attributes:
label: Example
description: Please provide an example for how this feature would be used.

10
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@ -0,0 +1,10 @@
---
name: 💬 Questions / Help
about: If you have questions, please check our Gitter or Help repo
---
## 💬 Questions and Help
### Please note that this issue tracker is not a help forum and this issue may be closed.
It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/elasticsearch-js/issues) at first before submitting a new one.

View File

@ -1,21 +0,0 @@
---
name: 💬 Questions / Help
description: If you have questions, please check our community forum or support
labels: ["Category: Question"]
body:
- type: markdown
attributes:
value: |
### Please note that this issue tracker is not a help forum and this issue may be closed.
Please check our [community forum](https://discuss.elastic.co/) or [contact Elastic support](https://www.elastic.co/support) if your issue is not specifically related to the documented functionality of this client library.
It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/elasticsearch-js/issues) at first before submitting a new one.
- type: textarea
id: question
attributes:
label: Question
description: Your question or comment
validations:
required: true

56
.github/ISSUE_TEMPLATE/regression.md vendored Normal file
View File

@ -0,0 +1,56 @@
---
name: 💥 Regression Report
about: Report unexpected behavior that worked in previous versions
---
It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/elasticsearch-js/issues) at first before submitting a new one.
**Please read this entire template before posting any issue. If you ignore these instructions
and post an issue here that does not follow the instructions, your issue might be closed,
locked, and assigned the `invalid` label.**
## 💥 Regression Report
A clear and concise description of what the regression is.
## Last working version
Worked up to version:
Stopped working in version:
## To Reproduce
Steps to reproduce the behavior:
Paste your code here:
```js
```
<!--
In some cases, it might be challenging to reproduce the bug in a few lines of code.
You can fork the following repository, which contains all the configuration needed
to spin up a three nodes Elasticsearch cluster with security enabled.
The repository also contains a preconfigured client instance that you can use to reproduce the issue.
https://github.com/delvedor/es-reproduce-issue
--->
## Expected behavior
A clear and concise description of what you expected to happen.
Paste the results here:
```js
```
## Your Environment
- *node version*: 6,8,10
- `@elastic/elasticsearch` *version*: >=7.0.0
- *typescript version*: 4.x (if applicable)
- *os*: Mac, Windows, Linux
- *any other relevant information*

View File

@ -1,92 +0,0 @@
---
name: 💥 Regression Report
description: Report unexpected behavior that worked in previous versions
labels: ["Category: Bug"]
body:
- type: markdown
attributes:
value: |
It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/elasticsearch-js/issues) at first before submitting a new one.
**Please read this entire template before posting any issue. If you ignore these instructions
and post an issue here that does not follow the instructions, your issue might be closed,
locked, and assigned the `Category: Not an issue` label.**
- type: textarea
id: report
attributes:
label: Regression report
description: A clear and concise description of what the regression is.
validations:
required: true
- type: input
id: last-working-version
attributes:
label: Last working version
description: Version of `@elastic/elasticsearch` where this last worked.
validations:
required: true
- type: textarea
id: to-reproduce
attributes:
label: To reproduce
description: |
Paste your code here that shows how to reproduce the behavior.
In some cases, it might be challenging to reproduce the bug in a few lines of code.
You can fork the following repository, which contains all the configuration needed to spin up a three nodes Elasticsearch cluster with security enabled.
[This repository](https://github.com/delvedor/es-reproduce-issue) also contains a preconfigured client instance that you can use to reproduce the issue.
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
validations:
required: true
- type: input
id: node-version
attributes:
label: Node.js version
description: What version of Node.js you are using (`node --version`).
validations:
required: true
- type: input
id: typescript-version
attributes:
label: TypeScript version
description: TypeScript version you are using, if applicable.
- type: input
id: elasticsearch-client-version
attributes:
label: Elasticsearch client version
description: What version of `@elastic/elasticsearch` and `@elastic/transport` you are using (`npm ls -a | grep '@elastic'`).
validations:
required: true
- type: input
id: elasticsearch-version
attributes:
label: Elasticsearch server version
description: What version of Elasticsearch you are using.
validations:
required: true
- type: input
id: operating-system
attributes:
label: Operating system
description: What operating system you are running.
placeholder: e.g. Linux, MacOS, Windows
- type: textarea
id: env-info
attributes:
label: Any other relevant environment information.

6
.github/ISSUE_TEMPLATE/security.md vendored Normal file
View File

@ -0,0 +1,6 @@
---
name: 👮 Security Issue
about: Responsible Disclosure
---
If you want to report a security issue, please take a look at [elastic/security](https://www.elastic.co/community/security).

View File

@ -1,8 +0,0 @@
---
name: 👮 Security Issue
description: Responsible disclosure
body:
- type: markdown
attributes:
value: |
If you want to report a security issue, please take a look at [elastic/security](https://www.elastic.co/community/security).

222
.github/make.sh vendored
View File

@ -1,222 +0,0 @@
#!/usr/bin/env bash
# ------------------------------------------------------- #
#
# Build entry script for elasticsearch-js
#
# Must be called: ./.github/make.sh <target> <params>
#
# Version: 1.1.0
#
# Targets:
# ---------------------------
# assemble <VERSION> : build client artifacts with version
# bump <VERSION> : bump client internals to version
# bumpmatrix <VERSION> : bump stack version in test matrix to version
# codegen <VERSION> : generate endpoints
# docsgen <VERSION> : generate documentation
# examplegen : generate the doc examples
# clean : clean workspace
#
# ------------------------------------------------------- #
# ------------------------------------------------------- #
# Bootstrap
# ------------------------------------------------------- #
script_path=$(dirname "$(realpath -s "$0")")
repo=$(realpath "$script_path/../")
# shellcheck disable=SC1090
CMD=$1
TASK=$1
TASK_ARGS=()
VERSION=$2
STACK_VERSION=$VERSION
set -euo pipefail
product="elastic/elasticsearch-js"
output_folder=".buildkite/output"
codegen_folder=".buildkite/output"
OUTPUT_DIR="$repo/${output_folder}"
NODE_JS_VERSION=22
WORKFLOW=${WORKFLOW-staging}
mkdir -p "$OUTPUT_DIR"
echo -e "\033[34;1mINFO:\033[0m PRODUCT ${product}\033[0m"
echo -e "\033[34;1mINFO:\033[0m VERSION ${STACK_VERSION}\033[0m"
echo -e "\033[34;1mINFO:\033[0m OUTPUT_DIR ${OUTPUT_DIR}\033[0m"
case $CMD in
clean)
echo -e "\033[36;1mTARGET: clean workspace $output_folder\033[0m"
rm -rf "$output_folder"
echo -e "\033[32;1mdone.\033[0m"
exit 0
;;
assemble)
if [ -v $VERSION ]; then
echo -e "\033[31;1mTARGET: assemble -> missing version parameter\033[0m"
exit 1
fi
echo -e "\033[36;1mTARGET: assemble artifact $VERSION\033[0m"
TASK=release
TASK_ARGS=("$VERSION" "$output_folder")
;;
codegen)
if [ -v "$VERSION" ] || [[ -z "$VERSION" ]]; then
# fall back to branch name or `main` if no VERSION is set
branch_name=$(git rev-parse --abbrev-ref HEAD)
if [[ "$branch_name" =~ ^[0-9]+\.([0-9]+|x) ]]; then
echo -e "\033[36;1mTARGET: codegen -> No VERSION argument found, using branch name: \`$branch_name\`\033[0m"
VERSION="$branch_name"
else
echo -e "\033[36;1mTARGET: codegen -> No VERSION argument found, using \`main\`\033[0m"
VERSION="main"
fi
fi
if [ "$VERSION" = 'main' ]; then
echo -e "\033[36;1mTARGET: codegen API $VERSION\033[0m"
else
echo -e "\033[36;1mTARGET: codegen API v$VERSION\033[0m"
fi
TASK=codegen
TASK_ARGS=("$VERSION")
;;
docsgen)
if [ -v $VERSION ]; then
echo -e "\033[31;1mTARGET: docsgen -> missing version parameter\033[0m"
exit 1
fi
echo -e "\033[36;1mTARGET: generate docs for $VERSION\033[0m"
TASK=codegen
TASK_ARGS=("$VERSION" "$codegen_folder")
;;
examplesgen)
echo -e "\033[36;1mTARGET: generate examples\033[0m"
TASK=codegen
TASK_ARGS=("$VERSION" "$codegen_folder")
;;
bump)
if [ -v $VERSION ]; then
echo -e "\033[31;1mTARGET: bump -> missing version parameter\033[0m"
exit 1
fi
echo -e "\033[36;1mTARGET: bump to version $VERSION\033[0m"
TASK=bump
TASK_ARGS=("$VERSION")
;;
bumpmatrix)
if [ -v $VERSION ]; then
echo -e "\033[31;1mTARGET: bumpmatrix -> missing version parameter\033[0m"
exit 1
fi
echo -e "\033[36;1mTARGET: bump stack in test matrix to version $VERSION\033[0m"
TASK=bumpmatrix
TASK_ARGS=("$VERSION")
;;
*)
echo -e "\n'$CMD' is not supported right now\n"
echo -e "\nUsage:"
echo -e "\t $0 release \$VERSION\n"
echo -e "\t $0 bump \$VERSION"
echo -e "\t $0 codegen \$VERSION"
exit 1
;;
esac
# ------------------------------------------------------- #
# Build Container
# ------------------------------------------------------- #
echo -e "\033[34;1mINFO: building $product container\033[0m"
docker build \
--file .buildkite/Dockerfile-make \
--tag "$product" \
--build-arg NODE_JS_VERSION="$NODE_JS_VERSION" \
--build-arg "BUILDER_UID=$(id -u)" \
--build-arg "BUILDER_GID=$(id -g)" \
.
# ------------------------------------------------------- #
# Run the Container
# ------------------------------------------------------- #
echo -e "\033[34;1mINFO: running $product container\033[0m"
if [[ -z "${BUILDKITE+x}" ]] && [[ -z "${CI+x}" ]] && [[ -z "${GITHUB_ACTIONS+x}" ]]; then
echo -e "\033[34;1mINFO: Running in local mode"
docker run \
-u "$(id -u):$(id -g)" \
--volume "$repo:/usr/src/elasticsearch-js" \
--volume /usr/src/elasticsearch-js/node_modules \
--volume "$(realpath "$repo/../elastic-client-generator-js"):/usr/src/elastic-client-generator-js" \
--env "WORKFLOW=$WORKFLOW" \
--name make-elasticsearch-js \
--rm \
$product \
/bin/bash -c "mkdir -p /usr/src/elastic-client-generator-js/output && \
node .buildkite/make.mjs --task $TASK ${TASK_ARGS[*]}"
else
echo -e "\033[34;1mINFO: Running in CI mode"
# determine branch to clone
GENERATOR_BRANCH="main"
if [[ "$VERSION" == 8.* ]]; then
GENERATOR_BRANCH="8.x"
fi
echo -e "\033[34;1mINFO: Generator branch: $GENERATOR_BRANCH"
docker run \
--volume "$repo:/usr/src/elasticsearch-js" \
--volume /usr/src/elasticsearch-js/node_modules \
-u "$(id -u):$(id -g)" \
--env "WORKFLOW=$WORKFLOW" \
--name make-elasticsearch-js \
--rm \
$product \
/bin/bash -c "cd /usr/src && \
git clone --branch $GENERATOR_BRANCH https://$CLIENTS_GITHUB_TOKEN@github.com/elastic/elastic-client-generator-js.git && \
mkdir -p /usr/src/elastic-client-generator-js/output && \
cd /usr/src/elasticsearch-js && \
node .buildkite/make.mjs --task $TASK ${TASK_ARGS[*]}"
fi
# ------------------------------------------------------- #
# Post Command tasks & checks
# ------------------------------------------------------- #
if [[ "$CMD" == "assemble" ]]; then
if compgen -G ".buildkite/output/*" >/dev/null; then
echo -e "\033[32;1mTARGET: successfully assembled client v$VERSION\033[0m"
else
echo -e "\033[31;1mTARGET: assemble failed, empty workspace!\033[0m"
exit 1
fi
fi
if [[ "$CMD" == "bump" ]]; then
if [ -n "$(git status --porcelain)" ]; then
echo -e "\033[32;1mTARGET: successfully bumped client v$VERSION\033[0m"
else
echo -e "\033[31;1mTARGET: failed bumped client v$VERSION\033[0m"
exit 1
fi
fi
if [[ "$CMD" == "codegen" ]]; then
if [ -n "$(git status --porcelain)" ]; then
echo -e "\033[32;1mTARGET: successfully generated client v$VERSION\033[0m"
else
echo -e "\033[31;1mTARGET: failed generating client v$VERSION\033[0m"
exit 1
fi
fi
if [[ "$CMD" == "docsgen" ]]; then
echo "TODO"
fi
if [[ "$CMD" == "examplesgen" ]]; then
echo "TODO"
fi

26
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,26 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 15
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- "discussion"
- "feature request"
- "bug"
- "todo"
- "good first issue"
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: |
We understand that this might be important for you, but this issue has been automatically marked as stale because it has not had recent activity either from our end or yours.
It will be closed if no further activity occurs, please write a comment if you would like to keep this going.
Note: in the past months we have built a new client, that has just landed in master. If you want to open an issue or a pr for the legacy client, you should do that in https://github.com/elastic/elasticsearch-js-legacy
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@ -1,27 +1,16 @@
---
name: Backport
on:
pull_request_target:
pull_request:
types:
- closed
- labeled
jobs:
backport:
name: Backport
runs-on: ubuntu-latest
# Only react to merged PRs for security reasons.
# See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target.
if: >
github.event.pull_request.merged
&& (
github.event.action == 'closed'
|| (
github.event.action == 'labeled'
&& contains(github.event.label.name, 'backport')
)
)
name: Backport
steps:
- uses: tibdex/backport@9565281eda0731b1d20c4025c43339fb0a23812e # v2.0.4
- name: Backport
uses: tibdex/backport@v2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,19 +0,0 @@
name: docs-build
on:
push:
branches:
- main
pull_request_target: ~
merge_group: ~
jobs:
docs-preview:
uses: elastic/docs-builder/.github/workflows/preview-build.yml@main
with:
path-pattern: docs/**
permissions:
deployments: write
id-token: write
contents: read
pull-requests: read

View File

@ -1,14 +0,0 @@
name: docs-cleanup
on:
pull_request_target:
types:
- closed
jobs:
docs-preview:
uses: elastic/docs-builder/.github/workflows/preview-cleanup.yml@main
permissions:
contents: none
id-token: write
deployments: write

View File

@ -1,50 +1,34 @@
---
name: Node CI
on:
pull_request: {}
on: [push, pull_request]
jobs:
paths-filter:
name: Detect files changed
runs-on: ubuntu-latest
outputs:
src-only: "${{ steps.changes.outputs.src-only }}"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
persist-credentials: false
- uses: dorny/paths-filter/@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: changes
with:
filters: |
src-only:
- '!(**/*.{md,asciidoc,txt}|*.{md,asciidoc,txt}|{docs,.buildkite,scripts}/**/*|catalog-info.yaml)'
- '.github/workflows/**'
test:
name: Test
runs-on: ${{ matrix.os }}
needs: paths-filter
# only run if code relevant to unit tests was changed
if: needs.paths-filter.outputs.src-only == 'true'
strategy:
fail-fast: false
matrix:
node-version: [18.x, 20.x, 22.x, 23.x]
node-version: [14.x, 16.x, 18.x, 20.x]
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
persist-credentials: false
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
# workaround for failing tests on Node.js 14.x
# see https://github.com/actions/setup-node/issues/411
- name: Force install specific npm version
run: |
npm install --global npm@8.3.1
npm install --global npm@9.7.1
- name: Install
run: |
npm install
@ -57,23 +41,21 @@ jobs:
run: |
npm run test:unit
- name: ECMAScript module test
run: |
npm run test:esm
license:
name: License check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
persist-credentials: false
strategy:
matrix:
node-version: [20.x]
- name: Use Node.js
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: 22.x
node-version: ${{ matrix.node-version }}
- name: Install
run: |
@ -82,42 +64,3 @@ jobs:
- name: License checker
run: |
npm run license-checker
- name: SPDX header check
run: npm run license-header
test-bun:
name: Test Bun
runs-on: ${{ matrix.os }}
needs: paths-filter
# only run if code relevant to unit tests was changed
if: needs.paths-filter.outputs.src-only == 'true'
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
persist-credentials: false
- name: Use Bun
uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2
- name: Install
run: |
bun install
- name: Lint
run: |
bun run lint
- name: Unit test
run: |
bun run test:unit-bun
- name: ECMAScript module test
run: |
bun run test:esm

View File

@ -1,60 +0,0 @@
name: Publish Package to npm
on:
workflow_dispatch:
inputs:
branch:
description: "Git branch to build and publish"
required: true
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
persist-credentials: false
ref: ${{ github.event.inputs.branch }}
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
with:
node-version: "22.x"
registry-url: "https://registry.npmjs.org"
- run: npm install -g npm
- run: npm install
- run: npm test
- name: npm publish
run: |
version=$(jq -r .version package.json)
tag_meta=$(echo "$version" | cut -s -d '-' -f2)
if [[ -z "$tag_meta" ]]; then
npm publish --provenance --access public
else
tag=$(echo "$tag_meta" | cut -d '.' -f1)
npm publish --provenance --access public --tag "$tag"
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Publish version on GitHub
run: |
version=$(jq -r .version package.json)
tag_meta=$(echo "$version" | cut -s -d '-' -f2)
if [[ -z "$tag_meta" ]]; then
gh release create \
-n "[Changelog](https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/$BRANCH_NAME/changelog-client.html)"
--target "$BRANCH_NAME" \
--title "v$version" \
"v$version"
else
tag_main=$(echo "$version" | cut -d '-' -f1)
gh release create \
-n "This is a $tag_main pre-release. Changes may not be stable." \
--latest=false \
--prerelease \
--target "$BRANCH_NAME" \
--title "v$version" \
"v$version"
fi
env:
BRANCH_NAME: ${{ github.event.inputs.branch }}
GH_TOKEN: ${{ github.token }}

View File

@ -1,21 +0,0 @@
---
name: "Close stale issues and PRs"
on:
schedule:
- cron: "30 1 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9
with:
stale-issue-label: stale
stale-pr-label: stale
days-before-stale: 90
days-before-close: 14
exempt-issue-labels: "good first issue,tracking"
close-issue-label: closed-stale
close-pr-label: closed-stale
stale-issue-message: "This issue is stale because it has been open 90 days with no activity. Remove the `stale` label, or leave a comment, or this will be closed in 14 days."
stale-pr-message: "This pull request is stale because it has been open 90 days with no activity. Remove the `stale` label, or leave a comment, or this will be closed in 14 days."

5
.gitignore vendored
View File

@ -63,8 +63,3 @@ test/bundlers/**/bundle.js
test/bundlers/parcel-test/.parcel-cache
lib
junit-output
bun.lockb
test-results
processinfo
.tap

View File

@ -64,6 +64,7 @@ test
scripts
# ci configuration
.ci
.travis.yml
.buildkite
certs
@ -72,5 +73,3 @@ CODE_OF_CONDUCT.md
CONTRIBUTING.md
src
bun.lockb
.tap

View File

@ -8,7 +8,7 @@ improving the documentation,
submitting bug reports and feature requests or writing code.
## Repository structure
The `main` branch is considered unstable, and it's compatible with Elasticsearch main. Unless you are patching an issue, new features should always be sent to the `main` branch, in case of a bugfix, it depends if the bug affects all the release lines.<br/>
The `master` branch is considered unstable, and it's compatible with Elasticsearch master. Unless you are patching an issue, new features should always be sent to the `master` branch, in case of a bugfix, it depends if the bug affects all the release lines.<br/>
There is a branch for every supported release line, such as `7.x` or `6.x`. We release bugfixes as soon as possible, while minor and major releases are published at the same time of the Elastic Stack.
Usually for every release line there will be a *published* version and a *next* version. Eg: the `7.x` branch contains the version published on npm, and bugfixes should be sent there, while `7.2` *(assuming that 7.1.x is released)* contains the next version, and new features should be sent there.
@ -31,7 +31,7 @@ Once your changes are ready to submit for review:
1. Test your changes
Run the test suite to make sure that nothing is broken.
Usually running `npm test` is enough; our CI will take care of running the integration tests. If you want to run the integration tests yourself, see [the *Testing* section](#testing) below.
Usually run `npm test` is enough, our CI will take care of running the integration test. If you want to run the integration test yourself, see the *Testing* section below.
2. Submit a pull request
@ -58,50 +58,36 @@ Once your changes are ready to submit for review:
### Code generation
The entire content of the `src/api/` directory is automatically generated from [the Elasticsearch specification](https://github.com/elastic/elasticsearch-specification), as is the `docs/reference.asciidoc` file.
This code generation is done using a separate repository that is not currently available to the public.
If you find discrepancies between this client's API code and what you see when actually interacting with an Elasticsearch API, you can open a pull request here to fix it.
For API fixes, it's likely a change will need to be made to the specification as well, to ensure your fix is not undone by the code generation process.
We will do our best to make sure this is addressed when reviewing and merging your changes.
PRs to improve the specification are also welcome!
It is implemented in TypeScript, so JavaScript devs should be able to understand it fairly easily.
Spec fixes are particularly helpful, as they will be reflected in ALL official Elasticsearch clients, not just this one.
The entire content of the API folder is generated as well as the `docs/reference.asciidoc` file.<br/>
If you want to run the code generation you should run the following command:
```sh
node scripts/generate --tag <tag name>
# or
node scripts/generate --branch <branch name>
```
Then you should copy the content of `api/generated.d.ts` into the `index.d.ts` file *(automate this step would be a nice pr!)*.
### Testing
There are a few different test scripts.
Usually during development you only need to run `npm test`, but if you want you can run just a part of the suite:
There are different test scripts, usually during development you only need to run `npm test`, but if you want you can run just a part of the suite, following you will find all the testing scripts and what they do.
| Script | Description |
|---|---|
| `npm run test:unit` | Runs the content of the `test/unit` folder. |
| `npm run test:coverage-100` | Runs unit tests enforcing 100% coverage. |
| `npm run test:coverage-report` | Runs unit tests and generates an `lcov` coverage report. |
| `npm run test:coverage-ui` | Runs unit tests and generates an HTML coverage report. |
| `npm run test:integration` | Runs the integration test runner.<br/>**Note: requires a living instance of Elasticsearch.** |
| `npm run lint` | Run the [linter](https://github.com/standard/ts-standard). |
| `npm run lint:fix` | Fixes linter errors. |
| `npm run license-checker` | Checks that all dependencies have acceptable open source licenses. |
| `npm test` | Runs `lint` and `test:unit`. |
| `npm run test:behavior` | Runs the content of the `test/behavior` folder. |
| `npm run test:types` | Runs the content of the `test/types` folder. |
| `npm run test:unit -- --cov --coverage-report=html` | Runs the content of the `test/unit` folder and calculates the code coverage. |
| `npm run test:integration` | Runs the integration test runner.<br/>*Note: it requires a living instance of Elasticsearch.* |
| `npm run lint` | Run the [linter](https://standardjs.com/). |
| `npm run lint:fix` | Fixes the lint errors. |
| `npm test` | Runs lint, unit, behavior, and types test. |
#### Integration test
The integration test are generated on the fly by the runner you will find inside `test/integration`, once you execute it, it will clone the Elasticsearch repository and checkout the correct version to grab the [OSS yaml files](https://github.com/elastic/elasticsearch/tree/master/rest-api-spec/src/main/resources/rest-api-spec/test) and the [Elastic licensed yaml files](https://github.com/elastic/elasticsearch/tree/master/x-pack/plugin/src/test/resources/rest-api-spec/test) that will be used for generating the test.
The integration tests are generated on the fly by the runner you will find inside `test/integration`.
Once you execute it, it will fetch the [YAML REST test files](https://github.com/elastic/elasticsearch/tree/main/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test) from our artifacts API.
These are used to generate the integration tests.
Usually this step is executed by CI since it takes some time, but you can easily run this yourself!
Just follow this steps:
1. Boot a fresh Elasticsearch instance, which can be done in a Docker container by running `STACK_VERSION=8.10.0 DETACH=true .buildkite/run-elasticsearch.sh`, where `STACK_VERSION` and `DETACH` environment variables can be adjusted to your needs. A `TEST_SUITE` env var can also be set to `free` or `platinum`, and defaults to `free`.
1. Run `npm run test:integration` to run the whole suite, or `npm run test:integration -- --bail` to stop after the first failure.
1. Grab a coffee, it will take some time. ;)
This suite is very large, and not all tests will pass.
This is fine.
This suite is mostly used to identify notable changes in success/fail rate over time as we make changes to the client.
Usually this step is executed by CI since it takes some time, but you can easily run this yourself! Just follow this steps:
1. Boot an Elasticsearch instance, you can do that by running `./scripts/es-docker.sh` or `./scripts/es-docker-platinum.sh`, the first one will work only with the OSS APIs, while the second will work also with the Elastic licensed APIs;
1. If you are running the OSS test, you should use `npm run test:integration`, otherwise use `TEST_ES_SERVER=https://elastic:changeme@localhost:9200 npm run test:integration`. You can also pass a `-b` parameter if you want the test to bail out at the first failure: `npm run test:integration -- -b`;
1. Grab a coffee, it will take some time ;)
### Releasing

11
Makefile Normal file
View File

@ -0,0 +1,11 @@
.PHONY: integration-setup
integration-setup: integration-cleanup
DETACH=true .ci/run-elasticsearch.sh
.PHONY: integration-cleanup
integration-cleanup:
docker container rm --force --volumes instance || true
.PHONY: integration
integration: integration-setup
npm run test:integration

View File

@ -4,11 +4,6 @@
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) [![Build Status](https://badge.buildkite.com/15e4246eb268ea78f6e10aa90bce38c1abb0a4489e79f5a0ac.svg)](https://buildkite.com/elastic/elasticsearch-javascript-client-integration-tests/builds?branch=main) [![Node CI](https://github.com/elastic/elasticsearch-js/actions/workflows/nodejs.yml/badge.svg)](https://github.com/elastic/elasticsearch-js/actions/workflows/nodejs.yml) [![codecov](https://codecov.io/gh/elastic/elasticsearch-js/branch/master/graph/badge.svg)](https://codecov.io/gh/elastic/elasticsearch-js) [![NPM downloads](https://img.shields.io/npm/dm/@elastic/elasticsearch.svg?style=flat)](https://www.npmjs.com/package/@elastic/elasticsearch)
**[Download the latest version of Elasticsearch](https://www.elastic.co/downloads/elasticsearch)**
or
**[sign-up](https://cloud.elastic.co/registration?elektra=en-ess-sign-up-page)**
**for a free trial of Elastic Cloud**.
The official Node.js client for Elasticsearch.
## Installation
@ -21,25 +16,6 @@ of the getting started documentation.
Refer to the [Connecting section](https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/getting-started-js.html#_connecting)
of the getting started documentation.
## Compatibility
The Elasticsearch client is compatible with currently maintained JS versions.
Language clients are forward compatible; meaning that clients support
communicating with greater or equal minor versions of Elasticsearch without
breaking. It does not mean that the client automatically supports new features
of newer Elasticsearch versions; it is only possible after a release of a new
client version. For example, a 8.12 client version won't automatically support
the new features of the 8.13 version of Elasticsearch, the 8.13 client version
is required for that. Elasticsearch language clients are only backwards
compatible with default distributions and without guarantees made.
| Elasticsearch Version | Elasticsearch-JS Branch | Supported |
| --------------------- | ------------------------ | --------- |
| main | main | |
| 8.x | 8.x | 8.x |
| 7.x | 7.x | 7.17 |
## Usage
* [Creating an index](https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/getting-started-js.html#_creating_an_index)
@ -52,7 +28,7 @@ compatible with default distributions and without guarantees made.
### Node.js support
NOTE: The minimum supported version of Node.js is `v18`.
NOTE: The minimum supported version of Node.js is `v14`.
The client versioning follows the Elastic Stack versioning, this means that
major, minor, and patch releases are done following a precise schedule that
@ -77,7 +53,6 @@ of `^7.10.0`).
| `10.x` | `April 2021` | `7.12` (mid 2021) |
| `12.x` | `April 2022` | `8.2` (early 2022) |
| `14.x` | `April 2023` | `8.8` (early 2023) |
| `16.x` | `September 2023` | `8.11` (late 2023) |
### Compatibility
@ -98,8 +73,7 @@ npm install @elastic/elasticsearch@<major>
#### Browser
> [!WARNING]
> There is no official support for the browser environment. It exposes your Elasticsearch instance to everyone, which could lead to security issues.
WARNING: There is no official support for the browser environment. It exposes your Elasticsearch instance to everyone, which could lead to security issues.
We recommend that you write a lightweight proxy that uses this client instead, you can see a proxy example [here](./docs/examples/proxy).
## Documentation

View File

@ -6,7 +6,7 @@ metadata:
name: elasticsearch-js
spec:
type: library
owner: group:devtools-team
owner: group:clients-team
lifecycle: production
---
@ -18,7 +18,7 @@ metadata:
description: elasticsearch-js - integration tests
spec:
type: buildkite-pipeline
owner: group:devtools-team
owner: group:clients-team
system: buildkite
implementation:
apiVersion: buildkite.elastic.dev/v1
@ -28,29 +28,22 @@ spec:
spec:
repository: elastic/elasticsearch-js
pipeline_file: .buildkite/pipeline.yml
env:
ELASTIC_SLACK_NOTIFICATIONS_ENABLED: "true"
SLACK_NOTIFICATIONS_CHANNEL: "#devtools-notify-javascript"
teams:
devtools-team:
clients-team:
access_level: MANAGE_BUILD_AND_READ
everyone:
access_level: READ_ONLY
provider_settings:
build_pull_requests: false
build_branches: false
cancel_intermediate_builds: true
cancel_intermediate_builds_branch_filter: "!main"
cancel_intermediate_builds_branch_filter: '!main'
schedules:
main:
branch: "main"
cronline: "@daily"
8_x:
branch: "8.x"
cronline: "@daily"
8_17:
branch: "8.17"
cronline: "@daily"
8_18:
branch: "8.18"
cronline: "@daily"
main_semi_daily:
branch: 'main'
cronline: '0 */12 * * *'
8_8_semi_daily:
branch: '8.8'
cronline: '0 */12 * * *'
8_7_daily:
branch: '8.7'
cronline: '@daily'

View File

@ -0,0 +1,106 @@
[[advanced-config]]
=== Advanced configuration
If you need to customize the client behavior heavily, you are in the right
place! The client enables you to customize the following internals:
* `ConnectionPool` class
* `Connection` class
* `Serializer` class
NOTE: For information about the `Transport` class, refer to <<transport>>.
[discrete]
==== `ConnectionPool`
This class is responsible for keeping in memory all the {es} Connection that you
are using. There is a single Connection for every node. The connection pool
handles the resurrection strategies and the updates of the pool.
[source,js]
----
const { Client, ConnectionPool } = require('@elastic/elasticsearch')
class MyConnectionPool extends ConnectionPool {
markAlive (connection) {
// your code
super.markAlive(connection)
}
}
const client = new Client({
ConnectionPool: MyConnectionPool,
cloud: { id: '<cloud-id>' },
auth: { apiKey: 'base64EncodedKey' }
})
----
[discrete]
==== `Connection`
This class represents a single node, it holds every information we have on the
node, such as roles, id, URL, custom headers and so on. The actual HTTP request
is performed here, this means that if you want to swap the default HTTP client
(Node.js core), you should override the `request` method of this class.
[source,js]
----
const { Client, BaseConnection } = require('@elastic/elasticsearch')
class MyConnection extends BaseConnection {
request (params, callback) {
// your code
}
}
const client = new Client({
Connection: MyConnection,
cloud: { id: '<cloud-id>' },
auth: { apiKey: 'base64EncodedKey' }
})
----
[discrete]
==== `Serializer`
This class is responsible for the serialization of every request, it offers the
following methods:
* `serialize(object: any): string;` serializes request objects.
* `deserialize(json: string): any;` deserializes response strings.
* `ndserialize(array: any[]): string;` serializes bulk request objects.
* `qserialize(object: any): string;` serializes request query parameters.
[source,js]
----
const { Client, Serializer } = require('@elastic/elasticsearch')
class MySerializer extends Serializer {
serialize (object) {
// your code
}
}
const client = new Client({
Serializer: MySerializer,
cloud: { id: '<cloud-id>' },
auth: { apiKey: 'base64EncodedKey' }
})
----
[discrete]
==== Migrate to v8
The Node.js client can be configured to emit an HTTP header
`Accept: application/vnd.elasticsearch+json; compatible-with=7`
which signals to Elasticsearch that the client is requesting
`7.x` version of request and response bodies. This allows for
upgrading from 7.x to 8.x version of Elasticsearch without upgrading
everything at once. Elasticsearch should be upgraded first after
the compatibility header is configured and clients should be upgraded
second.
To enable to setting, configure the environment variable
`ELASTIC_CLIENT_APIVERSIONING` to `true`.

270
docs/basic-config.asciidoc Normal file
View File

@ -0,0 +1,270 @@
[[basic-config]]
=== Basic configuration
This page shows you the possible basic configuration options that the clients
offers.
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
cloud: { id: '<cloud-id>' },
auth: { apiKey: 'base64EncodedKey' },
maxRetries: 5,
requestTimeout: 60000,
sniffOnStart: true
})
----
[cols=2*]
|===
|`node` or `nodes`
a|The Elasticsearch endpoint to use. +
It can be a single string or an array of strings:
[source,js]
----
node: 'http://localhost:9200'
----
Or it can be an object (or an array of objects) that represents the node:
[source,js]
----
node: {
url: new URL('http://localhost:9200'),
tls: 'tls options',
agent: 'http agent options',
id: 'custom node id',
headers: { 'custom': 'headers' }
roles: {
master: true,
data: true,
ingest: true,
ml: false
}
}
----
|`auth`
a|Your authentication data. You can use both basic authentication and
{ref}/security-api-create-api-key.html[ApiKey]. +
See <<authentication,Authentication>> for more details. +
_Default:_ `null`
Basic authentication:
[source,js]
----
auth: {
username: 'elastic',
password: 'changeme'
}
----
{ref}/security-api-create-api-key.html[ApiKey] authentication:
[source,js]
----
auth: {
apiKey: 'base64EncodedKey'
}
----
Bearer authentication, useful for https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-service-token.html[service account tokens]. Be aware that it does not handle automatic token refresh:
[source,js]
----
auth: {
bearer: 'token'
}
----
|`maxRetries`
|`number` - Max number of retries for each request. +
_Default:_ `3`
|`requestTimeout`
|`number` - Max request timeout in milliseconds for each request. +
_Default:_ `30000`
|`pingTimeout`
|`number` - Max ping request timeout in milliseconds for each request. +
_Default:_ `3000`
|`sniffInterval`
|`number, boolean` - Perform a sniff operation every `n` milliseconds. Sniffing might not be the best solution for you, take a look https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how[here] to know more. +
_Default:_ `false`
|`sniffOnStart`
|`boolean` - Perform a sniff once the client is started. Sniffing might not be the best solution for you, take a look https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how[here] to know more. +
_Default:_ `false`
|`sniffEndpoint`
|`string` - Endpoint to ping during a sniff. +
_Default:_ `'_nodes/_all/http'`
|`sniffOnConnectionFault`
|`boolean` - Perform a sniff on connection fault. Sniffing might not be the best solution for you, take a look https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how[here] to know more. +
_Default:_ `false`
|`resurrectStrategy`
|`string` - Configure the node resurrection strategy. +
_Options:_ `'ping'`, `'optimistic'`, `'none'` +
_Default:_ `'ping'`
|`suggestCompression`
|`boolean` - Adds `accept-encoding` header to every request. +
_Default:_ `false`
|`compression`
|`string, boolean` - Enables gzip request body compression. +
_Options:_ `'gzip'`, `false` +
_Default:_ `false`
|`tls`
|`http.SecureContextOptions` - tls https://nodejs.org/api/tls.html[configuraton]. +
_Default:_ `null`
|`proxy`
a|`string, URL` - If you are using an http(s) proxy, you can put its url here.
The client will automatically handle the connection to it. +
_Default:_ `null`
[source,js]
----
const client = new Client({
node: 'http://localhost:9200',
proxy: 'http://localhost:8080'
})
// Proxy with basic authentication
const client = new Client({
node: 'http://localhost:9200',
proxy: 'http://user:pwd@localhost:8080'
})
----
|`agent`
a|`http.AgentOptions, function` - http agent https://nodejs.org/api/http.html#http_new_agent_options[options],
or a function that returns an actual http agent instance. If you want to disable the http agent use entirely
(and disable the `keep-alive` feature), set the agent to `false`. +
_Default:_ `null`
[source,js]
----
const client = new Client({
node: 'http://localhost:9200',
agent: { agent: 'options' }
})
const client = new Client({
node: 'http://localhost:9200',
// the function takes as parameter the option
// object passed to the Connection constructor
agent: (opts) => new CustomAgent()
})
const client = new Client({
node: 'http://localhost:9200',
// Disable agent and keep-alive
agent: false
})
----
|`nodeFilter`
a|`function` - Filters which node not to use for a request. +
_Default:_
[source,js]
----
function defaultNodeFilter (node) {
// avoid master only nodes
if (node.roles.master === true &&
node.roles.data === false &&
node.roles.ingest === false) {
return false
}
return true
}
----
|`nodeSelector`
a|`function` - custom selection strategy. +
_Options:_ `'round-robin'`, `'random'`, custom function +
_Default:_ `'round-robin'` +
_Custom function example:_
[source,js]
----
function nodeSelector (connections) {
const index = calculateIndex()
return connections[index]
}
----
|`generateRequestId`
a|`function` - function to generate the request id for every request, it takes
two parameters, the request parameters and options. +
By default it generates an incremental integer for every request. +
_Custom function example:_
[source,js]
----
function generateRequestId (params, options) {
// your id generation logic
// must be syncronous
return 'id'
}
----
|`name`
|`string, symbol` - The name to identify the client instance in the events. +
_Default:_ `elasticsearch-js`
|`opaqueIdPrefix`
|`string` - A string that will be use to prefix any `X-Opaque-Id` header. +
See https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/observability.html#_x-opaque-id_support[`X-Opaque-Id` support] for more details. +
_Default:_ `null`
|`headers`
|`object` - A set of custom headers to send in every request. +
_Default:_ `{}`
|`context`
|`object` - A custom object that you can use for observability in your events.
It will be merged with the API level context option. +
_Default:_ `null`
|`enableMetaHeader`
|`boolean` - If true, adds an header named `'x-elastic-client-meta'`, containing some minimal telemetry data,
such as the client and platform version. +
_Default:_ `true`
|`cloud`
a|`object` - Custom configuration for connecting to
https://cloud.elastic.co[Elastic Cloud]. See https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/auth-reference.html[Authentication]
for more details. +
_Default:_ `null` +
_Cloud configuration example:_
[source,js]
----
const client = new Client({
cloud: {
id: '<cloud-id>'
},
auth: {
username: 'elastic',
password: 'changeme'
}
})
----
|`disablePrototypePoisoningProtection`
|`boolean`, `'proto'`, `'constructor'` - By the default the client will protect you against prototype poisoning attacks. Read https://web.archive.org/web/20200319091159/https://hueniverse.com/square-brackets-are-the-enemy-ff5b9fd8a3e8?gi=184a27ee2a08[this article] to learn more. If needed you can disable prototype poisoning protection entirely or one of the two checks. Read the `secure-json-parse` https://github.com/fastify/secure-json-parse[documentation] to learn more. +
_Default:_ `false`
|`caFingerprint`
|`string` - If configured, verify that the fingerprint of the CA certificate that has signed the certificate of the server matches the supplied fingerprint. Only accepts SHA256 digest fingerprints. +
_Default:_ `null`
|`maxResponseSize`
|`number` - When configured, it verifies that the uncompressed response size is lower than the configured number, if it's higher it will abort the request. It cannot be higher than buffer.constants.MAX_STRING_LENTGH +
_Default:_ `null`
|`maxCompressedResponseSize`
|`number` - When configured, it verifies that the compressed response size is lower than the configured number, if it's higher it will abort the request. It cannot be higher than buffer.constants.MAX_LENTGH +
_Default:_ `null`
|===

550
docs/changelog.asciidoc Normal file
View File

@ -0,0 +1,550 @@
[[changelog-client]]
== Release notes
[discrete]
=== 8.9.0
[discrete]
==== Features
[discrete]
===== Support for Elasticsearch `v8.9.0`
You can find all the API changes
https://www.elastic.co/guide/en/elasticsearch/reference/8.9/release-notes-8.9.0.html[here].
[discrete]
===== Allow document to be overwritten in `onDocument` iteratee of bulk helper https://github.com/elastic/elasticsearch-js/pull/1732[#1732]
In the https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/client-helpers.html#bulk-helper[bulk helper], documents could not be modified before being sent to Elasticsearch. It is now possible to https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/client-helpers.html#_modifying_a_document_before_operation[modify a document] before sending it.
[discrete]
==== Fixes
[discrete]
===== Updated `user-agent` header https://github.com/elastic/elasticsearch-js/pull/1954[#1954]
The `user-agent` header the client used to connect to Elasticsearch was using a non-standard format that has been improved.
[discrete]
=== 8.8.1
[discrete]
==== Features
[discrete]
===== Support for Elasticsearch `v8.8.1`
You can find all the API changes
https://www.elastic.co/guide/en/elasticsearch/reference/8.8/release-notes-8.8.1.html[here].
[discrete]
==== Fixes
[discrete]
===== Fix index drift bug in bulk helper https://github.com/elastic/elasticsearch-js/pull/1759[#1759]
Fixes a bug in the bulk helper that would cause `onDrop` to send back the wrong JSON document or error on a nonexistent document when an error occurred on a bulk HTTP request that contained a `delete` action.
[discrete]
===== Fix a memory leak caused by an outdated version of Undici https://github.com/elastic/elasticsearch-js/pull/1902[#1902]
Undici 5.5.1, used by https://github.com/elastic/elastic-transport-js[elastic-transport-js], could create a memory leak when a high volume of requests created too many HTTP `abort` listeners. Upgrading Undici to 5.22.1 removed the memory leak.
[discrete]
=== 8.8.0
[discrete]
==== Features
[discrete]
===== Support for Elasticsearch `v8.8.0`
You can find all the API changes
https://www.elastic.co/guide/en/elasticsearch/reference/8.8/release-notes-8.8.0.html[here].
[discrete]
==== Fixes
[discrete]
===== Fix type declarations for legacy types with a body key https://github.com/elastic/elasticsearch-js/pull/1784[#1784]
Prior releases contained a bug where type declarations for legacy types that include a `body` key were not actually importing the type that includes the `body` key.
[discrete]
=== 8.7.0
[discrete]
===== Support for Elasticsearch `v8.7.0`
You can find all the API changes
https://www.elastic.co/guide/en/elasticsearch/reference/8.7/release-notes-8.7.0.html[here].
[discrete]
=== 8.6.0
[discrete]
===== Bump @elastic/transport to 8.3.1+ https://github.com/elastic/elasticsearch-js/pull/1802[#1802]
The `@elastic/transport` dependency has been bumped to `~8.3.1` to ensure
fixes to the `maxResponseSize` option are available in the client.
[discrete]
===== Support for Elasticsearch `v8.6.0`
You can find all the API changes
https://www.elastic.co/guide/en/elasticsearch/reference/8.6/release-notes-8.6.0.html[here].
[discrete]
=== 8.5.0
[discrete]
===== Support for Elasticsearch `v8.5.0`
You can find all the API changes
https://www.elastic.co/guide/en/elasticsearch/reference/8.5/release-notes-8.5.0.html[here].
[discrete]
=== 8.4.0
[discrete]
===== Support for Elasticsearch `v8.4.0`
You can find all the API changes
https://www.elastic.co/guide/en/elasticsearch/reference/8.4/release-notes-8.4.0.html[here].
[discrete]
=== 8.2.1
[discrete]
==== Fixes
[discrete]
===== Support for Elasticsearch `v8.2.1`
You can find all the API changes
https://www.elastic.co/guide/en/elasticsearch/reference/8.2/release-notes-8.2.1.html[here].
[discrete]
===== Fix ndjson APIs https://github.com/elastic/elasticsearch-js/pull/1688[#1688]
The previous release contained a bug that broken ndjson APIs.
We have released `v8.2.0-patch.1` to address this.
This fix is the same as the one we have released and we strongly recommend upgrading to this version.
[discrete]
===== Fix node shutdown apis https://github.com/elastic/elasticsearch-js/pull/1697[#1697]
The shutdown APIs wheren't complete, this fix completes them.
[discrete]
==== Types: move query keys to body https://github.com/elastic/elasticsearch-js/pull/1693[#1693]
The types definitions where wrongly representing the types of fields present in both query and body.
[discrete]
=== 8.2.0
[discrete]
==== Breaking changes
[discrete]
===== Drop Node.js v12 https://github.com/elastic/elasticsearch-js/pull/1670[#1670]
According to our https://github.com/elastic/elasticsearch-js#nodejs-support[Node.js support matrix].
[discrete]
==== Features
[discrete]
===== Support for Elasticsearch `v8.2`
You can find all the API changes
https://www.elastic.co/guide/en/elasticsearch/reference/8.2/release-notes-8.2.0.html[here].
[discrete]
===== More lenient parameter checks https://github.com/elastic/elasticsearch-js/pull/1662[#1662]
When creating a new client, an `undefined` `caFingerprint` no longer trigger an error for a http connection.
[discrete]
===== Update TypeScript docs and export estypes https://github.com/elastic/elasticsearch-js/pull/1675[#1675]
You can import the full TypeScript requests & responses definitions as it follows:
[source,ts]
----
import { estypes } from '@elastic/elasticsearch'
----
If you need the legacy definitions with the body, you can do the following:
[source,ts]
----
import { estypesWithBody } from '@elastic/elasticsearch'
----
[discrete]
==== Fixes
[discrete]
===== Updated hpagent to the latest version https://github.com/elastic/elastic-transport-js/pull/49[transport/#49]
You can fing the related changes https://github.com/delvedor/hpagent/releases/tag/v1.0.0[here].
[discrete]
=== 8.1.0
[discrete]
==== Features
[discrete]
===== Support for Elasticsearch `v8.1`
You can find all the API changes
https://www.elastic.co/guide/en/elasticsearch/reference/8.1/release-notes-8.1.0.html[here].
[discrete]
===== Export SniffingTransport https://github.com/elastic/elasticsearch-js/pull/1653[#1653]
Now the client exports the SniffingTransport class.
[discrete]
==== Fixes
[discrete]
===== Fix onFlushTimeout timer not being cleared when upstream errors https://github.com/elastic/elasticsearch-js/pull/1616[#1616]
Fixes a memory leak caused by an error in the upstream dataset of the bulk helper.
[discrete]
===== Cleanup abort listener https://github.com/elastic/elastic-transport-js/pull/42[transport/#42]
The legacy http client was not cleaning up the abort listener, which could cause a memory leak.
[discrete]
===== Improve undici performances https://github.com/elastic/elastic-transport-js/pull/41[transport/#41]
Improve the stream body collection and keep alive timeout.
[discrete]
=== 8.0.0
[discrete]
==== Features
[discrete]
===== Support for Elasticsearch `v8.0`
You can find all the API changes
https://www.elastic.co/guide/en/elasticsearch/reference/8.0/release-notes-8.0.0.html[here].
[discrete]
===== Drop old typescript definitions
*Breaking: Yes* | *Migration effort: Medium*
The current TypeScript definitions will be removed from the client, and the new definitions, which contain request and response definitions as well will be shipped by default.
[discrete]
===== Drop callback-style API
*Breaking: Yes* | *Migration effort: Large*
Maintaining both API styles is not a problem per se, but it makes error handling more convoluted due to async stack traces.
Moving to a full-promise API will solve this issue.
[source,js]
----
// callback-style api
client.search({ params }, { options }, (err, result) => {
console.log(err || result)
})
// promise-style api
client.search({ params }, { options })
.then(console.log)
.catch(console.log)
// async-style (sugar syntax on top of promises)
const response = await client.search({ params }, { options })
console.log(response)
----
If you are already using the promise-style API, this won't be a breaking change for you.
[discrete]
===== Remove the current abort API and use the new AbortController standard
*Breaking: Yes* | *Migration effort: Small*
The old abort API makes sense for callbacks but it's annoying to use with promises
[source,js]
----
// callback-style api
const request = client.search({ params }, { options }, (err, result) => {
console.log(err) // RequestAbortedError
})
request.abort()
// promise-style api
const promise = client.search({ params }, { options })
promise
.then(console.log)
.catch(console.log) // RequestAbortedError
promise.abort()
----
Node v12 has added the standard https://nodejs.org/api/globals.html#globals_class_abortcontroller[`AbortController`] API which is designed to work well with both callbacks and promises.
[source,js]
----
const ac = new AbortController()
client.search({ params }, { signal: ac.signal })
.then(console.log)
.catch(console.log) // RequestAbortedError
ac.abort()
----
[discrete]
===== Remove the body key from the request
*Breaking: Yes* | *Migration effort: Small*
Thanks to the new types we are developing now we know exactly where a parameter should go.
The client API leaks HTTP-related notions in many places, and removing them would definitely improve the DX.
This could be a rather big breaking change, so a double solution could be used during the 8.x lifecycle. (accepting body keys without them being wrapped in the body as well as the current solution).
[source,js]
----
// from
const response = await client.search({
index: 'test',
body: {
query: {
match_all: {}
}
}
})
// to
const response = await client.search({
index: 'test',
query: {
match_all: {}
}
})
----
[discrete]
===== Migrate to new separate transport
*Breaking: Yes* | *Migration effort: Small to none*
The separated transport has been rewritten in TypeScript and has already dropped the callback style API.
Given that now is separated, most of the Elasticsearch specific concepts have been removed, and the client will likely need to extend parts of it for reintroducing them.
If you weren't extending the internals of the client, this won't be a breaking change for you.
[discrete]
===== The returned value of API calls is the body and not the HTTP related keys
*Breaking: Yes* | *Migration effort: Small*
The client API leaks HTTP-related notions in many places, and removing them would definitely improve the DX.
The client will expose a new request-specific option to still get the full response details.
[source,js]
----
// from
const response = await client.search({
index: 'test',
body: {
query: {
match_all: {}
}
}
})
console.log(response) // { body: SearchResponse, statusCode: number, headers: object, warnings: array }
// to
const response = await client.search({
index: 'test',
query: {
match_all: {}
}
})
console.log(response) // SearchResponse
// with a bit of TypeScript and JavaScript magic...
const response = await client.search({
index: 'test',
query: {
match_all: {}
}
}, {
meta: true
})
console.log(response) // { body: SearchResponse, statusCode: number, headers: object, warnings: array }
----
[discrete]
===== Use a weighted connection pool
*Breaking: Yes* | *Migration effort: Small to none*
Move from the current cluster connection pool to a weight-based implementation.
This new implementation offers better performances and runs less code in the background, the old connection pool can still be used.
If you weren't extending the internals of the client, this won't be a breaking change for you.
[discrete]
===== Migrate to the "undici" http client
*Breaking: Yes* | *Migration effort: Small to none*
By default, the HTTP client will no longer be the default Node.js HTTP client, but https://github.com/nodejs/undici[undici] instead.
Undici is a brand new HTTP client written from scratch, it offers vastly improved performances and has better support for promises.
Furthermore, it offers comprehensive and predictable error handling. The old HTTP client can still be used.
If you weren't extending the internals of the client, this won't be a breaking change for you.
[discrete]
===== Drop support for old camelCased keys
*Breaking: Yes* | *Migration effort: Medium*
Currently, every path or query parameter could be expressed in both `snake_case` and `camelCase`. Internally the client will convert everything to `snake_case`.
This was done in an effort to reduce the friction of migrating from the legacy to the new client, but now it no longer makes sense.
If you are already using `snake_case` keys, this won't be a breaking change for you.
[discrete]
===== Rename `ssl` option to `tls`
*Breaking: Yes* | *Migration effort: Small*
People usually refers to this as `tls`, furthermore, internally we use the tls API and Node.js refers to it as tls everywhere.
[source,js]
----
// before
const client = new Client({
node: 'https://localhost:9200',
ssl: {
rejectUnauthorized: false
}
})
// after
const client = new Client({
node: 'https://localhost:9200',
tls: {
rejectUnauthorized: false
}
})
----
[discrete]
===== Remove prototype poisoning protection
*Breaking: Yes* | *Migration effort: Small*
Prototype poisoning protection is very useful, but it can cause performances issues with big payloads.
In v8 it will be removed, and the documentation will show how to add it back with a custom serializer.
[discrete]
===== Remove client extensions API
*Breaking: Yes* | *Migration effort: Large*
Nowadays the client support the entire Elasticsearch API, and the `transport.request` method can be used if necessary. The client extensions API have no reason to exist.
[source,js]
----
client.extend('utility.index', ({ makeRequest }) => {
return function _index (params, options) {
// your code
}
})
client.utility.index(...)
----
If you weren't using client extensions, this won't be a breaking change for you.
[discrete]
===== Move to TypeScript
*Breaking: No* | *Migration effort: None*
The new separated transport is already written in TypeScript, and it makes sense that the client v8 will be fully written in TypeScript as well.
[discrete]
===== Move from emitter-like interface to a diagnostic method
*Breaking: Yes* | *Migration effort: Small*
Currently, the client offers a subset of methods of the `EventEmitter` class, v8 will ship with a `diagnostic` property which will be a proper event emitter.
[source,js]
----
// from
client.on('request', console.log)
// to
client.diagnostic.on('request', console.log)
----
[discrete]
===== Remove username & password properties from Cloud configuration
*Breaking: Yes* | *Migration effort: Small*
The Cloud configuration does not support ApiKey and Bearer auth, while the `auth` options does.
There is no need to keep the legacy basic auth support in the cloud configuration.
[source,js]
----
// before
const client = new Client({
cloud: {
id: '<cloud-id>',
username: 'elastic',
password: 'changeme'
}
})
// after
const client = new Client({
cloud: {
id: '<cloud-id>'
},
auth: {
username: 'elastic',
password: 'changeme'
}
})
----
If you are already passing the basic auth options in the `auth` configuration, this won't be a breaking change for you.
[discrete]
===== Calling `client.close` will reject new requests
Once you call `client.close` every new request after that will be rejected with a `NoLivingConnectionsError`. In-flight requests will be executed normally unless an in-flight request requires a retry, in which case it will be rejected.
[discrete]
===== Parameters rename
- `ilm.delete_lifecycle`: `policy` parameter has been renamed to `name`
- `ilm.get_lifecycle`: `policy` parameter has been renamed to `name`
- `ilm.put_lifecycle`: `policy` parameter has been renamed to `name`
- `snapshot.cleanup_repository`: `repository` parameter has been renamed to `name`
- `snapshot.create_repository`: `repository` parameter has been renamed to `name`
- `snapshot.delete_repository`: `repository` parameter has been renamed to `name`
- `snapshot.get_repository`: `repository` parameter has been renamed to `name`
- `snapshot.verify_repository`: `repository` parameter has been renamed to `name`
[discrete]
===== Removal of snake_cased methods
The v7 client provided snake_cased methods, such as `client.delete_by_query`. This is no longer supported, now only camelCased method are present.
So `client.delete_by_query` can be accessed with `client.deleteByQuery`

36
docs/child.asciidoc Normal file
View File

@ -0,0 +1,36 @@
[[child]]
=== Creating a child client
There are some use cases where you may need multiple instances of the client.
You can easily do that by calling `new Client()` as many times as you need, but
you will lose all the benefits of using one single client, such as the long
living connections and the connection pool handling. To avoid this problem, the
client offers a `child` API, which returns a new client instance that shares the
connection pool with the parent client.
NOTE: The event emitter is shared between the parent and the child(ren). If you
extend the parent client, the child client will have the same extensions, while
if the child client adds an extension, the parent client will not be extended.
You can pass to the `child` every client option you would pass to a normal
client, but the connection pool specific options (`ssl`, `agent`, `pingTimeout`,
`Connection`, and `resurrectStrategy`).
CAUTION: If you call `close` in any of the parent/child clients, every client
will be closed.
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
cloud: { id: '<cloud-id>' },
auth: { apiKey: 'base64EncodedKey' }
})
const child = client.child({
headers: { 'x-foo': 'bar' },
requestTimeout: 1000
})
client.info().then(console.log, console.log)
child.info().then(console.log, console.log)
----

View File

@ -0,0 +1,11 @@
[[client-configuration]]
== Configuration
The client is designed to be easily configured for your needs. In the following
section, you can see the possible options that you can use to configure it.
* <<basic-config>>
* <<advanced-config>>
* <<child>>
* <<client-testing>>

664
docs/connecting.asciidoc Normal file
View File

@ -0,0 +1,664 @@
[[client-connecting]]
== Connecting
This page contains the information you need to connect and use the Client with
{es}.
**On this page**
* <<authentication, Authentication options>>
* <<client-usage, Using the client>>
* <<client-faas-env, Using the Client in a Function-as-a-Service Environment>>
* <<client-connect-proxy, Connecting through a proxy>>
* <<client-error-handling, Handling errors>>
* <<product-check, Automatic product check>>
[[authentication]]
[discrete]
=== Authentication
This document contains code snippets to show you how to connect to various {es}
providers.
[discrete]
[[auth-ec]]
==== Elastic Cloud
If you are using https://www.elastic.co/cloud[Elastic Cloud], the client offers
an easy way to connect to it via the `cloud` option. You must pass the Cloud ID
that you can find in the cloud console, then your username and password inside
the `auth` option.
NOTE: When connecting to Elastic Cloud, the client will automatically enable
both request and response compression by default, since it yields significant
throughput improvements. Moreover, the client will also set the tls option
`secureProtocol` to `TLSv1_2_method` unless specified otherwise. You can still
override this option by configuring them.
IMPORTANT: Do not enable sniffing when using Elastic Cloud, since the nodes are
behind a load balancer, Elastic Cloud will take care of everything for you.
Take a look https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how[here]
to know more.
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
cloud: {
id: '<cloud-id>'
},
auth: {
username: 'elastic',
password: 'changeme'
}
})
----
[discrete]
[[connect-self-managed-new]]
=== Connecting to a self-managed cluster
By default {es} will start with security features like authentication and TLS
enabled. To connect to the {es} cluster you'll need to configure the Node.js {es}
client to use HTTPS with the generated CA certificate in order to make requests
successfully.
If you're just getting started with {es} we recommend reading the documentation
on https://www.elastic.co/guide/en/elasticsearch/reference/current/settings.html[configuring]
and
https://www.elastic.co/guide/en/elasticsearch/reference/current/starting-elasticsearch.html[starting {es}]
to ensure your cluster is running as expected.
When you start {es} for the first time you'll see a distinct block like the one
below in the output from {es} (you may have to scroll up if it's been a while):
[source,sh]
----
-> Elasticsearch security features have been automatically configured!
-> Authentication is enabled and cluster connections are encrypted.
-> Password for the elastic user (reset with `bin/elasticsearch-reset-password -u elastic`):
lhQpLELkjkrawaBoaz0Q
-> HTTP CA certificate SHA-256 fingerprint:
a52dd93511e8c6045e21f16654b77c9ee0f34aea26d9f40320b531c474676228
...
----
Depending on the circumstances there are two options for verifying the HTTPS
connection, either verifying with the CA certificate itself or via the HTTP CA
certificate fingerprint.
[discrete]
[[auth-tls]]
==== TLS configuration
The generated root CA certificate can be found in the `certs` directory in your
{es} config location (`$ES_CONF_PATH/certs/http_ca.crt`). If you're running {es}
in Docker there is
https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html[additional documentation for retrieving the CA certificate].
Without any additional configuration you can specify `https://` node urls, and
the certificates used to sign these requests will be verified. To turn off
certificate verification, you must specify an `tls` object in the top level
config and set `rejectUnauthorized: false`. The default `tls` values are the
same that Node.js's https://nodejs.org/api/tls.html#tls_tls_connect_options_callback[`tls.connect()`]
uses.
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
node: 'https://localhost:9200',
auth: {
username: 'elastic',
password: 'changeme'
},
tls: {
ca: fs.readFileSync('./http_ca.crt'),
rejectUnauthorized: false
}
})
----
[discrete]
[[auth-ca-fingerprint]]
==== CA fingerprint
You can configure the client to only trust certificates that are signed by a specific CA certificate
(CA certificate pinning) by providing a `caFingerprint` option.
This will verify that the fingerprint of the CA certificate that has signed
the certificate of the server matches the supplied value.
You must configure a SHA256 digest.
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
node: 'https://example.com'
auth: { ... },
// the fingerprint (SHA256) of the CA certificate that is used to sign
// the certificate that the Elasticsearch node presents for TLS.
caFingerprint: '20:0D:CA:FA:76:...',
tls: {
// might be required if it's a self-signed certificate
rejectUnauthorized: false
}
})
----
The certificate fingerprint can be calculated using `openssl x509` with the
certificate file:
[source,sh]
----
openssl x509 -fingerprint -sha256 -noout -in /path/to/http_ca.crt
----
If you don't have access to the generated CA file from {es} you can use the
following script to output the root CA fingerprint of the {es} instance with
`openssl s_client`:
[source,sh]
----
# Replace the values of 'localhost' and '9200' to the
# corresponding host and port values for the cluster.
openssl s_client -connect localhost:9200 -servername localhost -showcerts </dev/null 2>/dev/null \
| openssl x509 -fingerprint -sha256 -noout -in /dev/stdin
----
The output of `openssl x509` will look something like this:
[source,sh]
----
SHA256 Fingerprint=A5:2D:D9:35:11:E8:C6:04:5E:21:F1:66:54:B7:7C:9E:E0:F3:4A:EA:26:D9:F4:03:20:B5:31:C4:74:67:62:28
----
[discrete]
[[connect-no-security]]
=== Connecting without security enabled
WARNING: Running {es} without security enabled is not recommended.
If your cluster is configured with
https://www.elastic.co/guide/en/elasticsearch/reference/current/security-settings.html[security explicitly disabled]
then you can connect via HTTP:
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
node: 'http://example.com'
})
----
[discrete]
[[auth-strategies]]
=== Authentication strategies
Following you can find all the supported authentication strategies.
[discrete]
[[auth-apikey]]
==== ApiKey authentication
You can use the
{ref-7x}/security-api-create-api-key.html[ApiKey]
authentication by passing the `apiKey` parameter via the `auth` option. The
`apiKey` parameter can be either a base64 encoded string or an object with the
values that you can obtain from the
{ref-7x}/security-api-create-api-key.html[create api key endpoint].
NOTE: If you provide both basic authentication credentials and the ApiKey
configuration, the ApiKey takes precedence.
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
node: 'https://localhost:9200',
auth: {
apiKey: 'base64EncodedKey'
}
})
----
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
node: 'https://localhost:9200',
auth: {
apiKey: {
id: 'foo',
api_key: 'bar'
}
}
})
----
[discrete]
[[auth-bearer]]
==== Bearer authentication
You can provide your credentials by passing the `bearer` token
parameter via the `auth` option.
Useful for https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-service-token.html[service account tokens].
Be aware that it does not handle automatic token refresh.
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
node: 'https://localhost:9200',
auth: {
bearer: 'token'
}
})
----
[discrete]
[[auth-basic]]
==== Basic authentication
You can provide your credentials by passing the `username` and `password`
parameters via the `auth` option.
NOTE: If you provide both basic authentication credentials and the Api Key
configuration, the Api Key will take precedence.
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
node: 'https://localhost:9200',
auth: {
username: 'elastic',
password: 'changeme'
}
})
----
Otherwise, you can provide your credentials in the node(s) URL.
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
node: 'https://username:password@localhost:9200'
})
----
[discrete]
[[client-usage]]
=== Usage
Using the client is straightforward, it supports all the public APIs of {es},
and every method exposes the same signature.
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
cloud: { id: '<cloud-id>' },
auth: { apiKey: 'base64EncodedKey' }
})
const result = await client.search({
index: 'my-index',
query: {
match: { hello: 'world' }
}
})
----
The returned value of every API call is the response body from {es}.
If you need to access additonal metadata, such as the status code or headers,
you must specify `meta: true` in the request options:
[source,js]
----
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
cloud: { id: '<cloud-id>' },
auth: { apiKey: 'base64EncodedKey' }
})
const result = await client.search({
index: 'my-index',
query: {
match: { hello: 'world' }
}
}, { meta: true })
----
In this case, the result will be:
[source,ts]
----
{
body: object | boolean
statusCode: number
headers: object
warnings: [string],
meta: object
}
----
NOTE: The body is a boolean value when you use `HEAD` APIs.
[discrete]
==== Aborting a request
If needed, you can abort a running request by using the `AbortController` standard.
CAUTION: If you abort a request, the request will fail with a
`RequestAbortedError`.
[source,js]
----
const AbortController = require('node-abort-controller')
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
cloud: { id: '<cloud-id>' },
auth: { apiKey: 'base64EncodedKey' }
})
const abortController = new AbortController()
setImmediate(() => abortController.abort())
const result = await client.search({
index: 'my-index',
query: {
match: { hello: 'world' }
}
}, { signal: abortController.signal })
----
[discrete]
==== Request specific options
If needed you can pass request specific options in a second object:
[source,js]
----
const result = await client.search({
index: 'my-index',
body: {
query: {
match: { hello: 'world' }
}
}
}, {
ignore: [404],
maxRetries: 3
})
----
The supported request specific options are:
[cols=2*]
|===
|`ignore`
|`[number]` - HTTP status codes which should not be considered errors for this request. +
_Default:_ `null`
|`requestTimeout`
|`number` - Max request timeout for the request in milliseconds, it overrides the client default. +
_Default:_ `30000`
|`maxRetries`
|`number` - Max number of retries for the request, it overrides the client default. +
_Default:_ `3`
|`compression`
|`string, boolean` - Enables body compression for the request. +
_Options:_ `false`, `'gzip'` +
_Default:_ `false`
|`asStream`
|`boolean` - Instead of getting the parsed body back, you get the raw Node.js stream of data. +
_Default:_ `false`
|`headers`
|`object` - Custom headers for the request. +
_Default:_ `null`
|`querystring`
|`object` - Custom querystring for the request. +
_Default:_ `null`
|`id`
|`any` - Custom request id. _(overrides the top level request id generator)_ +
_Default:_ `null`
|`context`
|`any` - Custom object per request. _(you can use it to pass data to the clients events)_ +
_Default:_ `null`
|`maxResponseSize`
|`number` - When configured, it verifies that the uncompressed response size is lower than the configured number, if it's higher it will abort the request. It cannot be higher than buffer.constants.MAX_STRING_LENTGH +
_Default:_ `null`
|`maxCompressedResponseSize`
|`number` - When configured, it verifies that the compressed response size is lower than the configured number, if it's higher it will abort the request. It cannot be higher than buffer.constants.MAX_LENTGH +
_Default:_ `null`
|`signal`
|`AbortSignal` - The AbortSignal instance to allow request abortion. +
_Default:_ `null`
|===
[discrete]
[[client-faas-env]]
=== Using the Client in a Function-as-a-Service Environment
This section illustrates the best practices for leveraging the {es} client in a Function-as-a-Service (FaaS) environment.
The most influential optimization is to initialize the client outside of the function, the global scope.
This practice does not only improve performance but also enables background functionality as for example https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how[sniffing].
The following examples provide a skeleton for the best practices.
[discrete]
==== GCP Cloud Functions
[source,js]
----
'use strict'
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
// client initialisation
})
exports.testFunction = async function (req, res) {
// use the client
}
----
[discrete]
==== AWS Lambda
[source,js]
----
'use strict'
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
// client initialisation
})
exports.handler = async function (event, context) {
// use the client
}
----
[discrete]
==== Azure Functions
[source,js]
----
'use strict'
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
// client initialisation
})
module.exports = async function (context, req) {
// use the client
}
----
Resources used to assess these recommendations:
- https://cloud.google.com/functions/docs/bestpractices/tips#use_global_variables_to_reuse_objects_in_future_invocations[GCP Cloud Functions: Tips & Tricks]
- https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html[Best practices for working with AWS Lambda functions]
- https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-python?tabs=azurecli-linux%2Capplication-level#global-variables[Azure Functions Python developer guide]
- https://docs.aws.amazon.com/lambda/latest/operatorguide/global-scope.html[AWS Lambda: Comparing the effect of global scope]
[discrete]
[[client-connect-proxy]]
=== Connecting through a proxy
~Added~ ~in~ ~`v7.10.0`~
If you need to pass through an http(s) proxy for connecting to {es}, the client
out of the box offers a handy configuration for helping you with it. Under the
hood, it uses the https://github.com/delvedor/hpagent[`hpagent`] module.
[source,js]
----
const client = new Client({
node: 'http://localhost:9200',
proxy: 'http://localhost:8080'
})
----
Basic authentication is supported as well:
[source,js]
----
const client = new Client({
node: 'http://localhost:9200',
proxy: 'http:user:pwd@//localhost:8080'
})
----
If you are connecting through a not http(s) proxy, such as a `socks5` or `pac`,
you can use the `agent` option to configure it.
[source,js]
----
const SocksProxyAgent = require('socks-proxy-agent')
const client = new Client({
node: 'http://localhost:9200',
agent () {
return new SocksProxyAgent('socks://127.0.0.1:1080')
}
})
----
[discrete]
[[client-error-handling]]
=== Error handling
The client exposes a variety of error objects that you can use to enhance your
error handling. You can find all the error objects inside the `errors` key in
the client.
[source,js]
----
const { errors } = require('@elastic/elasticsearch')
console.log(errors)
----
You can find the errors exported by the client in the table below.
[cols=3*]
|===
|*Error*
|*Description*
|*Properties*
|`ElasticsearchClientError`
|Every error inherits from this class, it is the basic error generated by the client.
a|* `name` - `string`
* `message` - `string`
|`TimeoutError`
|Generated when a request exceeds the `requestTimeout` option.
a|* `name` - `string`
* `message` - `string`
* `meta` - `object`, contains all the information about the request
|`ConnectionError`
|Generated when an error occurs during the request, it can be a connection error or a malformed stream of data.
a|* `name` - `string`
* `message` - `string`
* `meta` - `object`, contains all the information about the request
|`RequestAbortedError`
|Generated if the user calls the `request.abort()` method.
a|* `name` - `string`
* `message` - `string`
* `meta` - `object`, contains all the information about the request
|`NoLivingConnectionsError`
|Given the configuration, the ConnectionPool was not able to find a usable Connection for this request.
a|* `name` - `string`
* `message` - `string`
* `meta` - `object`, contains all the information about the request
|`SerializationError`
|Generated if the serialization fails.
a|* `name` - `string`
* `message` - `string`
* `data` - `object`, the object to serialize
|`DeserializationError`
|Generated if the deserialization fails.
a|* `name` - `string`
* `message` - `string`
* `data` - `string`, the string to deserialize
|`ConfigurationError`
|Generated if there is a malformed configuration or parameter.
a|* `name` - `string`
* `message` - `string`
|`ResponseError`
|Generated when in case of a `4xx` or `5xx` response.
a|* `name` - `string`
* `message` - `string`
* `meta` - `object`, contains all the information about the request
* `body` - `object`, the response body
* `statusCode` - `object`, the response headers
* `headers` - `object`, the response status code
|===
[discrete]
[[product-check]]
=== Automatic product check
Since v7.14.0, the client performs a required product check before the first call.
This pre-flight product check allows the client to establish the version of Elasticsearch
that it is communicating with. The product check requires one additional HTTP request to
be sent to the server as part of the request pipeline before the main API call is sent.
In most cases, this will succeed during the very first API call that the client sends.
Once the product check completes, no further product check HTTP requests are sent for
subsequent API calls.

View File

@ -1,10 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.security.clearCachedRealms({
realms: "default_file,ldap1",
});
console.log(response);
----

View File

@ -1,11 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.forcemerge({
index: ".ds-my-data-stream-2099.03.07-000001",
max_num_segments: 1,
});
console.log(response);
----

View File

@ -1,19 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
query: {
pinned: {
ids: ["1", "4", "100"],
organic: {
match: {
description: "iphone",
},
},
},
},
});
console.log(response);
----

View File

@ -1,20 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.create({
index: "my-index-000001",
settings: {
analysis: {
analyzer: {
my_analyzer: {
tokenizer: "whitespace",
filter: ["stemmer"],
},
},
},
},
});
console.log(response);
----

View File

@ -1,40 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.watcher.putWatch({
id: "cluster_health_watch",
trigger: {
schedule: {
interval: "10s",
},
},
input: {
http: {
request: {
host: "localhost",
port: 9200,
path: "/_cluster/health",
},
},
},
condition: {
compare: {
"ctx.payload.status": {
eq: "red",
},
},
},
actions: {
send_email: {
email: {
to: "username@example.org",
subject: "Cluster Status Warning",
body: "Cluster status is RED",
},
},
},
});
console.log(response);
----

View File

@ -1,8 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.migration.postFeatureUpgrade();
console.log(response);
----

View File

@ -1,16 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
index: "my-index",
query: {
match: {
"http.clientip": "40.135.0.0",
},
},
fields: ["http.clientip"],
});
console.log(response);
----

View File

@ -1,11 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.getDataStream({
name: "my-data-stream",
filter_path: "data_streams.indices.index_name",
});
console.log(response);
----

View File

@ -1,8 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.shardStores();
console.log(response);
----

View File

@ -1,15 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.renderSearchTemplate({
source: '{ "query": {{#toJson}}my_query{{/toJson}} }',
params: {
my_query: {
match_all: {},
},
},
});
console.log(response);
----

View File

@ -1,12 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.analyze({
tokenizer: "standard",
filter: ["asciifolding"],
text: "açaí à la carte",
});
console.log(response);
----

View File

@ -1,67 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.create({
index: "italian_example",
settings: {
analysis: {
filter: {
italian_elision: {
type: "elision",
articles: [
"c",
"l",
"all",
"dall",
"dell",
"nell",
"sull",
"coll",
"pell",
"gl",
"agl",
"dagl",
"degl",
"negl",
"sugl",
"un",
"m",
"t",
"s",
"v",
"d",
],
articles_case: true,
},
italian_stop: {
type: "stop",
stopwords: "_italian_",
},
italian_keywords: {
type: "keyword_marker",
keywords: ["esempio"],
},
italian_stemmer: {
type: "stemmer",
language: "light_italian",
},
},
analyzer: {
rebuilt_italian: {
tokenizer: "standard",
filter: [
"italian_elision",
"lowercase",
"italian_stop",
"italian_keywords",
"italian_stemmer",
],
},
},
},
},
});
console.log(response);
----

View File

@ -1,19 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.inference.put({
task_type: "text_embedding",
inference_id: "my-e5-model",
inference_config: {
service: "elasticsearch",
service_settings: {
num_allocations: 1,
num_threads: 1,
model_id: ".multilingual-e5-small",
},
},
});
console.log(response);
----

View File

@ -1,13 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.putIndexTemplate({
name: "my-data-stream-template",
index_patterns: ["my-data-stream*"],
data_stream: {},
priority: 500,
});
console.log(response);
----

View File

@ -0,0 +1,15 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.cluster.putSettings({
body: {
transient: {
'cluster.routing.use_adaptive_replica_selection': false
}
}
})
console.log(response)
----

View File

@ -0,0 +1,18 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.update({
index: 'test',
id: '1',
body: {
doc: {
name: 'new_name'
},
detect_noop: false
}
})
console.log(response)
----

View File

@ -1,46 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
index: "retrievers_example",
retriever: {
rrf: {
retrievers: [
{
standard: {
query: {
range: {
year: {
gt: 2023,
},
},
},
},
},
{
standard: {
query: {
term: {
topic: "elastic",
},
},
},
},
],
rank_window_size: 10,
rank_constant: 1,
},
},
_source: false,
aggs: {
topics: {
terms: {
field: "topic",
},
},
},
});
console.log(response);
----

View File

@ -1,24 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
index: "sales",
size: 0,
filter_path: "aggregations",
query: {
term: {
type: "t-shirt",
},
},
aggs: {
avg_price: {
avg: {
field: "price",
},
},
},
});
console.log(response);
----

View File

@ -1,18 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.inference.put({
task_type: "rerank",
inference_id: "my-rerank-model",
inference_config: {
service: "cohere",
service_settings: {
model_id: "rerank-english-v3.0",
api_key: "{{COHERE_API_KEY}}",
},
},
});
console.log(response);
----

View File

@ -1,17 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.updateAliases({
actions: [
{
add: {
index: "logs-*",
alias: "logs",
},
},
],
});
console.log(response);
----

View File

@ -1,26 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.create({
index: "asciifold_example",
settings: {
analysis: {
analyzer: {
standard_asciifolding: {
tokenizer: "standard",
filter: ["my_ascii_folding"],
},
},
filter: {
my_ascii_folding: {
type: "asciifolding",
preserve_original: true,
},
},
},
},
});
console.log(response);
----

View File

@ -1,36 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.create({
index: "idx",
settings: {
index: {
mapping: {
source: {
mode: "synthetic",
},
},
},
},
mappings: {
properties: {
kwd: {
type: "keyword",
ignore_above: 3,
},
},
},
});
console.log(response);
const response1 = await client.index({
index: "idx",
id: 1,
document: {
kwd: ["foo", "foo", "bang", "bar", "baz"],
},
});
console.log(response1);
----

View File

@ -1,37 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.cluster.putComponentTemplate({
name: "component_template1",
template: {
mappings: {
properties: {
"@timestamp": {
type: "date",
},
},
},
},
});
console.log(response);
const response1 = await client.cluster.putComponentTemplate({
name: "runtime_component_template",
template: {
mappings: {
runtime: {
day_of_week: {
type: "keyword",
script: {
source:
"emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))",
},
},
},
},
},
});
console.log(response1);
----

View File

@ -1,10 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.transform.startTransform({
transform_id: "ecommerce_transform",
});
console.log(response);
----

View File

@ -1,12 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.tasks.list({
human: "true",
detailed: "true",
actions: "indices:data/write/bulk",
});
console.log(response);
----

View File

@ -1,17 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
index: "my-index-000001",
aggs: {
"my-agg-name": {
terms: {
field: "my-field",
},
},
},
});
console.log(response);
----

View File

@ -1,10 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.watcher.executeWatch({
id: "my_watch",
});
console.log(response);
----

View File

@ -1,39 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.create({
index: "basque_example",
settings: {
analysis: {
filter: {
basque_stop: {
type: "stop",
stopwords: "_basque_",
},
basque_keywords: {
type: "keyword_marker",
keywords: ["Adibidez"],
},
basque_stemmer: {
type: "stemmer",
language: "basque",
},
},
analyzer: {
rebuilt_basque: {
tokenizer: "standard",
filter: [
"lowercase",
"basque_stop",
"basque_keywords",
"basque_stemmer",
],
},
},
},
},
});
console.log(response);
----

View File

@ -1,10 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.ccr.followStats({
index: "<index>",
});
console.log(response);
----

View File

@ -1,20 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
query: {
has_child: {
type: "child",
query: {
match_all: {},
},
max_children: 10,
min_children: 2,
score_mode: "min",
},
},
});
console.log(response);
----

View File

@ -1,19 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.putMapping({
index: "my-index-000001",
properties: {
name: {
properties: {
last: {
type: "text",
},
},
},
},
});
console.log(response);
----

View File

@ -1,28 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.create({
index: "sales",
mappings: {
properties: {
tags: {
type: "keyword",
},
comments: {
type: "nested",
properties: {
username: {
type: "keyword",
},
comment: {
type: "text",
},
},
},
},
},
});
console.log(response);
----

View File

@ -1,11 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.ml.flushJob({
job_id: "low_request_rate",
calc_interim: true,
});
console.log(response);
----

View File

@ -0,0 +1,14 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
index: 'twitter',
size: '0',
q: 'extra:test',
filter_path: 'hits.total'
})
console.log(response)
----

View File

@ -1,23 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
aggs: {
JapaneseCars: {
terms: {
field: "make",
include: ["mazda", "honda"],
},
},
ActiveCarManufacturers: {
terms: {
field: "make",
exclude: ["rover", "jensen"],
},
},
},
});
console.log(response);
----

View File

@ -1,10 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.security.invalidateToken({
username: "myuser",
});
console.log(response);
----

View File

@ -1,28 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.analyze({
tokenizer: "keyword",
char_filter: [
{
type: "mapping",
mappings: [
"٠ => 0",
"١ => 1",
"٢ => 2",
"٣ => 3",
"٤ => 4",
"٥ => 5",
"٦ => 6",
"٧ => 7",
"٨ => 8",
"٩ => 9",
],
},
],
text: "My license plate is ٢٥٠١٥",
});
console.log(response);
----

View File

@ -0,0 +1,43 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
body: {
aggs: {
countries: {
terms: {
field: 'artist.country',
order: [
{
'rock>playback_stats.avg': 'desc'
},
{
_count: 'desc'
}
]
},
aggs: {
rock: {
filter: {
term: {
genre: 'rock'
}
},
aggs: {
playback_stats: {
stats: {
field: 'play_count'
}
}
}
}
}
}
}
}
})
console.log(response)
----

View File

@ -1,21 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.create({
index: "my-index-000001",
mappings: {
properties: {
full_name: {
type: "text",
index_prefixes: {
min_chars: 1,
max_chars: 10,
},
},
},
},
});
console.log(response);
----

View File

@ -1,16 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
index: "my-index-000001",
routing: "user1,user2",
query: {
match: {
title: "document",
},
},
});
console.log(response);
----

View File

@ -1,10 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
index: "my-data-stream",
});
console.log(response);
----

View File

@ -1,24 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.ingest.putPipeline({
id: "pipelineB",
description: "outer pipeline",
processors: [
{
pipeline: {
name: "pipelineA",
},
},
{
set: {
field: "outer_pipeline_set",
value: "outer",
},
},
],
});
console.log(response);
----

View File

@ -1,10 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.getTemplate({
name: "template_1",
});
console.log(response);
----

View File

@ -1,38 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.create({
index: "my-index-000001",
mappings: {
properties: {
my_wildcard: {
type: "wildcard",
},
},
},
});
console.log(response);
const response1 = await client.index({
index: "my-index-000001",
id: 1,
document: {
my_wildcard: "This string can be quite lengthy",
},
});
console.log(response1);
const response2 = await client.search({
index: "my-index-000001",
query: {
wildcard: {
my_wildcard: {
value: "*quite*lengthy",
},
},
},
});
console.log(response2);
----

View File

@ -1,12 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.get({
index: "my-index-000001",
id: 0,
_source: "*.id",
});
console.log(response);
----

View File

@ -1,10 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.refresh({
index: "my-index-000001,my-index-000002",
});
console.log(response);
----

View File

@ -0,0 +1,22 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
body: {
aggs: {
genres: {
terms: {
script: {
source: "doc['genre'].value",
lang: 'painless'
}
}
}
}
}
})
console.log(response)
----

View File

@ -1,26 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.index({
index: "example",
document: {
location: {
type: "Polygon",
orientation: "LEFT",
coordinates: [
[
[-177, 10],
[176, 15],
[172, 0],
[176, -15],
[-177, -10],
[-177, 10],
],
],
},
},
});
console.log(response);
----

View File

@ -1,36 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.index({
index: "my-index-000001",
id: 5,
refresh: "true",
document: {
query: {
bool: {
should: [
{
match: {
message: {
query: "Japanese art",
_name: "query1",
},
},
},
{
match: {
message: {
query: "Holand culture",
_name: "query2",
},
},
},
],
},
},
},
});
console.log(response);
----

View File

@ -1,38 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
index: "example-index",
retriever: {
rrf: {
retrievers: [
{
standard: {
query: {
term: {
text: "blue shoes sale",
},
},
},
},
{
standard: {
query: {
sparse_vector: {
field: "ml.tokens",
inference_id: "my_elser_model",
query: "What blue shoes are on sale?",
},
},
},
},
],
rank_window_size: 50,
rank_constant: 20,
},
},
});
console.log(response);
----

View File

@ -1,29 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.create({
index: "my-index-000001",
settings: {
analysis: {
analyzer: {
my_custom_analyzer: {
type: "custom",
tokenizer: "standard",
char_filter: ["html_strip"],
filter: ["lowercase", "asciifolding"],
},
},
},
},
});
console.log(response);
const response1 = await client.indices.analyze({
index: "my-index-000001",
analyzer: "my_custom_analyzer",
text: "Is this déjà vu</b>?",
});
console.log(response1);
----

View File

@ -1,11 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.indices.analyze({
analyzer: "whitespace",
text: "The quick brown fox.",
});
console.log(response);
----

View File

@ -1,8 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.security.getServiceAccounts();
console.log(response);
----

View File

@ -1,14 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.snapshot.restore({
repository: "my_repository",
snapshot: "my_snapshot_2099.05.06",
indices: "my-index,logs-my_app-default",
rename_pattern: "(.+)",
rename_replacement: "restored-$1",
});
console.log(response);
----

View File

@ -1,11 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.sql.query({
format: "txt",
query: "SELECT * FROM library ORDER BY page_count DESC LIMIT 5",
});
console.log(response);
----

View File

@ -1,12 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.connector.updateApiKeyId({
connector_id: "my-connector",
api_key_id: "my-api-key-id",
api_key_secret_id: "my-connector-secret-id",
});
console.log(response);
----

View File

@ -1,12 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.eql.search({
index: "my-data-stream",
query: '\n process where process.name == "regsvr32.exe"\n ',
size: 50,
});
console.log(response);
----

View File

@ -1,52 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.search({
index: "my-index",
retriever: {
rrf: {
retrievers: [
{
standard: {
query: {
multi_match: {
query: "How is the weather in Jamaica?",
fields: ["title", "description"],
},
},
},
},
{
standard: {
query: {
text_expansion: {
"ml.inference.title_expanded.predicted_value": {
model_id: ".elser_model_2",
model_text: "How is the weather in Jamaica?",
},
},
},
},
},
{
standard: {
query: {
text_expansion: {
"ml.inference.description_expanded.predicted_value": {
model_id: ".elser_model_2",
model_text: "How is the weather in Jamaica?",
},
},
},
},
},
],
window_size: 10,
rank_constant: 20,
},
},
});
console.log(response);
----

View File

@ -1,27 +0,0 @@
// This file is autogenerated, DO NOT EDIT
// Use `node scripts/generate-docs-examples.js` to generate the docs examples
[source, js]
----
const response = await client.transport.request({
method: "PUT",
path: "/_internal/desired_nodes/&lt;history_id&gt;/&lt;version&gt;",
body: {
nodes: [
{
settings: {
"node.name": "instance-000187",
"node.external_id": "instance-000187",
"node.roles": ["data_hot", "master"],
"node.attr.data": "hot",
"node.attr.logical_availability_zone": "zone-0",
},
processors: 8,
memory: "58gb",
storage: "2tb",
},
],
},
});
console.log(response);
----

View File

@ -4,14 +4,20 @@
[source, js]
----
const response = await client.search({
query: {
multi_match: {
query: "Will Smith",
type: "cross_fields",
fields: ["first_name", "last_name"],
operator: "and",
},
},
});
console.log(response);
body: {
query: {
multi_match: {
query: 'Will Smith',
type: 'cross_fields',
fields: [
'first_name',
'last_name'
],
operator: 'and'
}
}
}
})
console.log(response)
----

Some files were not shown because too many files have changed in this diff Show More