kibana/packages/kbn-rison/kbn_rison.ts
Maxim Palenov 4a93da0ba3
[Security Solution] Global query string functionality improvements (#147218)
Addresses: https://github.com/elastic/kibana/issues/140263

This PR was inspired by https://github.com/elastic/kibana/pull/146649 and while working on persistent rules table state https://github.com/elastic/kibana/pull/145111.

## Summary

It includes improvements for url search parameters manipulation functionality. In particular `useGetInitialUrlParamValue` and `useReplaceUrlParams` hooks.

The main idea is to isolate the encoding layer ([rison](https://github.com/Nanonid/rison)) as an implementation detail so `useGetInitialUrlParamValue` and `useReplaceUrlParams` consumers can just provide types they wish and the hooks serialize/desirealize the data into appropriate format under the hood.

On top of that after `@kbn/rison` was added in https://github.com/elastic/kibana/pull/146649 it's possible to use this package directly to encode and decode parameters whenever necessary.

The improvements include
- store unserialized url parameters state in the redux store
- encode and decode data by using functions from `@kbn/rison` directly
- let `useReplaceUrlParams` accept an updater object

### Checklist

- [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
2023-01-05 18:02:12 +01:00

70 lines
1.7 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
// @ts-expect-error untyped module from npm
// eslint-disable-next-line @kbn/eslint/module_migration
import Rison from 'rison-node';
export type RisonValue =
| boolean
| string
| number
| RisonValue[]
| { [key: string]: RisonValue }
| null;
export function encodeUnknown(obj: any): string | undefined {
return Rison.encode(obj);
}
/**
* rison-encode a javascript structure
*/
export function encode(obj: any) {
const rison = encodeUnknown(obj);
if (rison === undefined) {
throw new Error(
'unable to encode value into rison, expected a primitive value array or object'
);
}
return rison;
}
/**
* parse a rison string into a javascript structure.
*/
export function decode(rison: string): RisonValue {
return Rison.decode(rison);
}
/**
* safely parse a rison string into a javascript structure, never throws
*/
export function safeDecode(rison: string): RisonValue {
try {
return decode(rison);
} catch {
return null;
}
}
/**
* rison-encode a javascript array without surrounding parens
*/
export function encodeArray(array: any[]) {
return Rison.encode_array(array);
}
/**
* parse an a-rison string into a javascript structure.
*
* this simply adds array markup around the string before parsing.
*/
export function decodeArray(rison: string): RisonValue[] {
return Rison.decode_array(rison);
}