Skip to content

Commit 4df79e1

Browse files
committed
Change output for empty strings, null and undefined #9
1 parent 7710f1c commit 4df79e1

File tree

12 files changed

+160
-7
lines changed

12 files changed

+160
-7
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
All notable changes to the library will be documented in this file.
44

5+
## vX.X.X (Month DD, YYYY)
6+
7+
- Change output for empty strings, `'null'` and `'undefined'` (issue #9)
8+
59
## v0.5.0 (December 14, 2023)
610

711
- Add `FormDataInfo` type to global exports

src/regex.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
*/
44
export const DIGIT_REGEX = /^\d+$/u;
55

6+
/**
7+
* Number regex.
8+
*/
9+
export const NUMBER_REGEX = /^-?\d*(\.\d+)?$/u;
10+
611
/**
712
* [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) date regex.
813
*/
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { describe, expect, test } from 'vitest';
2+
import { getFieldBoolean } from './getFieldBoolean.ts';
3+
4+
describe('getFieldBoolean', () => {
5+
test('should decode booleans', () => {
6+
// Emtpy string
7+
expect(getFieldBoolean('')).toBeNull();
8+
9+
// "null" string
10+
expect(getFieldBoolean('null')).toBeNull();
11+
12+
// "undefined" string
13+
expect(getFieldBoolean('undefined')).toBeUndefined();
14+
15+
// "true" string
16+
expect(getFieldBoolean('true')).toBe(true);
17+
18+
// "false" string
19+
expect(getFieldBoolean('false')).toBe(false);
20+
21+
// "1" string
22+
expect(getFieldBoolean('1')).toBe(true);
23+
24+
// "0" string
25+
expect(getFieldBoolean('0')).toBe(false);
26+
27+
// "on" string
28+
expect(getFieldBoolean('on')).toBe(true);
29+
30+
// "off" string
31+
expect(getFieldBoolean('off')).toBe(false);
32+
33+
// Otherwise
34+
expect(getFieldBoolean('test')).toBe(true);
35+
});
36+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Returns the decoded boolean of a field.
3+
*
4+
* @param value The field value.
5+
*
6+
* @returns The decoded boolean.
7+
*/
8+
export function getFieldBoolean(value: FormDataEntryValue) {
9+
// Null
10+
if (!value || value === 'null') {
11+
return null;
12+
}
13+
14+
// Undefined
15+
if (value === 'undefined') {
16+
return undefined;
17+
}
18+
19+
// Otherwise
20+
return !(value === 'false' || value === 'off' || value === '0');
21+
}

src/utils/getFieldBoolean/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './getFieldBoolean.ts';

src/utils/getFieldDate/getFieldDate.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ describe('getFieldDate', () => {
66
// Emtpy string
77
expect(getFieldDate('')).toBeNull();
88

9+
// Null string
10+
expect(getFieldDate('null')).toBeNull();
11+
12+
// Undefined string
13+
expect(getFieldDate('undefined')).toBeUndefined();
14+
915
// Date (yyyy-mm-dd)
1016
expect(getFieldDate('2023-10-04')).toEqual(
1117
new Date('2023-10-04T00:00:00.000Z')

src/utils/getFieldDate/getFieldDate.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@ import {
1515
* @returns The decoded date.
1616
*/
1717
export function getFieldDate(value: string) {
18-
// Empty string
19-
if (!value) {
18+
// Null
19+
if (!value || value === 'null') {
2020
return null;
2121
}
2222

23+
// Undefined
24+
if (value === 'undefined') {
25+
return undefined;
26+
}
27+
2328
// Date (yyyy-mm-dd)
2429
if (ISO_DATE_REGEX.test(value)) {
2530
return new Date(`${value}T00:00:00.000Z`);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { describe, expect, test } from 'vitest';
2+
import { getFieldNumber } from './getFieldNumber.ts';
3+
4+
describe('getFieldNumber', () => {
5+
test('should decode numbers', () => {
6+
// Emtpy string
7+
expect(getFieldNumber('')).toBeNull();
8+
9+
// "null" string
10+
expect(getFieldNumber('null')).toBeNull();
11+
12+
// "undefined" string
13+
expect(getFieldNumber('undefined')).toBeUndefined();
14+
15+
// Number strings
16+
expect(getFieldNumber('123')).toBe(123);
17+
expect(getFieldNumber('-123')).toBe(-123);
18+
expect(getFieldNumber('1.23')).toBe(1.23);
19+
expect(getFieldNumber('-1.23')).toBe(-1.23);
20+
expect(getFieldNumber('12.3')).toBe(12.3);
21+
expect(getFieldNumber('-12.3')).toBe(-12.3);
22+
23+
// Date string
24+
expect(getFieldNumber('2023-10-04')).toBe(1696377600000);
25+
expect(getFieldNumber('2024-02-11T21:54:10.851Z')).toBe(1707688450851);
26+
27+
// Otherwise
28+
expect(getFieldNumber('1,234.56')).toBeNaN();
29+
expect(getFieldNumber('Invalid Date')).toBeNaN();
30+
expect(getFieldNumber('abc')).toBeNaN();
31+
});
32+
});
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { NUMBER_REGEX } from '../../regex.ts';
2+
import { getFieldDate } from '../getFieldDate/index.ts';
3+
4+
/**
5+
* Returns the decoded number of a field.
6+
*
7+
* @param value The field value.
8+
*
9+
* @returns The decoded number.
10+
*/
11+
export function getFieldNumber(value: string) {
12+
// Null
13+
if (!value || value === 'null') {
14+
return null;
15+
}
16+
17+
// Undefined
18+
if (value === 'undefined') {
19+
return undefined;
20+
}
21+
22+
// Number
23+
if (NUMBER_REGEX.test(value)) {
24+
return Number(value);
25+
}
26+
27+
// Date
28+
return getFieldDate(value)!.getTime();
29+
}

src/utils/getFieldNumber/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './getFieldNumber.ts';

0 commit comments

Comments
 (0)