Skip to content
This repository was archived by the owner on May 1, 2021. It is now read-only.

Commit ba685db

Browse files
committed
Add ability to quickly create enum params
1 parent 1241b94 commit ba685db

File tree

6 files changed

+68
-0
lines changed

6 files changed

+68
-0
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ Examples in this table assume query parameter named `qp`.
6868
| DelimitedArrayParam | string[] | `['a','b','c']` | `?qp=a_b_c'` |
6969
| DelimitedNumericArrayParam | number[] | `[1, 2, 3]` | `?qp=1_2_3'` |
7070

71+
**Enum Param**
72+
73+
You can define enum param using `createEnumParam`. It works as `StringParam` but restricts decoded output to a list of allowed strings:
74+
75+
```js
76+
import { createEnumParam } from 'serialize-query-params';
77+
78+
// values other than 'asc' or 'desc' will be decoded as undefined
79+
const SortOrderEnumParam = createEnumParam(['asc', 'desc'])
80+
```
81+
7182
**Setting a default value**
7283

7384
If you'd like to have a default value, you can wrap your param with `withDefault()`:

src/__tests__/params-test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
NumericObjectParam,
1212
DelimitedArrayParam,
1313
DelimitedNumericArrayParam,
14+
createEnumParam,
1415
} from '../index';
1516

1617
describe('params', () => {
@@ -110,5 +111,11 @@ describe('params', () => {
110111
expect(DelimitedNumericArrayParam.encode([1, 2])).toBe('1_2');
111112
expect(DelimitedNumericArrayParam.decode('1_2')).toEqual([1, 2]);
112113
});
114+
it('createEnumParam', () => {
115+
const TestEnumParam = createEnumParam(['foo', 'bar'])
116+
expect(TestEnumParam.encode('foo')).toBe('foo');
117+
expect(TestEnumParam.decode('bar')).toBe('bar');
118+
expect(TestEnumParam.decode('baz')).toBeUndefined();
119+
});
113120
});
114121
});

src/__tests__/serialize-test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
decodeNumber,
88
encodeString,
99
decodeString,
10+
decodeEnum,
1011
encodeJson,
1112
decodeJson,
1213
encodeArray,
@@ -146,6 +147,24 @@ describe('serialize', () => {
146147
expect(decodeString(['foo', 'bar'])).toBe('foo');
147148
});
148149
});
150+
151+
describe('decodeEnum', () => {
152+
const enumValues = ['foo', 'bar']
153+
154+
it('produces the correct value', () => {
155+
expect(decodeEnum('foo', enumValues)).toBe('foo');
156+
expect(decodeEnum('bar', enumValues)).toBe('bar');
157+
expect(decodeEnum('baz', enumValues)).toBeUndefined();
158+
expect(decodeEnum('', enumValues)).toBeUndefined();
159+
expect(decodeEnum(undefined, enumValues)).toBeUndefined();
160+
expect(decodeEnum(null, enumValues)).toBeNull();
161+
});
162+
163+
it('handles array of values', () => {
164+
expect(decodeEnum(['foo', 'bar'], enumValues)).toBe('foo');
165+
});
166+
})
167+
149168
describe('encodeJson', () => {
150169
it('produces the correct value', () => {
151170
const input = { test: '123', foo: [1, 2, 3] };

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export {
99
decodeNumber,
1010
encodeString,
1111
decodeString,
12+
decodeEnum,
1213
encodeJson,
1314
decodeJson,
1415
encodeArray,
@@ -38,6 +39,7 @@ export {
3839
NumericObjectParam,
3940
DelimitedArrayParam,
4041
DelimitedNumericArrayParam,
42+
createEnumParam,
4143
} from './params';
4244

4345
export {

src/params.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ export const StringParam: QueryParamConfig<
1212
decode: Serialize.decodeString,
1313
};
1414

15+
/**
16+
* String enum
17+
*/
18+
export const createEnumParam = <T extends string>(
19+
enumValues: T[]
20+
): QueryParamConfig<string | null | undefined, T | null | undefined> => ({
21+
encode: Serialize.encodeString,
22+
decode: input => Serialize.decodeEnum(input, enumValues),
23+
})
24+
1525
/**
1626
* Numbers (integers or floats)
1727
*/

src/serialize.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,25 @@ export function decodeString(
253253
return String(str);
254254
}
255255

256+
/**
257+
* Decodes an enum value while safely handling null and undefined values.
258+
*
259+
* If an array is provided, only the first entry is used.
260+
*
261+
* @param {String} input the encoded string
262+
* @param {String[]} enumValues allowed enum values
263+
* @return {String} the string value from enumValues
264+
*/
265+
export function decodeEnum<T extends string>(
266+
input: string | (string | null)[] | null | undefined,
267+
enumValues: T[]
268+
): T | null | undefined {
269+
const str = decodeString(input)
270+
if (str == null) return str
271+
const isEnumMember = (str: string): str is T => enumValues.includes(str as any)
272+
return isEnumMember(str) ? str : undefined
273+
}
274+
256275
/**
257276
* Encodes anything as a JSON string.
258277
*

0 commit comments

Comments
 (0)