UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

54 lines (53 loc) 2.15 kB
import { isData } from "../util/data.js"; import { omitProps, pickProps } from "../util/object.js"; import { mapProps } from "../util/transform.js"; import { validateData } from "../util/validate.js"; import { NULLABLE } from "./NullableSchema.js"; import { OPTIONAL } from "./OptionalSchema.js"; import { Schema } from "./Schema.js"; /** Validate a data object. */ export class DataSchema extends Schema { props; constructor({ one = "item", title = "Item", props, value: partialValue, ...options }) { // Build default value from props and partial value. const value = { ...mapProps(props, _getSchemaValue), ...partialValue }; super({ one, title, value, ...options }); this.props = props; } validate(unsafeValue = this.value) { if (!isData(unsafeValue)) throw "Must be object"; return validateData(unsafeValue, this.props); } /** Make a new `DataSchema` that only uses a defined subset of the current props. */ pick(...keys) { return new DataSchema({ ...this, props: pickProps(this.props, ...keys) }); } /** Make a new `DataSchema` that omits one or more of the current props. */ omit(...keys) { return new DataSchema({ ...this, props: omitProps(this.props, ...keys) }); } } function _getSchemaValue([, { value }]) { return value; } /** Create a `DataSchema` for a set of properties. */ export const DATA = (props) => new DataSchema({ props }); /** Valid data object with specifed properties, or `null` */ export const NULLABLE_DATA = (props) => NULLABLE(new DataSchema({ props })); export function PARTIAL(source) { const props = source instanceof DataSchema ? source.props : source; return new DataSchema({ props: mapProps(props, _optionalProp), }); } function _optionalProp([, v]) { return OPTIONAL(v); } /** Create a `DataSchema` that validates a data item, i.e. it has a string or number `.id` identifier property. */ export function ITEM(id, schemas) { const props = schemas instanceof DataSchema ? schemas.props : schemas; return new DataSchema({ props: { id, ...props }, }); }