Skip to content

Commit 5594fc2

Browse files
author
Kai Eichinger
committed
Add two new LocalRouter route parameter types: nullableStringParameter and nullableNumberParameter.
1 parent 297b46b commit 5594fc2

File tree

3 files changed

+129
-5
lines changed

3 files changed

+129
-5
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
5.20.0
2+
======
3+
4+
* (feature) Add two new `LocalRouter` route parameter types: `nullableStringParameter` and `nullableNumberParameter`.
5+
6+
17
5.19.0
28
======
39

tests/cases/url/router-parameters.js

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import QUnit from "qunit";
2-
import {booleanParameter, numberParameter, stringParameter} from "../../../url/router-parameters";
2+
import {booleanParameter, nullableNumberParameter, nullableStringParameter, numberParameter, stringParameter} from "../../../url/router-parameters";
33

44
QUnit.module("url/router-parameters");
55

@@ -143,3 +143,59 @@ QUnit.test(
143143
);
144144
}
145145
);
146+
147+
QUnit.test(
148+
"nullableStringParameter() valid cases",
149+
(assert) =>
150+
{
151+
// input, defaultValue, expected
152+
const cases = [
153+
["test", null, "test"],
154+
["test", undefined, "test"],
155+
[null, null, null],
156+
[null, undefined, null],
157+
[undefined, null, null],
158+
[undefined, undefined, null],
159+
[null, "default", null],
160+
[undefined, "default", "default"],
161+
[123, null, "123"],
162+
[123, undefined, "123"],
163+
["", null, null],
164+
["", undefined, null],
165+
];
166+
167+
cases.forEach(
168+
([input, defaultValue, expected]) =>
169+
{
170+
assert.strictEqual(nullableStringParameter(defaultValue)(input), expected);
171+
}
172+
);
173+
}
174+
);
175+
176+
QUnit.test(
177+
"nullableNumberParameter() valid cases",
178+
(assert) =>
179+
{
180+
// input, defaultValue, expected
181+
const cases = [
182+
[123, null, 123],
183+
[123, undefined, 123],
184+
["123", null, 123],
185+
["123", undefined, 123],
186+
[null, null, null],
187+
[null, undefined, null],
188+
[null, 432, 432],
189+
[undefined, null, null],
190+
[undefined, undefined, null],
191+
[undefined, 432, 432],
192+
];
193+
194+
cases.forEach(
195+
([input, defaultValue, expected]) =>
196+
{
197+
assert.strictEqual(nullableNumberParameter(defaultValue)(input), expected);
198+
}
199+
);
200+
}
201+
);

url/router-parameters.ts

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {ParameterNormalizer} from "./LocalRouter";
66
*
77
* @internal
88
*/
9-
function typeError (expected: string, value: any): never
9+
function throwTypeError (expected: string, value: any): never
1010
{
1111
throw new Error(
1212
undefined === value
@@ -28,7 +28,7 @@ export function stringParameter (defaultValue?: string) : ParameterNormalizer<st
2828
if (null == value)
2929
{
3030
return defaultValue === undefined
31-
? typeError("string", value)
31+
? throwTypeError("string", value)
3232
: defaultValue;
3333
}
3434

@@ -59,7 +59,7 @@ export function numberParameter (defaultValue?: number) : ParameterNormalizer<nu
5959

6060
// throw if required or invalid (non-empty) value given
6161
return (defaultValue === undefined || null != value)
62-
? typeError("number", value)
62+
? throwTypeError("number", value)
6363
: defaultValue;
6464
};
6565
}
@@ -87,7 +87,69 @@ export function booleanParameter (defaultValue?: boolean) : ParameterNormalizer<
8787

8888
// throw if required or invalid (non-empty) value given
8989
return (defaultValue === undefined || null != value)
90-
? typeError("boolean", value)
90+
? throwTypeError("boolean", value)
9191
: defaultValue;
9292
};
9393
}
94+
95+
96+
/**
97+
* Normalizes the value into a nullable string.
98+
*
99+
* If the parameter is missing or an empty string, either the default value or `null` is returned.
100+
*/
101+
export function nullableStringParameter (defaultValue: string|null = null) : ParameterNormalizer<string|null>
102+
{
103+
return (value) =>
104+
{
105+
if (typeof value === "number")
106+
{
107+
return "" + value;
108+
}
109+
110+
if (null !== value && undefined !== value && typeof value !== "string")
111+
{
112+
throwTypeError("string or null", value);
113+
}
114+
115+
return "" !== value && undefined !== value
116+
? value
117+
: (defaultValue ?? null)
118+
};
119+
}
120+
121+
122+
/**
123+
* Normalizes the value into a nullable number.
124+
*
125+
* If the parameter is missing or , either the default value or `null` is returned.
126+
*/
127+
export function nullableNumberParameter (defaultValue: number|null = null) : ParameterNormalizer<number|null>
128+
{
129+
return (value) =>
130+
{
131+
if (null === value)
132+
{
133+
return defaultValue;
134+
}
135+
136+
if (typeof value === "number")
137+
{
138+
return value;
139+
}
140+
141+
const parsed = parseInt(value, 10);
142+
143+
if (!isNaN(parsed))
144+
{
145+
return parsed;
146+
}
147+
148+
if (defaultValue === undefined || null != value)
149+
{
150+
throwTypeError("number or null", value);
151+
}
152+
153+
return defaultValue ?? null;
154+
};
155+
}

0 commit comments

Comments
 (0)