packages/refine/Refine_API.js (40 lines of code) (raw):

/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * refine: type-refinement combinator library for checking mixed values * see wiki for more info: https://fburl.com/wiki/14q16qqy * * @emails oncall+monitoring_interfaces * @flow strict * @format */ 'use strict'; import type {Checker, CheckFailure, CheckResult} from './Refine_Checkers'; const err = require('recoil-shared/util/Recoil_err'); /** * function to assert that a given value matches a checker */ export type AssertionFunction<V> = (value: mixed) => V; /** * function to coerce a given value to a checker type, returning null if invalid */ export type CoercionFunction<V> = (value: mixed) => ?V; /** * helper for raising an error based on a failure */ function raiseError(suffix: string, resultFailure: ?CheckFailure): empty { if (resultFailure != null) { const path = resultFailure.path.toString(); const message = resultFailure.message; throw err(`[refine.js (path=${path}, message=${message})]: ${suffix}`); } throw err(`[refine.js (null result)]: ${suffix}`); } /** * create a function to assert a value matches a checker, throwing otherwise * * For example, * * ``` * const assert = assertion(array(number())); * const value: Array<number> = assert([1,2]); * * try { * // should throw with `Refine.js assertion failed: ...` * const invalid = assert('test'); * } catch { * } * ``` */ function assertion<T>( checker: Checker<T>, errorMessage: string = 'assertion error', ): AssertionFunction<T> { return value => { const result = checker(value); return result.type === 'success' ? result.value : raiseError(errorMessage, result); }; } /** * create a CoercionFunction given a checker. * * Allows for null-coercing a value to a given type using a checker. Optionally * provide a callback which receives the full check * result object (e.g. for logging). * * Example: * * ```javascript * import {coercion, record, string} from 'refine'; * import MyLogger from './MyLogger'; * * const Person = record({ * name: string(), * hobby: string(), * }); * * const coerce = coercion(Person, result => MyLogger.log(result)); * * declare value: mixed; * * // ?Person * const person = coerce(value); * ``` */ function coercion<T>( checker: Checker<T>, onResult?: (CheckResult<T>) => void, ): CoercionFunction<T> { return value => { const result = checker(value); if (onResult != null) { onResult(result); } return result.type === 'success' ? result.value : null; }; } module.exports = { assertion, coercion, };