packages feed

bloodhound-1.0.0.0: src/Database/Bloodhound/ElasticSearch8/Client.hs

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}

-- |
-- Module      : Database.Bloodhound.ElasticSearch8.Client
-- Description : Elasticsearch 8 client (re-exports Common + ES8-specific APIs)
--
-- The Elasticsearch 8 client. Re-exports the version-agnostic "Database.Bloodhound.Common.Client"
-- surface and adds ES8-specific features: k-NN search, point in time (PIT), ES|QL
-- and EQL (sync and async, plus ES|QL views), data streams and lifecycles, query
-- rulesets, search applications, inference endpoints, and the terms enum API.
module Database.Bloodhound.ElasticSearch8.Client
  ( module Reexport,
    esql,
    esqlWith,
    eqlSearch,
    eqlSearchWith,
    getEQLSearch,
    getEQLStatus,
    deleteEQLSearch,
    esqlAsync,
    esqlAsyncWith,
    getAsyncESQL,
    getAsyncESQLWith,
    deleteAsyncESQL,
    stopAsyncESQL,
    getDataStreams,
    getDataStreamStats,
    createDataStream,
    dataStreamExists,
    deleteDataStream,
    migrateToDataStream,
    promoteDataStream,
    putDataStreamLifecycle,
    putDataStreamsLifecycle,
    getDataStreamLifecycle,
    deleteDataStreamLifecycle,
    modifyDataStream,
    getDataStreamOptions,
    updateDataStreamOptions,
    deleteDataStreamOptions,
    getDataStreamLifecycleStats,
    explainDataStreamLifecycle,
    explainDataStreamLifecycleWith,
    ExplainDataStreamLifecycleOptions (..),
    defaultExplainDataStreamLifecycleOptions,
    knnSearch,
    pitSearch,
    pitSearchWith,
    openPointInTime,
    openPointInTimeWith,
    openPointInTimeWithBody,
    closePointInTime,
    putInferenceEndpoint,
    putInferenceEndpointWith,
    updateInferenceEndpoint,
    getInferenceEndpoints,
    deleteInferenceEndpoint,
    deleteInferenceEndpointWith,
    runInference,
    runInferenceWith,
    streamCompletionInference,
    streamCompletionInferenceWith,
    streamChatCompletionInference,
    streamChatCompletionInferenceWith,
    putQueryRuleset,
    getQueryRuleset,
    deleteQueryRuleset,
    testQueryRuleset,
    putSearchApplication,
    putSearchApplicationWith,
    getSearchApplication,
    deleteSearchApplication,
    searchApplication,
    searchApplicationWith,
    listSearchApplications,
    listSearchApplicationsWith,
    renderSearchApplicationQuery,
    putSynonymsSet,
    getSynonymsSet,
    getSynonymsSetWith,
    deleteSynonymsSet,
    getAnalyticsCollections,
    putAnalyticsCollection,
    deleteAnalyticsCollection,
    postAnalyticsEvent,
    postAnalyticsEventWith,
    createConnector,
    putConnector,
    getConnector,
    deleteConnector,
    deleteConnectorWith,
    listConnectors,
    listConnectorsWith,
    checkInConnector,
    updateConnectorApiKeyId,
    updateConnectorConfiguration,
    updateConnectorError,
    updateConnectorFeatures,
    updateConnectorFiltering,
    updateConnectorDraftFilteringValidation,
    activateConnectorDraftFiltering,
    updateConnectorIndexName,
    updateConnectorNameDescription,
    updateConnectorNative,
    updateConnectorPipeline,
    updateConnectorScheduling,
    updateConnectorServiceType,
    updateConnectorStatus,
    createConnectorSyncJob,
    getConnectorSyncJob,
    listConnectorSyncJobs,
    listConnectorSyncJobsWith,
    deleteConnectorSyncJob,
    cancelConnectorSyncJob,
    checkInConnectorSyncJob,
    claimConnectorSyncJob,
    setConnectorSyncJobError,
    setConnectorSyncJobStats,
    migrateReindex,
    cancelMigrateReindex,
    getMigrateReindexStatus,
    createIndexFrom,
    createIndexFromWith,
    MigrateReindexMode (..),
    MigrateReindexSource (..),
    MigrateReindexRequest (..),
    mkMigrateReindexRequest,
    MigrateReindexInProgress (..),
    MigrateReindexError (..),
    MigrateReindexStatus (..),
    CreateIndexFromBody (..),
    defaultCreateIndexFromBody,
    CreateIndexFromResponse (..),
    getTermsEnum,
    getTermsEnumWith,
    TermValue (..),
    TermsEnumRequest (..),
    defaultTermsEnumRequest,
    TermsEnumOptions (..),
    defaultTermsEnumOptions,
    termsEnumOptionsParams,
    TermsEnumResponse (..),
  )
where

import Control.Monad
import Data.Aeson
import Data.ByteString.Lazy qualified as L
import Data.List.NonEmpty (NonEmpty)
import Data.Text (Text)
import Database.Bloodhound.Client.Cluster
import Database.Bloodhound.Common.Client as Reexport
import Database.Bloodhound.Common.Requests as Requests
import Database.Bloodhound.ElasticSearch7.Requests qualified as Requests7
import Database.Bloodhound.ElasticSearch7.Types
import Database.Bloodhound.ElasticSearch8.Requests qualified as Requests8
import Database.Bloodhound.ElasticSearch8.Types
import Database.Bloodhound.Internal.Utils.Requests
import Prelude hiding (filter, head)

-- | 'pitSearch' uses the point in time (PIT) API of elastic, for a given
-- 'IndexName'. Requires Elasticsearch >=7.10. The supplied 'KeepAlive'
-- duration is forwarded to every PIT open\/extend call. Note that this will
-- consume the entire search result set and will be doing O(n) list appends so
-- this may not be suitable for large result sets. In that case, the point in
-- time API should be used directly with `openPointInTime` and `closePointInTime`.
--
-- This is a convenience wrapper around 'pitSearchWith' that lifts the
-- single 'IndexName' into an 'IndexPattern'. To search across multiple
-- comma-joined indices or a wildcard pattern, use 'pitSearchWith'
-- directly with an 'IndexPattern'.
--
-- Note that 'pitSearch' utilizes the 'search_after' parameter under the hood,
-- which requires a non-empty 'sortBody' field in the provided 'Search' value.
-- Otherwise, 'pitSearch' will fail to return all matching documents.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/point-in-time-api.html>.
pitSearch ::
  forall a m.
  (FromJSON a, MonadBH m, WithBackend ElasticSearch8 m) =>
  IndexName ->
  KeepAlive ->
  Search ->
  m [Hit a]
pitSearch indexName = pitSearchWith (IndexPattern (unIndexName indexName))

-- | 'pitSearchWith' is the parameterized variant of 'pitSearch': it
-- takes an 'IndexPattern' as the target, which may be a single index
-- name, a comma-separated list of indices, or a wildcard pattern
-- (e.g. @\"logs-*\"@, @\"logs-2024,logs-2025\"@). Otherwise behaves
-- exactly like 'pitSearch'. See 'openPointInTimeWith' for the target
-- rendering.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/point-in-time-api.html>.
pitSearchWith ::
  forall a m.
  (FromJSON a, MonadBH m, WithBackend ElasticSearch8 m) =>
  IndexPattern ->
  KeepAlive ->
  Search ->
  m [Hit a]
pitSearchWith indexPattern keepAlive search = do
  openResp <- openPointInTimeWith indexPattern keepAlive defaultPITOptions
  case openResp of
    Left e -> throwEsError e
    Right OpenPointInTimeResponse {..} -> do
      let searchPIT = search {pointInTime = Just (PointInTime oPitId (Just keepAlive))}
      hits <- pitAccumulator searchPIT []
      closeResp <- closePointInTime (ClosePointInTime oPitId)
      case closeResp of
        Left _ -> return []
        Right (ClosePointInTimeResponse False _) ->
          error "failed to close point in time (PIT)"
        Right (ClosePointInTimeResponse True _) -> return hits
  where
    pitAccumulator :: Search -> [Hit a] -> m [Hit a]
    pitAccumulator search' oldHits = do
      resp <- tryPerformBHRequest $ Requests.searchAll search'
      case resp of
        Left _ -> return []
        Right searchResult -> case hits (searchHits searchResult) of
          [] -> return oldHits
          newHits -> case (hitSort $ last newHits, pitId searchResult) of
            (Nothing, Nothing) ->
              error "no point in time (PIT) ID or last sort value"
            (Just _, Nothing) -> error "no point in time (PIT) ID"
            (Nothing, _) -> return (oldHits <> newHits)
            (Just lastSort, Just pitId') -> do
              let newSearch =
                    search'
                      { pointInTime = Just (PointInTime pitId' (Just keepAlive)),
                        searchAfterKey = Just lastSort
                      }
              pitAccumulator newSearch (oldHits <> newHits)

-- | 'openPointInTime' opens a point in time for an index given an 'IndexName'
-- and a 'KeepAlive' duration (e.g. @keepAliveMinutes 1@). Note that the point
-- in time should be closed with 'closePointInTime' as soon as it is no longer
-- needed.
--
-- Equivalent to 'openPointInTimeWith' with
-- 'Database.Bloodhound.Internal.Versions.Common.Types.PointInTime.defaultPITOptions'
-- (no optional URI parameters).
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/point-in-time-api.html>.
openPointInTime ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  IndexName ->
  KeepAlive ->
  m (ParsedEsResponse OpenPointInTimeResponse)
openPointInTime indexName keepAlive = performBHRequest $ Requests7.openPointInTime indexName keepAlive

-- | 'openPointInTimeWith' is the parameterized variant of
-- 'openPointInTime': it takes an 'IndexPattern' target (single name,
-- comma-list, or wildcard) and forwards the supplied 'PITOptions' as
-- query-string parameters in addition to the mandatory @keep_alive@.
-- Delegates to the ES7 request builder because the wire format is
-- identical across ES 7.x, 8.x and 9.x. See
-- 'Database.Bloodhound.ElasticSearch7.Requests.openPointInTimeWith'
-- for which parameters are emitted.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/point-in-time-api.html>.
openPointInTimeWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  IndexPattern ->
  KeepAlive ->
  PITOptions ->
  m (ParsedEsResponse OpenPointInTimeResponse)
openPointInTimeWith indexPattern keepAlive opts =
  performBHRequest $ Requests7.openPointInTimeWith indexPattern keepAlive opts

-- | 'openPointInTimeWithBody' is the body-carrying variant of
-- 'openPointInTimeWith': it sends the supplied 'OpenPointInTimeBody' as
-- the JSON request body (the only way to supply an @index_filter@
-- query), in addition to the 'PITOptions' URI parameters and the
-- mandatory @keep_alive@. The 'IndexPattern' target follows the same
-- rules as 'openPointInTimeWith'. Delegates to the ES7 request builder
-- because the wire format is identical across ES 7.x, 8.x and 9.x. See
-- 'Database.Bloodhound.ElasticSearch7.Requests.openPointInTimeWithBody'.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/point-in-time-api.html>.
openPointInTimeWithBody ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  IndexPattern ->
  KeepAlive ->
  OpenPointInTimeBody ->
  PITOptions ->
  m (ParsedEsResponse OpenPointInTimeResponse)
openPointInTimeWithBody indexPattern keepAlive body opts =
  performBHRequest $ Requests7.openPointInTimeWithBody indexPattern keepAlive body opts

-- | 'closePointInTime' closes a point in time given a 'ClosePointInTime'.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/point-in-time-api.html>.
closePointInTime ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ClosePointInTime ->
  m (ParsedEsResponse ClosePointInTimeResponse)
closePointInTime q = performBHRequest $ Requests7.closePointInTime q

-- | knnSearch executes a k-NN vector search request for Elasticsearch 8+.
--
-- In ES8 the standalone @\/{index}\/_knn_search@ endpoint no longer exists:
-- kNN is a top-level @\"knn\"@ clause inside a standard
-- @POST \/{index}\/_search@ body. This function injects the supplied
-- 'KnnQuery' as a single-element @\"knn\"@ array on the body of the given
-- 'Search' and POSTs it to @\/{index}\/_search@.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/knn-search.html>.
knnSearch ::
  (FromJSON a) =>
  IndexName ->
  KnnQuery ->
  Search ->
  BHRequest StatusDependant (SearchResult a)
knnSearch indexName knnQuery search =
  post @StatusDependant endpoint (encode searchWithKnn)
  where
    endpoint = mkEndpoint [unIndexName indexName, "_search"]
    searchWithKnn = search {knnBody = Just [knnQuery]}

-- | 'esql' executes an ES|QL query synchronously via @POST /_query@
-- (Elasticsearch 8.11+). The result is returned as an 'ESQLResult' containing
-- column descriptors and row values.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/esql-rest.html>.
esql ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ESQLRequest ->
  m (ParsedEsResponse ESQLResult)
esql = performBHRequest . Requests8.esql

-- | 'esqlWith' executes an ES|QL query synchronously via @POST /_query@
-- (Elasticsearch 8.11+) with the documented URI query parameters
-- ('ESQLQueryOptions'). Pass 'defaultESQLQueryOptions' to behave
-- identically to 'esql'.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/esql-rest.html>.
esqlWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ESQLRequest ->
  ESQLQueryOptions ->
  m (ParsedEsResponse ESQLResult)
esqlWith req = performBHRequest . Requests8.esqlWith req

-- | 'esqlAsync' submits a long-running ES|QL query via @POST /_query/async@
-- (Elasticsearch 8.11+). The 'AsyncESQLRequest' carries both the base
-- query and the async-only body parameters (@wait_for_completion_timeout@,
-- @keep_alive@, @keep_on_completion@, ...). Construct one with
-- 'mkAsyncESQLRequest' from a plain 'ESQLRequest', then populate the
-- async fields via their lenses. Poll the returned id with 'getAsyncESQL'.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/esql-async.html>.
esqlAsync ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  AsyncESQLRequest ->
  m (ParsedEsResponse AsyncESQLResult)
esqlAsync = performBHRequest . Requests8.esqlAsync

-- | 'esqlAsyncWith' submits a long-running ES|QL query via
-- @POST /_query/async@ (Elasticsearch 8.11+) with the documented URI
-- query parameters ('ESQLQueryOptions') — the same parameter surface as
-- the synchronous 'esqlWith', minus @format@. The body is built as for
-- 'esqlAsync'. Pass 'defaultESQLQueryOptions' to behave identically to
-- 'esqlAsync'.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/esql-async.html>.
esqlAsyncWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  AsyncESQLRequest ->
  ESQLQueryOptions ->
  m (ParsedEsResponse AsyncESQLResult)
esqlAsyncWith req = performBHRequest . Requests8.esqlAsyncWith req

-- | 'getAsyncESQL' polls an async ES|QL query by id, returning its current
-- state and (partial or final) results. Maps to
-- @GET /_query/async/{id}@. The optional 'Text' sets
-- @wait_for_completion_timeout@ as a duration-string query parameter
-- (e.g. @"5s"@).
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/esql-async.html>.
getAsyncESQL ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  AsyncESQLId ->
  Maybe Text ->
  m (ParsedEsResponse AsyncESQLResult)
getAsyncESQL = (performBHRequest .) . Requests8.getAsyncESQL

-- | 'getAsyncESQLWith' is the fully-parameterised form of 'getAsyncESQL',
-- exposing every URI parameter accepted by @GET /_query/async/{id}@ via
-- 'GetAsyncESQLOptions' (@wait_for_completion_timeout@, @keep_alive@,
-- @drop_null_columns@). Pass 'defaultGetAsyncESQLOptions' to reproduce
-- the behaviour of @'getAsyncESQL' id 'Nothing'@.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/esql-async.html>.
getAsyncESQLWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  AsyncESQLId ->
  GetAsyncESQLOptions ->
  m (ParsedEsResponse AsyncESQLResult)
getAsyncESQLWith = (performBHRequest .) . Requests8.getAsyncESQLWith

-- | 'deleteAsyncESQL' deletes an async ES|QL result and its context by id.
-- Maps to @DELETE /_query/async/{id}@ and returns 'Acknowledged' on success.
-- Deleting a non-existent or already-purged async id surfaces as an
-- 'EsError' (a @404@ with an error body); wrap with 'tryEsError' for
-- miss-tolerant deletion.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/esql-async.html>.
deleteAsyncESQL ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  AsyncESQLId ->
  m Acknowledged
deleteAsyncESQL = performBHRequest . Requests8.deleteAsyncESQL

-- | 'stopAsyncESQL' requests the server to stop a running async ES|QL
-- query by id. Maps to @POST /_query/async/{id}/stop@ (Elasticsearch
-- 8.11+) and returns the final 'AsyncESQLResult' — @is_running@ will be
-- @False@ and @columns@\/@values@ carry whatever the query produced
-- before being stopped.
--
-- For more information see
-- <https://www.elastic.co/docs/reference/elasticsearch/rest-apis/esql-async-api>.
stopAsyncESQL ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  AsyncESQLId ->
  m (ParsedEsResponse AsyncESQLResult)
stopAsyncESQL = performBHRequest . Requests8.stopAsyncESQL

-- | 'putInferenceEndpoint' creates or updates an inference endpoint via
-- @PUT \/_inference\/{task_type}\/{inference_id}@ (Elasticsearch 8.12+).
-- The 'InferenceProvider' inside the 'InferenceConfig' selects the backing
-- service (OpenAI, Cohere, ELSER, or a generic provider).
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/inference-apis.html>.
putInferenceEndpoint ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  TaskType ->
  InferenceId ->
  InferenceConfig ->
  m (ParsedEsResponse InferencePutResponse)
putInferenceEndpoint taskType' inferenceId config =
  performBHRequest $ Requests8.putInferenceEndpoint taskType' inferenceId config

-- | Fully-parameterised form of 'putInferenceEndpoint'. Pass
-- 'PutInferenceOptions' to attach the @timeout@ query parameter; see
-- 'Requests.putInferenceEndpointWith'.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/inference-apis.html>.
putInferenceEndpointWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  TaskType ->
  InferenceId ->
  InferenceConfig ->
  PutInferenceOptions ->
  m (ParsedEsResponse InferencePutResponse)
putInferenceEndpointWith taskType' inferenceId config opts =
  performBHRequest $ Requests8.putInferenceEndpointWith taskType' inferenceId config opts

-- | 'updateInferenceEndpoint' partially updates an existing inference
-- endpoint via @PUT \/_inference\/{task_type}\/{inference_id}\/_update@
-- (Elasticsearch 8.12+). Unlike 'putInferenceEndpoint', omitted fields in
-- the 'InferenceConfig' are left unchanged rather than replaced. The
-- updated endpoint is returned as an 'InferenceInfo'.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-inference-update>.
updateInferenceEndpoint ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  TaskType ->
  InferenceId ->
  InferenceConfig ->
  m (ParsedEsResponse InferenceInfo)
updateInferenceEndpoint taskType' inferenceId config =
  performBHRequest $ Requests8.updateInferenceEndpoint taskType' inferenceId config

-- | 'getInferenceEndpoints' lists configured inference endpoints via the
-- @GET \/_inference@ family (Elasticsearch 8.12+). Both filters are
-- optional:
--
-- * @'Nothing'@  task type  → list every endpoint;
-- * @'Just' tt@, no id      → list endpoints of the given task type;
-- * @'Just' tt@, @'Just' iid@ → fetch a single endpoint.
--
-- Passing @'Just' iid@ without a task type is not a valid Elasticsearch
-- URL; the builder falls back to listing every endpoint in that case.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/get-inference-api.html>.
getInferenceEndpoints ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe TaskType ->
  Maybe InferenceId ->
  m [InferenceInfo]
getInferenceEndpoints mTaskType mInferenceId =
  performBHRequest $ Requests8.getInferenceEndpoints mTaskType mInferenceId

-- | 'deleteInferenceEndpoint' deletes an inference endpoint via
-- @DELETE \/_inference\/{task_type}\/{inference_id}@ (Elasticsearch 8.12+).
-- Deleting a non-existent endpoint surfaces as an 'EsError' (the underlying
-- request builder is 'StatusDependant'); wrap with 'tryPerformBHRequest' for
-- miss-tolerant deletion.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/delete-inference-api.html>.
deleteInferenceEndpoint ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  TaskType ->
  InferenceId ->
  m Acknowledged
deleteInferenceEndpoint taskType' inferenceId =
  performBHRequest $ Requests8.deleteInferenceEndpoint taskType' inferenceId

-- | Fully-parameterised form of 'deleteInferenceEndpoint'. Pass
-- 'DeleteInferenceOptions' to attach the @dry_run@ and @force@ query
-- parameters; see 'Requests.deleteInferenceEndpointWith'.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/delete-inference-api.html>.
deleteInferenceEndpointWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  TaskType ->
  InferenceId ->
  DeleteInferenceOptions ->
  m Acknowledged
deleteInferenceEndpointWith taskType' inferenceId opts =
  performBHRequest $ Requests8.deleteInferenceEndpointWith taskType' inferenceId opts

-- | 'runInference' performs inference against an existing endpoint via
-- @POST \/_inference\/{task_type}\/{inference_id}@ (Elasticsearch 8.12+).
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/inference-apis.html>.
runInference ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  TaskType ->
  InferenceId ->
  InferenceInput ->
  m (ParsedEsResponse InferenceResult)
runInference taskType' inferenceId input =
  performBHRequest $ Requests8.runInference taskType' inferenceId input

-- | Fully-parameterised form of 'runInference'. Pass 'RunInferenceOptions'
-- to attach the @timeout@ query parameter; see 'Requests.runInferenceWith'.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/inference-apis.html>.
runInferenceWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  TaskType ->
  InferenceId ->
  InferenceInput ->
  RunInferenceOptions ->
  m (ParsedEsResponse InferenceResult)
runInferenceWith taskType' inferenceId input opts =
  performBHRequest $ Requests8.runInferenceWith taskType' inferenceId input opts

-- | 'streamCompletionInference' streams completion chunks from an existing
-- completion endpoint via
-- @POST \/_inference\/completion\/{inference_id}\/_stream@ (Elasticsearch
-- 8.12+). The full buffered NDJSON stream is returned as a lazy
-- 'L.ByteString'; callers split it into newline-delimited JSON chunks and
-- decode each.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-inference-stream-completion>.
streamCompletionInference ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  InferenceId ->
  InferenceInput ->
  m L.ByteString
streamCompletionInference inferenceId input =
  performBHRequest $ Requests8.streamCompletionInference inferenceId input

-- | Fully-parameterised form of 'streamCompletionInference'. Pass
-- 'StreamCompletionInferenceOptions' to attach the @timeout@ query
-- parameter; see 'Requests.streamCompletionInferenceWith'.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-inference-stream-completion>.
streamCompletionInferenceWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  InferenceId ->
  InferenceInput ->
  StreamCompletionInferenceOptions ->
  m L.ByteString
streamCompletionInferenceWith inferenceId input opts =
  performBHRequest $ Requests8.streamCompletionInferenceWith inferenceId input opts

-- | 'streamChatCompletionInference' streams chat-completion chunks from an
-- existing chat endpoint via
-- @POST \/_inference\/chat_completion\/{inference_id}\/_stream@
-- (Elasticsearch 8.18+). The full buffered NDJSON stream is returned as a
-- lazy 'L.ByteString'; callers split it into newline-delimited JSON chunks
-- and decode each.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-inference-chat-completion-unified>.
streamChatCompletionInference ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  InferenceId ->
  ChatCompletionRequest ->
  m L.ByteString
streamChatCompletionInference inferenceId request =
  performBHRequest $ Requests8.streamChatCompletionInference inferenceId request

-- | Fully-parameterised form of 'streamChatCompletionInference'. Pass
-- 'StreamChatCompletionInferenceOptions' to attach the @timeout@ query
-- parameter; see 'Requests.streamChatCompletionInferenceWith'.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-inference-chat-completion-unified>.
streamChatCompletionInferenceWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  InferenceId ->
  ChatCompletionRequest ->
  StreamChatCompletionInferenceOptions ->
  m L.ByteString
streamChatCompletionInferenceWith inferenceId request opts =
  performBHRequest $ Requests8.streamChatCompletionInferenceWith inferenceId request opts

-- | 'putQueryRuleset' creates or updates a query ruleset via
-- @PUT \/_query_rules\/{ruleset_id}@ (Elasticsearch 8.9+). The
-- 'QueryRuleset' body carries an ordered list of 'Rule's; ES
-- evaluates them top-down and applies the actions of the first match.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/put-query-ruleset.html>.
putQueryRuleset ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  RulesetId ->
  QueryRuleset ->
  m QueryRulesetPutResponse
putQueryRuleset rulesetId ruleset =
  performBHRequest $ Requests8.putQueryRuleset rulesetId ruleset

-- | 'getQueryRuleset' fetches a query ruleset by id via
-- @GET \/_query_rules\/{ruleset_id}@ (Elasticsearch 8.9+), returning
-- a 'QueryRulesetInfo' (@ruleset_id@ and @rules@). A @404@ for a
-- missing ruleset surfaces as an 'EsError'; wrap with
-- 'tryPerformBHRequest' for miss-tolerant reads.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/get-query-ruleset.html>.
getQueryRuleset ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  RulesetId ->
  m QueryRulesetInfo
getQueryRuleset = performBHRequest . Requests8.getQueryRuleset

-- | 'deleteQueryRuleset' deletes a query ruleset by id via
-- @DELETE \/_query_rules\/{ruleset_id}@ (Elasticsearch 8.9+).
-- Deleting a non-existent ruleset surfaces as an 'EsError'; wrap with
-- 'tryPerformBHRequest' for miss-tolerant deletion.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/delete-query-ruleset.html>.
deleteQueryRuleset ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  RulesetId ->
  m Acknowledged
deleteQueryRuleset = performBHRequest . Requests8.deleteQueryRuleset

-- | 'testQueryRuleset' evaluates the supplied 'QueryRulesetTest' match
-- criteria against every rule in the stored ruleset via
-- @POST \/_query_rules\/{ruleset_id}\/_test@ (Elasticsearch 8.10+).
-- The server returns a 'QueryRulesetTestResponse' whose
-- 'qrtMatched' field lists the @ruleset_id@\/@rule_id@ pairs that
-- fired. Useful for validating pinned\/exclude rules in development
-- without issuing a real search.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/test-query-ruleset.html>.
testQueryRuleset ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  RulesetId ->
  QueryRulesetTest ->
  m QueryRulesetTestResponse
testQueryRuleset rulesetId body =
  performBHRequest $ Requests8.testQueryRuleset rulesetId body

-- | 'putSearchApplication' creates or updates a search application via
-- @PUT \/_application\/search_application\/{name}@ (Elasticsearch 8.6+).
-- The body declares the target indices and optionally an analytics
-- collection name and\/or a template. The server returns
-- 'SearchApplicationPutResponse', whose @result@ field is @"created"@
-- or @"updated"@.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-application-apis.html>.
putSearchApplication ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  SearchApplicationName ->
  SearchApplication ->
  m SearchApplicationPutResponse
putSearchApplication appName app =
  performBHRequest $ Requests8.putSearchApplication appName app

-- | 'putSearchApplicationWith' is the fully-parameterised form of
-- 'putSearchApplication'. 'SearchApplicationPutOptions' carries the
-- @create@ query parameter: @'Just' 'True'@ emits @?create=true@, which
-- makes the request fail if the search application already exists.
-- Passing 'defaultSearchApplicationPutOptions' is byte-for-byte
-- identical to 'putSearchApplication'.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/v8/operation/operation-search-application-put>.
putSearchApplicationWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  SearchApplicationName ->
  SearchApplicationPutOptions ->
  SearchApplication ->
  m SearchApplicationPutResponse
putSearchApplicationWith appName opts app =
  performBHRequest $ Requests8.putSearchApplicationWith appName opts app

-- | 'getSearchApplication' fetches a search application by name via
-- @GET \/_application\/search_application\/{name}@ (Elasticsearch 8.6+).
-- The response includes the stored body plus the path-echoed @name@ and
-- an optional @updated_at_millis@ timestamp. A @404@ for a missing
-- application surfaces as an 'EsError'; wrap with
-- 'tryPerformBHRequest' for miss-tolerant reads.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-application-apis.html>.
getSearchApplication ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  SearchApplicationName ->
  m SearchApplicationInfo
getSearchApplication = performBHRequest . Requests8.getSearchApplication

-- | 'deleteSearchApplication' deletes a search application by name via
-- @DELETE \/_application\/search_application\/{name}@ (Elasticsearch
-- 8.6+). Deleting a non-existent application surfaces as an 'EsError';
-- wrap with 'tryPerformBHRequest' for miss-tolerant deletion.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-application-apis.html>.
deleteSearchApplication ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  SearchApplicationName ->
  m Acknowledged
deleteSearchApplication = performBHRequest . Requests8.deleteSearchApplication

-- | 'searchApplication' runs a search application's stored template
-- against its indices via
-- @POST \/_application\/search_application\/{name}\/_search@
-- (Elasticsearch 8.6+). The optional 'SearchApplicationSearchParams'
-- carries per-request template parameter overrides; 'Nothing' runs the
-- template with its defaults. The response is a regular 'SearchResult'
-- parameterized by the document-source type @a@.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-application-apis.html>.
searchApplication ::
  (FromJSON a, MonadBH m, WithBackend ElasticSearch8 m) =>
  SearchApplicationName ->
  Maybe SearchApplicationSearchParams ->
  m (ParsedEsResponse (SearchResult a))
searchApplication appName mParams =
  performBHRequest $ Requests8.searchApplication appName mParams

-- | Fully-parameterised form of 'searchApplication'. Pass
-- 'SearchApplicationOptions' to attach the @typed_keys@ query parameter;
-- see 'Requests.searchApplicationWith'.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-application-apis.html>.
searchApplicationWith ::
  (MonadBH m, WithBackend ElasticSearch8 m, FromJSON a) =>
  SearchApplicationName ->
  Maybe SearchApplicationSearchParams ->
  SearchApplicationOptions ->
  m (ParsedEsResponse (SearchResult a))
searchApplicationWith appName mParams opts =
  performBHRequest $ Requests8.searchApplicationWith appName mParams opts

-- | 'listSearchApplications' lists configured search applications via
-- @GET \/_application\/search_application@ (Elasticsearch 8.6+). Returns
-- a 'SearchApplicationListResponse' whose @results@ each reuse the
-- 'SearchApplicationInfo' shape (typically carrying only @name@ and
-- @updated_at_millis@ per item). Use 'listSearchApplicationsWith' to
-- attach the @q@\/@from@\/@size@ query parameters.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/list-search-applications.html>.
listSearchApplications ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  m SearchApplicationListResponse
listSearchApplications =
  performBHRequest Requests8.listSearchApplications

-- | Fully-parameterised form of 'listSearchApplications'. Pass
-- 'SearchApplicationListOptions' to attach the @q@ (Lucene query-string
-- filter), @from@ (offset) and @size@ (max results) query parameters;
-- see 'Requests.listSearchApplicationsWith'.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/list-search-applications.html>.
listSearchApplicationsWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  SearchApplicationListOptions ->
  m SearchApplicationListResponse
listSearchApplicationsWith opts =
  performBHRequest $ Requests8.listSearchApplicationsWith opts

-- | 'renderSearchApplicationQuery' renders a search application's stored
-- template against the supplied parameters and returns the resulting
-- Elasticsearch query body /without/ executing the search, via
-- @POST \/_application\/search_application\/{name}\/_render_query@
-- (Elasticsearch 8.6+). The optional 'SearchApplicationSearchParams'
-- carries per-request template parameter overrides; 'Nothing' renders
-- the template with its defaults. The response is the rendered
-- search-request body as an opaque 'Value'.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-application-render-query.html>.
renderSearchApplicationQuery ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  SearchApplicationName ->
  Maybe SearchApplicationSearchParams ->
  m Value
renderSearchApplicationQuery appName mParams =
  performBHRequest $ Requests8.renderSearchApplicationQuery appName mParams

-- | 'putSynonymsSet' creates or updates a synonyms set via
-- @PUT \/_synonyms\/{synonyms_set_id}@ (Elasticsearch 8.10+). The
-- 'SynonymsSet' body carries an ordered list of 'SynonymRule's.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/put-synonyms-set.html>.
putSynonymsSet ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  SynonymsSetId ->
  SynonymsSet ->
  m SynonymsSetPutResponse
putSynonymsSet setId body =
  performBHRequest $ Requests8.putSynonymsSet setId body

-- | 'getSynonymsSet' fetches a synonyms set by id via
-- @GET \/_synonyms\/{synonyms_set_id}@ (Elasticsearch 8.10+),
-- returning a 'SynonymsSetInfo' (@count@ and the @synonyms_set@
-- rules). Equivalent to @'getSynonymsSetWith' setId
-- 'defaultSynonymsGetOptions'@. A @404@ for a missing set surfaces as
-- an 'EsError'; wrap with 'tryPerformBHRequest' for miss-tolerant
-- reads.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/get-synonyms-set.html>.
getSynonymsSet ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  SynonymsSetId ->
  m SynonymsSetInfo
getSynonymsSet = performBHRequest . Requests8.getSynonymsSet

-- | 'getSynonymsSetWith' is the fully-parameterised variant of
-- 'getSynonymsSet', accepting 'SynonymsGetOptions' (@from@\/@size@).
getSynonymsSetWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  SynonymsSetId ->
  SynonymsGetOptions ->
  m SynonymsSetInfo
getSynonymsSetWith setId opts =
  performBHRequest $ Requests8.getSynonymsSetWith setId opts

-- | 'deleteSynonymsSet' deletes a synonyms set by id via
-- @DELETE \/_synonyms\/{synonyms_set_id}@ (Elasticsearch 8.10+).
-- Deleting a non-existent set surfaces as an 'EsError'; wrap with
-- 'tryPerformBHRequest' for miss-tolerant deletion.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/delete-synonyms-set.html>.
deleteSynonymsSet ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  SynonymsSetId ->
  m Acknowledged
deleteSynonymsSet = performBHRequest . Requests8.deleteSynonymsSet

-- | 'getAnalyticsCollections' lists behavioral analytics collections
-- (Elasticsearch 8.7+). @'Nothing'@ lists every collection;
-- @'Just' name@ fetches a single one. See
-- 'Requests8.getAnalyticsCollections'.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/v8/group/endpoint-analytics>.
getAnalyticsCollections ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe AnalyticsCollectionName ->
  m [AnalyticsCollection]
getAnalyticsCollections =
  performBHRequest . Requests8.getAnalyticsCollections

-- | 'putAnalyticsCollection' creates or replaces a behavioral analytics
-- collection (Elasticsearch 8.7+). See 'Requests8.putAnalyticsCollection'.
putAnalyticsCollection ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  AnalyticsCollectionName ->
  m AnalyticsCollectionPutResponse
putAnalyticsCollection =
  performBHRequest . Requests8.putAnalyticsCollection

-- | 'deleteAnalyticsCollection' deletes a behavioral analytics
-- collection and its backing index (Elasticsearch 8.7+). See
-- 'Requests8.deleteAnalyticsCollection'.
deleteAnalyticsCollection ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  AnalyticsCollectionName ->
  m Acknowledged
deleteAnalyticsCollection =
  performBHRequest . Requests8.deleteAnalyticsCollection

-- | 'postAnalyticsEvent' ingests a single behavioral event
-- (Elasticsearch 8.7+). See 'Requests8.postAnalyticsEvent'.
postAnalyticsEvent ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  AnalyticsCollectionName ->
  AnalyticsEventType ->
  Value ->
  m AnalyticsEventResponse
postAnalyticsEvent coll evType payload =
  performBHRequest $ Requests8.postAnalyticsEvent coll evType payload

-- | 'postAnalyticsEventWith' is the fully-parameterised form of
-- 'postAnalyticsEvent'; pass 'AnalyticsEventOptions' to set @?debug=true@.
postAnalyticsEventWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  AnalyticsEventOptions ->
  AnalyticsCollectionName ->
  AnalyticsEventType ->
  Value ->
  m AnalyticsEventResponse
postAnalyticsEventWith opts coll evType payload =
  performBHRequest $
    Requests8.postAnalyticsEventWith opts coll evType payload

------------------------------------------------------------------------------
-- Connectors (Elasticsearch 8.8+)
------------------------------------------------------------------------------

-- | 'createConnector' creates a connector (@POST /_connector@). See
-- 'Requests8.createConnector'.
createConnector ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  CreateConnectorRequest ->
  m ConnectorCreateResponse
createConnector = performBHRequest . Requests8.createConnector

-- | 'putConnector' creates or fully replaces a connector by id
-- (@PUT /_connector/{id}@).
putConnector ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  CreateConnectorRequest ->
  m ConnectorCreateResponse
putConnector cid = performBHRequest . Requests8.putConnector cid

-- | 'getConnector' fetches a connector by id.
getConnector ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  m Connector
getConnector = performBHRequest . Requests8.getConnector

-- | 'deleteConnector' deletes a connector by id.
deleteConnector ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  m Acknowledged
deleteConnector = performBHRequest . Requests8.deleteConnector

-- | 'deleteConnectorWith' deletes a connector, optionally also deleting
-- its pending sync jobs (@?delete_sync_jobs=true@).
deleteConnectorWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe Bool ->
  ConnectorId ->
  m Acknowledged
deleteConnectorWith mDeleteSyncJobs cid =
  performBHRequest $ Requests8.deleteConnectorWith mDeleteSyncJobs cid

-- | 'listConnectors' lists configured connectors.
listConnectors ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  m ConnectorListResponse
listConnectors = performBHRequest Requests8.listConnectors

-- | 'listConnectorsWith' is the fully-parameterised form of
-- 'listConnectors'.
listConnectorsWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorListOptions ->
  m ConnectorListResponse
listConnectorsWith =
  performBHRequest . Requests8.listConnectorsWith

-- | 'checkInConnector' records a connector heartbeat
-- (@PUT /_connector/{id}/_check_in@).
checkInConnector ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  m ConnectorMutationResult
checkInConnector = performBHRequest . Requests8.checkInConnector

-- | 'updateConnectorApiKeyId' sets the connector API key id + secret id.
updateConnectorApiKeyId ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorApiKeyRequest ->
  m ConnectorMutationResult
updateConnectorApiKeyId cid =
  performBHRequest . Requests8.updateConnectorApiKeyId cid

-- | 'updateConnectorConfiguration' updates the connector configuration.
updateConnectorConfiguration ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorConfigurationRequest ->
  m ConnectorMutationResult
updateConnectorConfiguration cid =
  performBHRequest . Requests8.updateConnectorConfiguration cid

-- | 'updateConnectorError' sets or clears the connector error field.
updateConnectorError ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorErrorRequest ->
  m ConnectorMutationResult
updateConnectorError cid =
  performBHRequest . Requests8.updateConnectorError cid

-- | 'updateConnectorFeatures' overrides connector features.
updateConnectorFeatures ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorFeaturesRequest ->
  m ConnectorMutationResult
updateConnectorFeatures cid =
  performBHRequest . Requests8.updateConnectorFeatures cid

-- | 'updateConnectorFiltering' updates the draft filtering.
updateConnectorFiltering ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorFilteringRequest ->
  m ConnectorMutationResult
updateConnectorFiltering cid =
  performBHRequest . Requests8.updateConnectorFiltering cid

-- | 'updateConnectorDraftFilteringValidation' updates draft filtering
-- validation info.
updateConnectorDraftFilteringValidation ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorFilteringValidationRequest ->
  m ConnectorMutationResult
updateConnectorDraftFilteringValidation cid =
  performBHRequest . Requests8.updateConnectorDraftFilteringValidation cid

-- | 'activateConnectorDraftFiltering' activates the valid draft filter.
activateConnectorDraftFiltering ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  m ConnectorMutationResult
activateConnectorDraftFiltering =
  performBHRequest . Requests8.activateConnectorDraftFiltering

-- | 'updateConnectorIndexName' sets or clears the destination index.
updateConnectorIndexName ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorIndexNameRequest ->
  m ConnectorMutationResult
updateConnectorIndexName cid =
  performBHRequest . Requests8.updateConnectorIndexName cid

-- | 'updateConnectorNameDescription' updates name and description.
updateConnectorNameDescription ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorNameDescriptionRequest ->
  m ConnectorMutationResult
updateConnectorNameDescription cid =
  performBHRequest . Requests8.updateConnectorNameDescription cid

-- | 'updateConnectorNative' toggles the @is_native@ flag.
updateConnectorNative ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorNativeRequest ->
  m ConnectorMutationResult
updateConnectorNative cid =
  performBHRequest . Requests8.updateConnectorNative cid

-- | 'updateConnectorPipeline' updates the ingest pipeline.
updateConnectorPipeline ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorPipelineRequest ->
  m ConnectorMutationResult
updateConnectorPipeline cid =
  performBHRequest . Requests8.updateConnectorPipeline cid

-- | 'updateConnectorScheduling' updates the scheduling.
updateConnectorScheduling ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorSchedulingRequest ->
  m ConnectorMutationResult
updateConnectorScheduling cid =
  performBHRequest . Requests8.updateConnectorScheduling cid

-- | 'updateConnectorServiceType' updates the service type.
updateConnectorServiceType ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorServiceTypeRequest ->
  m ConnectorMutationResult
updateConnectorServiceType cid =
  performBHRequest . Requests8.updateConnectorServiceType cid

-- | 'updateConnectorStatus' updates the status.
updateConnectorStatus ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorId ->
  UpdateConnectorStatusRequest ->
  m ConnectorMutationResult
updateConnectorStatus cid =
  performBHRequest . Requests8.updateConnectorStatus cid

-- | 'createConnectorSyncJob' creates a sync job
-- (@POST /_connector/_sync_job@).
createConnectorSyncJob ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  CreateConnectorSyncJobRequest ->
  m ConnectorSyncJobCreateResponse
createConnectorSyncJob =
  performBHRequest . Requests8.createConnectorSyncJob

-- | 'getConnectorSyncJob' fetches a sync job by id.
getConnectorSyncJob ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorSyncJobId ->
  m ConnectorSyncJob
getConnectorSyncJob =
  performBHRequest . Requests8.getConnectorSyncJob

-- | 'listConnectorSyncJobs' lists sync jobs.
listConnectorSyncJobs ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  m ConnectorSyncJobListResponse
listConnectorSyncJobs =
  performBHRequest Requests8.listConnectorSyncJobs

-- | 'listConnectorSyncJobsWith' is the fully-parameterised form of
-- 'listConnectorSyncJobs'.
listConnectorSyncJobsWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorSyncJobListOptions ->
  m ConnectorSyncJobListResponse
listConnectorSyncJobsWith =
  performBHRequest . Requests8.listConnectorSyncJobsWith

-- | 'deleteConnectorSyncJob' deletes a sync job by id.
deleteConnectorSyncJob ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorSyncJobId ->
  m Acknowledged
deleteConnectorSyncJob =
  performBHRequest . Requests8.deleteConnectorSyncJob

-- | 'cancelConnectorSyncJob' requests cancellation of a sync job.
cancelConnectorSyncJob ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorSyncJobId ->
  m ConnectorMutationResult
cancelConnectorSyncJob =
  performBHRequest . Requests8.cancelConnectorSyncJob

-- | 'checkInConnectorSyncJob' records a sync-job heartbeat. The response
-- is undocumented and returned as an opaque 'Value'.
checkInConnectorSyncJob ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorSyncJobId ->
  m Value
checkInConnectorSyncJob =
  performBHRequest . Requests8.checkInConnectorSyncJob

-- | 'claimConnectorSyncJob' claims a sync job for a worker. The response
-- is undocumented and returned as an opaque 'Value'.
claimConnectorSyncJob ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorSyncJobId ->
  ClaimConnectorSyncJobRequest ->
  m Value
claimConnectorSyncJob jid =
  performBHRequest . Requests8.claimConnectorSyncJob jid

-- | 'setConnectorSyncJobError' sets the error on a sync job. The
-- response is undocumented and returned as an opaque 'Value'.
setConnectorSyncJobError ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorSyncJobId ->
  SetConnectorSyncJobErrorRequest ->
  m Value
setConnectorSyncJobError jid =
  performBHRequest . Requests8.setConnectorSyncJobError jid

-- | 'setConnectorSyncJobStats' updates the per-run counters of a sync
-- job. The response is undocumented and returned as an opaque 'Value'.
setConnectorSyncJobStats ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ConnectorSyncJobId ->
  SetConnectorSyncJobStatsRequest ->
  m Value
setConnectorSyncJobStats jid =
  performBHRequest . Requests8.setConnectorSyncJobStats jid

-- | 'eqlSearch' submits an EQL (Event Query Language) search via
-- @POST /{index}/_eql/search@ (Elasticsearch 8.x). The result is
-- parameterized by the document-source type @a@.
--
-- The wire format is identical to ES 7.10+, so the ES8 request builder
-- delegates to the ES7 implementation.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/eql-search-api.html>.
eqlSearch ::
  (FromJSON a, MonadBH m, WithBackend ElasticSearch8 m) =>
  IndexName ->
  EQLRequest ->
  m (ParsedEsResponse (EQLResult a))
eqlSearch indexName req = performBHRequest $ Requests8.eqlSearch indexName req

-- | 'eqlSearchWith' is the fully-parameterised form of 'eqlSearch'. The
-- wire format is identical to ES 7.10+, so the ES8 request builder
-- delegates to the ES7 implementation. See 'EQLSearchOptions' for the
-- available URI parameters.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/eql-search-api.html>.
eqlSearchWith ::
  (FromJSON a, MonadBH m, WithBackend ElasticSearch8 m) =>
  IndexName ->
  EQLSearchOptions ->
  EQLRequest ->
  m (ParsedEsResponse (EQLResult a))
eqlSearchWith indexName opts req =
  performBHRequest $ Requests8.eqlSearchWith indexName opts req

-- | 'getEQLSearch' fetches the deferred results of an async EQL search
-- via @GET /_eql/search\/{id}@ (Elasticsearch 8.x). The result is
-- parameterized by the document-source type @a@. The optional 'Text'
-- sets @wait_for_completion_timeout@ as a query parameter; 'Nothing'
-- returns immediately with the current state.
--
-- The wire format is identical to ES 7.10+, so the ES8 request builder
-- delegates to the ES7 implementation.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-eql-get>.
getEQLSearch ::
  (FromJSON a, MonadBH m, WithBackend ElasticSearch8 m) =>
  EQLSearchId ->
  Maybe Text ->
  m (ParsedEsResponse (EQLResult a))
getEQLSearch sid = performBHRequest . Requests8.getEQLSearch sid

-- | 'getEQLStatus' returns only the status of an async EQL search via
-- @GET /_eql/search/status\/{id}@ (Elasticsearch 8.x) without fetching
-- the results.
--
-- The wire format is identical to ES 7.10+, so the ES8 request builder
-- delegates to the ES7 implementation.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-eql-get-status>.
getEQLStatus ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  EQLSearchId ->
  m EQLStatus
getEQLStatus = performBHRequest . Requests8.getEQLStatus

-- | 'getDataStreams' lists data streams. The wire format is identical
-- across ES 7.x, 8.x and 9.x, so the ES7 request builder is reused
-- verbatim.
--
-- * @'Nothing'@ or @'Just' []@  → @GET /_data_stream@ returns every data
--   stream on the cluster.
-- * @'Just' names@              → @GET /_data_stream\/{a,b,c}@ returns
--   only the named data streams.
--
-- See
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/data-stream-apis.html#get-data-streams>.
getDataStreams ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe [DataStreamName] ->
  m [DataStreamInfo]
getDataStreams = performBHRequest . Requests7.getDataStreams

-- | 'getDataStreamStats' returns statistics about data streams
-- (document counts, store sizes, shard counts, etc.). The wire format
-- is identical to ES7, so the ES7 request builder is reused verbatim.
--
-- * @'Nothing'@ or @'Just' []@  → @GET /_data_stream/_stats@ returns
--   statistics for every data stream on the cluster.
-- * @'Just' names@              → @GET /_data_stream\/{a,b,c}/_stats@
--   returns statistics for only the named data streams.
--
-- See
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/data-stream-apis.html#get-data-stream-stats>.
getDataStreamStats ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe [DataStreamName] ->
  m DataStreamStats
getDataStreamStats = performBHRequest . Requests7.getDataStreamStats

-- | 'createDataStream' creates a data stream with the given name. The
-- stream's configuration is derived from the matching index template
-- (which must already exist and declare a @data_stream@ object). The
-- wire format is identical to ES7, so the ES7 request builder is reused
-- verbatim.
--
-- See
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/data-stream-apis.html#create-data-stream>.
createDataStream ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  DataStreamName ->
  m Acknowledged
createDataStream = performBHRequest . Requests7.createDataStream

-- | 'dataStreamExists' checks whether a data stream with the given
-- name exists. Returns 'True' if the stream exists, 'False'
-- otherwise (any non-2xx status, including @404@, decodes to
-- 'False'; no 'EsError' is raised). The wire format is identical to
-- ES7, so the ES7 request builder is reused verbatim.
--
-- See
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/data-stream-apis.html>.
dataStreamExists ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  DataStreamName ->
  m Bool
dataStreamExists = performBHRequest . Requests7.dataStreamExists

-- | 'deleteDataStream' deletes a data stream and its backing indices.
-- Deleting a non-existent stream surfaces as an 'EsError'. The wire
-- format is identical to ES7, so the ES7 request builder is reused
-- verbatim.
--
-- See
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/data-stream-apis.html#delete-data-stream>.
deleteDataStream ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  DataStreamName ->
  m Acknowledged
deleteDataStream = performBHRequest . Requests7.deleteDataStream

-- | 'migrateToDataStream' converts an existing alias (whose write index
-- is a hidden or data-stream-compatible backing index) into a data
-- stream. The alias and its write index must already be set up
-- correctly; an ineligible alias surfaces as an 'EsError'. The wire
-- format is identical to ES7, so the ES7 request builder is reused
-- verbatim.
--
-- See
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/data-stream-apis.html#migrate-to-data-stream>.
migrateToDataStream ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  IndexAliasName ->
  m Acknowledged
migrateToDataStream = performBHRequest . Requests7.migrateToDataStream

-- | 'promoteDataStream' promotes a frozen or cloned data stream back to a
-- regular data stream (disaster recovery). A stream that is not
-- currently frozen surfaces as an 'EsError'. The wire format is
-- identical to ES7, so the ES7 request builder is reused verbatim.
--
-- See
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/data-stream-apis.html#promote-data-stream>.
promoteDataStream ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  DataStreamName ->
  m Acknowledged
promoteDataStream = performBHRequest . Requests7.promoteDataStream

-- | 'putDataStreamLifecycle' sets or updates the lifecycle of a data
-- stream (retention, downsampling, enabled toggle). The request
-- builder lives in the ES8 module and is re-exported by the ES9
-- client module.
--
-- See
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/data-stream-lifecycle.html#put-data-stream-lifecycle>.
putDataStreamLifecycle ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  DataStreamName ->
  DataStreamLifecycle ->
  m Acknowledged
putDataStreamLifecycle = (performBHRequest .) . Requests8.putDataStreamLifecycle

-- | 'putDataStreamsLifecycle' sets or updates the lifecycle of
-- multiple data streams in a single bulk request (see
-- 'PutDataStreamsLifecycleRequest'). The request builder lives in
-- the ES8 module and is re-exported by the ES9 client module.
--
-- See
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/data-stream-lifecycle.html#put-data-streams-lifecycle>.
putDataStreamsLifecycle ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  PutDataStreamsLifecycleRequest ->
  m Acknowledged
putDataStreamsLifecycle = performBHRequest . Requests8.putDataStreamsLifecycle

-- | 'getDataStreamLifecycle' retrieves the lifecycle configuration of
-- one or more data streams. The request builder lives in the ES8
-- module and is re-exported by the ES9 client module.
--
-- * @'Nothing'@ or @'Just' []@  → @GET /_data_stream/_lifecycle@
--   returns the lifecycle of every data stream on the cluster.
-- * @'Just' names@              → @GET /_data_stream\/{a,b,c}/_lifecycle@
--   returns only the lifecycles of the named data streams.
--
-- Streams that are not managed by a lifecycle appear with their
-- @lifecycle@ field decoded as 'Nothing'.
--
-- See
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/data-stream-lifecycle.html#get-data-stream-lifecycle>.
getDataStreamLifecycle ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe [DataStreamName] ->
  m GetDataStreamLifecyclesResponse
getDataStreamLifecycle = performBHRequest . Requests8.getDataStreamLifecycle

-- | 'deleteDataStreamLifecycle' removes the lifecycle configuration
-- from a data stream, rendering it unmanaged by the data stream
-- lifecycle. The request builder lives in the ES8 module and is
-- re-exported by the ES9 client module.
--
-- See
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/data-stream-lifecycle.html#delete-data-stream-lifecycle>.
deleteDataStreamLifecycle ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  DataStreamName ->
  m Acknowledged
deleteDataStreamLifecycle = performBHRequest . Requests8.deleteDataStreamLifecycle

-- | 'modifyDataStream' changes the backing indices of one or more data
-- streams (batched add\/remove backing index). Referencing a
-- non-existent stream or an ineligible index surfaces as an 'EsError'.
-- The wire format is identical to ES7, so the ES7 request builder is
-- reused verbatim.
--
-- See
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/data-stream-apis.html#modify-data-stream>.
modifyDataStream ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  ModifyDataStreamRequest ->
  m Acknowledged
modifyDataStream = performBHRequest . Requests7.modifyDataStream

-- | 'getDataStreamOptions' retrieves the options (e.g. failure store
-- configuration) of one or more data streams. Requires
-- Elasticsearch >= 8.19. The request builder lives in the ES8 module
-- and is re-exported by the ES9 client module.
--
-- * @'Nothing'@ or @'Just' []@  → @GET /_data_stream/_options@
--   returns the options of every data stream on the cluster.
-- * @'Just' names@              → @GET /_data_stream\/{a,b,c}/_options@
--   returns only the options of the named data streams.
--
-- See
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-get-data-stream-options>.
getDataStreamOptions ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe [DataStreamName] ->
  m GetDataStreamOptionsResponse
getDataStreamOptions = performBHRequest . Requests8.getDataStreamOptions

-- | 'updateDataStreamOptions' sets the options (e.g. failure store
-- configuration) of one or more data streams. Referencing a
-- non-existent stream surfaces as an 'EsError'. Requires
-- Elasticsearch >= 8.19. The request builder lives in the ES8 module
-- and is re-exported by the ES9 client module.
--
-- See
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-put-data-stream-options>.
updateDataStreamOptions ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe [DataStreamName] ->
  UpdateDataStreamOptionsRequest ->
  m Acknowledged
updateDataStreamOptions = (performBHRequest .) . Requests8.updateDataStreamOptions

-- | 'deleteDataStreamOptions' removes the options (e.g. failure store
-- configuration) from one or more data streams, resetting them to
-- their defaults. Deleting the options of a non-existent stream
-- surfaces as an 'EsError'. Requires Elasticsearch >= 8.19. The
-- request builder lives in the ES8 module and is re-exported by the
-- ES9 client module.
--
-- See
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-delete-data-stream-options>.
deleteDataStreamOptions ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe [DataStreamName] ->
  m Acknowledged
deleteDataStreamOptions = performBHRequest . Requests8.deleteDataStreamOptions

-- | 'getDataStreamLifecycleStats' retrieves cluster-wide runtime
-- statistics for the data stream lifecycle service via
-- @GET /_lifecycle/stats@ (Elasticsearch 8.12+). The response carries
-- aggregate timing information plus a per-stream breakdown of
-- backing-index health. The wire format is identical across ES 8.x
-- and 9.x, so the request builder lives in the ES8 module and is
-- re-exported by the ES9 client module.
--
-- See
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-get-data-lifecycle-stats>.
getDataStreamLifecycleStats ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  m DataStreamLifecycleStats
getDataStreamLifecycleStats = performBHRequest Requests8.getDataStreamLifecycleStats

-- | 'explainDataStreamLifecycle' retrieves the per-index lifecycle
-- status for one or more backing indices via
-- @GET /{index}/_lifecycle/explain@ (Elasticsearch 8.11+). Equivalent
-- to @'explainDataStreamLifecycleWith' indices 'defaultExplainDataStreamLifecycleOptions'@.
--
-- Note the path parameter is an @index@ (typically a backing index of
-- the form @.ds-<stream>-<date>-<generation>@), not a data-stream
-- name. The wire format is identical across ES 8.x and 9.x, so the
-- request builder lives in the ES8 module and is re-exported by the
-- ES9 client module.
--
-- See
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-explain-data-lifecycle>.
explainDataStreamLifecycle ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe [IndexName] ->
  m ExplainDataStreamLifecycleResponse
explainDataStreamLifecycle = performBHRequest . Requests8.explainDataStreamLifecycle

-- | 'explainDataStreamLifecycleWith' is the fully-parameterised form
-- of 'explainDataStreamLifecycle'.
explainDataStreamLifecycleWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe [IndexName] ->
  ExplainDataStreamLifecycleOptions ->
  m ExplainDataStreamLifecycleResponse
explainDataStreamLifecycleWith indices =
  performBHRequest . Requests8.explainDataStreamLifecycleWith indices

-- | 'deleteEQLSearch' deletes an async EQL search result and its
-- context by id via @DELETE /_eql/search/{id}@ (Elasticsearch 7.10+)
-- and returns 'Acknowledged' on success. The wire format is identical
-- across ES 7.x, 8.x and 9.x.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-eql-delete>.
deleteEQLSearch ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  EQLSearchId ->
  m Acknowledged
deleteEQLSearch = performBHRequest . Requests8.deleteEQLSearch

-- | 'getTermsEnum' returns a list of terms in a field for auto-complete
-- use cases via @GET \/{index}\/_terms_enum@ (Elasticsearch >= 7.10).
-- The wire format is identical to ES 7.10+, so the ES7 request builder
-- is reused via the ES8 requests module.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-terms-enum.html>.
getTermsEnum ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe [IndexName] ->
  FieldName ->
  Maybe Text ->
  m TermsEnumResponse
getTermsEnum mIndices field mString =
  performBHRequest $ Requests8.getTermsEnum mIndices field mString

-- | 'getTermsEnumWith' is the fully-parameterised form of
-- 'getTermsEnum' (ES >= 7.10). Forwards 'TermsEnumOptions' (URI
-- parameters) and a full 'TermsEnumRequest' body.
--
-- For more information see
-- <https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-terms-enum.html>.
getTermsEnumWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  Maybe [IndexName] ->
  TermsEnumOptions ->
  TermsEnumRequest ->
  m TermsEnumResponse
getTermsEnumWith mIndices opts req =
  performBHRequest $ Requests8.getTermsEnumWith mIndices opts req

------------------------------------------------------------------------------
-- Migration reindex (/_migration/reindex, /_create_from)
------------------------------------------------------------------------------

-- | 'migrateReindex' reindexes all legacy backing indices of a data
-- stream via @POST /_migration/reindex@ (ES 8.18+). The reindex runs in
-- a persistent task; the endpoint returns 'Acknowledged' immediately.
-- Poll 'getMigrateReindexStatus' to observe progress. Mutates cluster
-- state — call deliberately.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-indices-migrate-reindex>.
migrateReindex ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  MigrateReindexRequest ->
  m Acknowledged
migrateReindex req = performBHRequest $ Requests8.migrateReindex req

-- | 'cancelMigrateReindex' cancels an in-progress migration reindex
-- attempt via @POST /_migration/reindex/{index}/_cancel@ (ES 8.18+).
-- Returns 'Acknowledged' on success.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-indices-cancel-migrate-reindex>.
cancelMigrateReindex ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  NonEmpty IndexName ->
  m Acknowledged
cancelMigrateReindex indices =
  performBHRequest $ Requests8.cancelMigrateReindex indices

-- | 'getMigrateReindexStatus' reports the status of a migration reindex
-- attempt via @GET /_migration/reindex/{index}/_status@ (ES 8.18+). The
-- response is decoded into 'MigrateReindexStatus'.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-indices-get-migrate-reindex-status>.
getMigrateReindexStatus ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  NonEmpty IndexName ->
  m MigrateReindexStatus
getMigrateReindexStatus indices =
  performBHRequest $ Requests8.getMigrateReindexStatus indices

-- | 'createIndexFrom' copies the mappings and settings from a source
-- index into a fresh destination index via
-- @POST /_create_from/{source}/{dest}@ (ES 8.18+), with no overrides.
-- Returns 'CreateIndexFromResponse' on success. Mutates cluster state.
--
-- For more information see
-- <https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-indices-create-from>.
createIndexFrom ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  IndexName ->
  IndexName ->
  m CreateIndexFromResponse
createIndexFrom source dest =
  performBHRequest $ Requests8.createIndexFrom source dest

-- | 'createIndexFromWith' is the fully-parameterised variant of
-- 'createIndexFrom', accepting an optional 'CreateIndexFromBody' whose
-- @mappings_override@ and @settings_override@ replace the source values.
createIndexFromWith ::
  (MonadBH m, WithBackend ElasticSearch8 m) =>
  IndexName ->
  IndexName ->
  Maybe CreateIndexFromBody ->
  m CreateIndexFromResponse
createIndexFromWith source dest mBody =
  performBHRequest $ Requests8.createIndexFromWith source dest mBody