SplitKey and ClusterKey react query builder basic filters + must_not/should change + groupKey + exists Clause + root grouping

by alfredopacino

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
  text-align: center;
}

TypeScript

/**
 * OpenSearch QueryBuilder for basic filters.
 *
 * It supports the following cases:
 *
 * 1. **Top-level fields**
 *    Generates either a `term`, `terms` (for arrays), or a `range` query.
 *    Examples:
 *      { field: "variantCategory", value: "small" }
 *      { field: "variantCategory", value: ["cnv", "structural"] }
 *      { field: "start", value: { lte: 1 } }
 *
 * 2. **Indexed nested fields**
 *    Fields indexed as nested objects in OpenSearch.
 *    Example: { field: "genes.genePanels.source", value: ["NGTD", "AWSD"] }
 *
 * 3. **Nested fields that are not entirely indexed as nested**
 *    Allows overriding the nesting level through `nestedPath` in `queryConfig`. In case nestedPath is null, the field is treated as top-level.
 *    Example: { field: "reportEvents.vendorSpecificScores.rank", value: { lte: 1 }, queryConfig: { nestedPath: "reportEvents" } }
 *
 * 4. **Fields that imply additional underlying query terms**
 *    Uses `requiredTerm` in `queryConfig` to inject another QueryTerm.
 *    Example: { field: "reportEvents.vendorSpecificScores.rank", value: { lte: 1 }, queryConfig: { nestedPath: "reportEvents", requiredTerm: { field: "reportEvents.interpretationService", value: "Exomiser" } } }
 *
 *    By default, the injected `requiredTerm` inherits the host filter's `nestedPath` AND
 *    `groupConfig` (so it joins the same group/scope as its host), unless the requiredTerm
 *    explicitly sets its own `nestedPath` and/or `groupConfig`.
 *
 * 5. **Special-case fields with ad-hoc render (exceptionTerms())**
 *    Example: { field: "size", value: { lte: 1 } }
 *
 * 6. **Group-level boolean operators (root and nested)**
 *    Use `queryConfig.groupConfig` to group filters into a named branch, decide how members of
 *    that branch combine (`bool`), and optionally cluster several branches together with
 *    `clusterKey` so they combine as siblings (typically OR'd) at a specific scope.
 *
 *      -...