# generateKiwtQueryParams

The `generateKiwtQueryParams` function is similar to `generateKiwtQuery`, but instead of returning a string, it returns an array of query parameters. This can be useful for more advanced use cases where you need to manipulate the parameters before constructing the final query string.

## Basic Usage

```javascript
import { generateKiwtQueryParams } from '@k-int/stripes-kint-components';

const nsValues = {
  query: 'test',
  filters: 'requestStatus.completed,journalVolume.test1,startDate.startDate>=2021-10-28'
};

const options = {
  searchKey: 'request.name',
  filterKeys: {
    requestStatus: 'requestStatus.value',
    journalVolume: 'journalVolume'
  }
};

const queryArray = generateKiwtQueryParams(options, nsValues);

// queryArray will be:
// [
//   "match=request.name",
//   "term=test",
//   "filters=requestStatus.value==completed",
//   "filters=journalVolume==test1",
//   "filters=startDate%3E=2021-10-28",
//   "stats=true"
// ]
```

## Props

| Name | Type | Description | Default | Required |
|---|---|---|---|---|
| options | object | An object with keys: `searchKey`, `filterKeys`, `sortKeys`, and `stats`, which maps the incoming `nsValues` object to a KIWT query array. You can also pass arbitrary `key`/`value` pairs to append `key==value` onto the query. |  | ✓ |
| nsValues | object | An object containing the query parameters. Can contain `query`, `filters`, and `sort`, as well as any other arbitrary parameters. |  | ✓ |
| encode | boolean | A boolean indicating whether to URL-encode the values. | `true` | ✕ |


## Options Parameter Structure

The `options` parameter is a powerful tool for customizing the query string generation manually. It has the following key elements:

*   **Search:**
    *   `searchKey`: Specifies the field to search on. If using SASQ, the corresponding value in `nsValues.query` will be used as the search term. Otherwise, you can directly specify the search term using the `term` key in `options`.
*   **Filters:** See the "Filters Object Structure" section below for details.
*   **Sorting:**
    *   `sortKeys`: An object mapping sort field names from `nsValues.sort` to their corresponding backend keys.
    *   `sort`: An array of sort objects. Each object can have `path` (field to sort on) and `direction` (`asc` or `desc`).
*   **Statistics:**
    *   `stats`: A boolean value indicating whether to include the `stats=true` parameter.
*   **Other parameters:** Any other key-value pairs in the `options` object will be directly added as query parameters.


### Filters Object Structure

The `filters` option in the `options` parameter allows you to define complex filter expressions using an array of filter objects. Each filter object can have the following properties:

*   **path:** The path to the field to filter on (e.g., `item.title`).
*   **comparator:** *(Optional)* The comparator to use for the filter (e.g., `==`, `!=`, `>`, `<`). Defaults to `==`.
*   **value:** A single value to filter on.
*   **values:** An array of values to filter on. If present, this property takes precedence over `value`, and an `OR` condition is implied between the values.
*   **groupValues:** An object defining nested filter groups with `AND` or `OR` logic. This property allows for building complex nested filters. See the explanation below.

### Nested Filter Groups (`groupValues`)

The `groupValues` property enables the creation of nested filter expressions with `AND` and `OR` logic. It is an object with either `AND` or `OR` properties (or both, with `AND` taking precedence). The value of these properties should be an array of filter objects, allowing for recursive nesting.

```javascript
// Example: (status==active AND type==local) OR (status==pending)
const filters = [
  {
    groupValues: {
      OR: [
        {
          groupValues: {
            AND: [
              { path: 'item.status', value: 'active' },
              { path: 'item.type', value: 'local' },
            ],
          }
        },
        { path: 'item.status', value: 'pending' },
      ]
    },
  },
];
```

This structure allows you to express complex filter logic in a clear and organized way.

## nsValues options

In addition to the manual filtering capabilities, `generateKiwtQueryParams` supports advanced filtering options including custom comparators and dynamic filter key overrides for the `query` nsValues passed by SASQ. These features enable you to generate complex query expressions more easily.

### Custom Comparators & Filter Key Overrides
  When using the older `nsValues.filters` string (e.g., `"requestStatus.completed,journalVolume.test1"`), you can use `filterConfig` to customize how filters are interpreted:

    - **Mapping Filter Names:**  
      Each entry in `filterConfig` should include a `name` field that matches the filter name parsed from `nsValues.filters`.

    - **Overriding Values and Comparators:**  
      Optionally, a `values` array can be provided for more granular control. For each possible value, you can specify:
        - A replacement value.
        - A custom comparator to be used instead of the default `'=='`.

  For example, if you want the filter `status` to use a comparator like `isNotSet` for a certain value, your configuration might look like this:

  ```javascript
  const options = {
    filterKeys: { status: 'requestStatus.value' },
    filterConfig: [
      {
        name: 'status',
        values: [
          { name: 'notSet', value: '', comparator: ' isNotSet' },
          { name: 'isNotActive', value: 'active', comparator: '!=' },
          // other value mappings... Any not present will be evaluated as is
        ]
      }
    ]
  };
  ```

  With this configuration, the generated query parameter for various nsValues.filters would be:

| nsValues.filters | outcome |
| -- | -- |
| status.notSet | `filters=requestStatus.value isNotSet` |
| status.wibble | `filters=requestStatus.value==wibble` |
| status.isNotActive | `filters=requestStatus.value!=active` |




### Dynamic Date Example with `moreThanToday`

You can also dynamically set filter values based on runtime data. For instance, if you want to filter records where a date field is greater than or equal to today’s date, you can calculate the date value first and then reference it in your `filterConfig`:

```javascript
// Dynamically calculate today's date in YYYY-MM-DD format
const today = new Date().toISOString().split('T')[0];

const filterConfig = [
  {
    name: 'startDate',
    values: [
      {
        name: 'moreThanToday',
        value: today,
        comparator: '>='
      }
    ]
  }
];

const options = {
  filterConfig,
};

const nsValues = {
  // When 'startDate.moreThanToday' is encountered, it will use the filterConfig mapping
  filters: 'startDate.moreThanToday'
};

const queryArray = generateKiwtQueryParams(options, nsValues);
console.log(queryArray);
// Example output (URL encoded):
// [
//   "filters=startDate%3E%3D2025-02-19", // The date value will reflect today's date
//   "stats=true"
// ]
```

In this example, when `nsValues.filters` contains `startDate.moreThanToday`, the function looks up the corresponding configuration in `filterConfig`, uses the dynamically calculated date stored in `today`, and applies the comparator `>=` to produce a query parameter like:

```
filters=startDate>=2025-02-19
```

This approach makes it easy to filter records based on dynamic criteria, such as dates relative to the current day.

### How It Works

- **For `options.filters` (object-based filtering):**  
  The function handles nested filters, groups (using `groupValues` with `AND`/`OR` logic), and applies the specified comparators. This provides full flexibility when building complex queries.

- **For Legacy SASQ `nsValues.filters` (string-based filtering):**  
  The code splits the incoming comma-separated string into individual filters. For each filter:
    - It checks if there’s a matching entry in `filterConfig`.
    - If found, it applies the mapping from `filterConfig` and uses the comparator specified there (or defaults to `'=='`).
    - If no mapping exists and no filter key is provided in `filterKeys`, the raw value is passed to the backend.

By utilizing these advanced filtering options, you can tailor your query string generation to meet complex backend requirements while maintaining clarity and control over your filter logic.