UNPKG

uniforms-bridge-simple-schema-2

Version:

SimpleSchema 2 bridge for uniforms.

164 lines (163 loc) 6.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const invariant_1 = tslib_1.__importDefault(require("invariant")); const cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep")); const memoize_1 = tslib_1.__importDefault(require("lodash/memoize")); const simpl_schema_1 = tslib_1.__importDefault(require("simpl-schema")); const uniforms_1 = require("uniforms"); const propsToRemove = ['optional', 'uniforms', 'allowedValues']; function makeGeneric(name) { return name === null || name === void 0 ? void 0 : name.replace(/\.\d+(\.|$)/g, '.$$$1'); } class SimpleSchema2Bridge extends uniforms_1.Bridge { constructor({ schema }) { super(); this.schema = schema; // Memoize for performance and referential equality. this.getField = (0, memoize_1.default)(this.getField.bind(this)); this.getInitialValue = (0, memoize_1.default)(this.getInitialValue.bind(this)); this.getProps = (0, memoize_1.default)(this.getProps.bind(this)); this.getSubfields = (0, memoize_1.default)(this.getSubfields.bind(this)); this.getType = (0, memoize_1.default)(this.getType.bind(this)); } // TODO: Get rid of this `any`. getError(name, error) { const details = error === null || error === void 0 ? void 0 : error.details; if (!Array.isArray(details)) { return null; } return details.find(error => error.name === name) || null; } // TODO: Get rid of this `any`. getErrorMessage(name, error) { const scopedError = this.getError(name, error); // @ts-expect-error: `messageForError` has incorrect typing. return !scopedError ? '' : this.schema.messageForError(scopedError); } // TODO: Get rid of this `any`. getErrorMessages(error) { if (!error) { return []; } const { details } = error; return Array.isArray(details) ? // @ts-expect-error: `messageForError` has incorrect typing. details.map(error => this.schema.messageForError(error)) : [error.message || error]; } getField(name) { const definition = this.schema.getDefinition(name); (0, invariant_1.default)(definition, 'Field not found in schema: "%s"', name); const merged = Object.assign(Object.assign({}, definition), definition.type[0]); // aldeed/node-simple-schema#27 if (merged.autoValue && (merged.autoValue.name === 'defaultAutoValueFunction' || merged.autoValue.toString().indexOf('$setOnInsert:') !== -1) // FIXME: Hack. ) { try { merged.defaultValue = merged.autoValue.call({ operator: null }); } catch (_) { // It's fine. } } return merged; } getInitialValue(name) { const field = this.getField(name); const defaultValue = field.defaultValue; if (defaultValue !== undefined) { return (0, cloneDeep_1.default)(defaultValue); } if (field.type === Array) { const item = this.getInitialValue((0, uniforms_1.joinName)(name, '$')); if (item === undefined) { return []; } const length = field.minCount || 0; return Array.from({ length }, () => item); } if (field.type === Object || field.type instanceof simpl_schema_1.default) { const value = {}; this.getSubfields(name).forEach(key => { const initialValue = this.getInitialValue((0, uniforms_1.joinName)(name, key)); if (initialValue !== undefined) { value[key] = initialValue; } }); return value; } return undefined; } getProps(name) { const _a = this.getField(name), { type: fieldType } = _a, props = tslib_1.__rest(_a, ["type"]); props.required = !props.optional; if (typeof props.uniforms === 'function' || typeof props.uniforms === 'string') { props.component = props.uniforms; } else { Object.assign(props, props.uniforms); } if (fieldType === Number) { props.decimal = true; } let options = props.options; let allowedValues = props.allowedValues; if (typeof options === 'function') { options = options(); } if (!options && typeof allowedValues === 'function') { allowedValues = allowedValues(); } if (!options && Array.isArray(allowedValues)) { options = allowedValues.map(value => ({ value })); } else if (fieldType === Array) { try { const itemProps = this.getProps(`${name}.$`); if (itemProps.options) { options = itemProps.options; } } catch (_) { // It's fine. } } propsToRemove.forEach(key => { if (key in props) { delete props[key]; } }); return Object.assign(props, { options }); } getSubfields(name) { return this.schema.objectKeys(makeGeneric(name)); } getType(name) { const type = this.getField(name).type; if (type === simpl_schema_1.default.Integer) { return Number; } if (type instanceof simpl_schema_1.default) { return Object; } return type; } // TODO: `ValidationOption` is not exported. getValidator(options = { clean: true, mutate: true }) { const validator = this.schema.validator(options); return (model) => { try { // Clean mutate its argument, even if mutate is false. validator(options.clean ? (0, cloneDeep_1.default)(Object.assign({}, model)) : model); return null; } catch (error) { return error; } }; } } exports.default = SimpleSchema2Bridge;