@restless/sanitizers
v0.2.5
Published
Data sanitization in a functional way
Downloads
4,009
Readme
Restless - Sanitizers
Functional data validation.
Installation
npm install @restless/sanitizers
yarn add @restless/sanitizers
Api
cast
asString
asNumber
asInteger
asBoolean
asMatching
asObject
asArray
asOptional
asChecked
asMapped
asFlatMapped
asAnyOf
withErrorMessage
cast
Accepts a value and applies a sanitizer to it resulting in returning the sanitized value or throwing a TypeError. The third optional parameter is the custom error message, with which cast will be thrown.
cast('123', asNumber) // 123
cast('foo', asNumber) // TypeError
cast('foo', asNumber, 'My custom message') // throws error with custom message
castOr
Accepts a value and applies a sanitizer to it resulting in returning the sanitized value or the default value. Also works when values have different types.
castOr('123', asNumber, null) // 123
castOr('foo', asNumber, null) // null
asString
Accepts any value that is a string. Returns a string.
asString('asd', 'path') // Result.ok('asd')
asString(123, 'path') // Result.error([{expected: 'string', path: 'path'}])
asNumber
Accepts any value that is a number or a string that represents a number. Returns a number.
asNumber(123, 'path') // Result.ok(123)
asNumber('0.2', 'path') // Result.ok(0.2)
asNumber('boo', 'path') // Result.error([{expected: 'number', path: 'path'}])
asNumber({}, 'path') // Result.error([{expected: 'number', path: 'path'}])
asInteger
Same as asNumber
, but does not accept floating point values.
asInteger('123', 'path') // Result.ok(123)
asInteger(0.2, 'path') // Result.error([{expected: 'integer', path: 'path'}])
asInteger('boo', 'path') // Result.error([{expected: 'integer', path: 'path'}])
asInteger({}, 'path') // Result.error([{expected: 'integer', path: 'path'}])
asBoolean
Accepts any value that is a number or a string that represents a boolean ("true"
or "false"
). Returns a number.
asBoolean(true, 'path') // Result.ok(true)
asBoolean('false', 'path') // Result.ok(false)
asBoolean('boo', 'path') // Result.error([{expected: 'boolean', path: 'path'}])
asBoolean(123, 'path') // Result.error([{expected: 'boolean', path: 'path'}])
asMatching
This higher-order sanitizer accepts values that are strings matching the regex provided as an argument. You can pass a custom message to it.
const sanitizer = asMatching(/aaa/, 'custom message')
sanitizer('aaa', 'path') // Result.ok('aaa')
sanitizer(123, 'path') // Result.error([{expected: 'custom message', path: 'path'}])
sanitizer('b', 'path') // Result.error([{expected: 'custom message', path: 'path'}])
asObject
This higher-order sanitizer requires a schema in the form of an object. Values of the schema are sanitizers used to sanitize the values of the input. Returns an object with keys and values matching the schema.
const sanitizer = asObject({ foo: asNumber, bar: asString })
sanitizer({ foo: 1, bar: 'a' }, 'path') // Result.ok({ foo: 1, bar: 'a' })
sanitizer(123, 'path') // Result.error([{expected: 'object', path: 'path'}])
sanitizer({}, 'path')
// Result.error([
// {expected: 'number', path: 'path.foo'},
// {expected: 'string', path: 'path.bar'}
// ])
sanitizer({ foo: true, bar: 'a' , 'path') // Result.error([{expected: 'number', path: 'path.foo'}])
asArray
This higher-order sanitizer accepts any value that is an array of items that are sanitized through the sanitizer passed as argument.
const sanitizer = asArray(asNumber)
sanitizer([123, '45'], 'path') // Result.ok([123, 45])
sanitizer(123, 'path') // Result.error([{expected: 'array', path: 'path'}])
sanitizer([123, 'foo'], 'path') // Result.error([{expected: 'number', path: 'path[0]'}])
asOptional
This higher-order sanitizer accepts undefined or null or any value that is sanitized through the sanitizer passed as argument.
const sanitizer = asOptional(asString)
sanitizer('abcdef', 'path') // Result.ok('abcdef')
sanitizer(null, 'path') // Result.ok(undefined)
sanitizer(undefined, 'path') // Result.ok(undefined)
sanitizer(123, 'path') // Result.error([{expected: 'string', path: 'path'}])
asExactly
This higher-order sanitizer accepts only exactly the same values as the reference provided. Values are compared using the triple-equals operator (===
).
Works with strings, numbers, booleans, null, and undefined.
const sanitizer = asExactly('foo')
sanitizer('foo', 'path') // Result.ok('foo')
sanitizer('bar', 'path') // Result.error([{expected: 'exactly "foo"', path: 'path'}])
asChecked
This higher-order sanitizer accepts any value that is sanitized through the sanitizer passed as argument and satisfies the predicate passed as the second argument. A third argument that specifies an optional expected message can be provided
const sanitizer = asChecked(asString, x => x.length > 3)
sanitizer('abcdef', 'path') // Result.ok('abcdef')
sanitizer(123, 'path') // Result.error([{expected: 'string', path: 'path'}])
sanitizer('a', 'path') // Result.error([{expected: 'custom logic', path: 'path'}])
const sanitizer = asChecked(asString, x => x.length > 3, 'string longer than 3')
sanitizer('a', 'path') // Result.error([{expected: 'string longer than 3', path: 'path'}])
It also works with type guards in the same way as Array.filter
:
const asFoo: Sanitizer<'foo'> = asChecked(asString, (x): x is 'foo' => x === 'foo')
asMapped
This higher-order sanitizer accepts any value that is sanitized through the sanitizer passed as argument. That value is then transformed using the provided function.
const sanitizer = asMapped(asNumber, x => x > 1)
sanitizer(123, 'path') // Result.ok(true)
sanitizer(0, 'path') // Result.ok(false)
sanitizer('a', 'path') // Result.error([{expected: 'number', path: 'path'}])
asFlatMapped
This higher-order sanitizer accepts any value that is sanitized through the sanitizer passed as argument. That value is then transformed using the provided function that can return Result a new value or an error.
const sanitizer = asFlatMapped(asNumber, (value, path) => x > 1
? Result.ok(value)
: Result.error([{ path, expected: 'number > 1' }])
)
sanitizer(123, 'path') // Result.ok(123)
sanitizer(0, 'path') // Result.error([{expected: 'number > 1', path: 'path'}])
sanitizer('a', 'path') // Result.error([{expected: 'number', path: 'path'}])
asAnyOf
This higher-order sanitizer accepts any value that is successfully sanitized through any of the sanitizers passed as an array argument. In case of multiple passing sanitizers, first one is used. A second argument specifies expected message.
const sanitizer = asAnyOf([asNumber, asString], 'a string or a number')
sanitizer('abcdef', 'path') // Result.ok('abcdef')
sanitizer('123', 'path') // Result.ok(123)
sanitizer(123, 'path') // Result.ok(123)
sanitizer({}, 'path') // Result.error([{expected: 'a string or a number', path: 'path'}])
withErrorMessage
This higher-order sanitizer will act just like the sanitizer passed as an argument, but will change the error value to contain a different expected
message.
const sanitizer = withErrorMessage(asString, 'bla bla')
sanitizer('abcdef', 'path') // Result.ok('abcdef')
sanitizer(123, 'path') // Result.error([{expected: 'bla bla', path: 'path'}])