UNPKG

sharec-schema

Version:

Utilities for configuration files merge

89 lines (74 loc) 2.42 kB
// @ts-check const without = require('lodash.without') /** * @typedef {import('../').Schema} Schema * @typedef {import('../').SchemaParams<*>} SchemaParams */ /** * Mutates given target by given schema and keys * Can work only with hash-like structures! * @param {object} params * @param {Schema} params.schema Configuration schema definition * @param {string[]} params.keys Fields which should be processed * @param {Map} params.target Map-like structure * @returns {Function} */ const applySchemaByKeys = ({ schema, keys = [], target }) => /** * Mutates the passed map! * @param {SchemaParams} params * @returns {Map} */ (params) => { if (keys.length === 0) return target for (const key of keys) { const strategy = schema[key] || schema.$$default const ignoreList = schema.$$ignore || [] const current = params.current.get(key) const skip = !strategy || !params.upcoming.has(key) || ignoreList.includes(key) if (skip && current !== undefined) { target.set(key, current) continue } if (skip) continue const upcoming = params.upcoming.get(key) const cached = params.cached && params.cached.get(key) if (current === undefined && cached !== undefined) continue target.set( key, strategy({ ignore: schema.$$ignore, current, upcoming, cached, }), ) } return target } /** * Main utility which allows to create callable schemas-representation * Returns function which applies incoming params by given schema * @param {Schema} schema * @returns {Function} */ const compose = (schema) => /** * @param {SchemaParams} params * @returns {*} */ (params) => { const { current, upcoming } = params if (upcoming === undefined) return current if (current === undefined) return upcoming if (typeof current !== typeof upcoming) return upcoming if (Array.isArray(schema)) return schema[0](params) const result = new Map() const currentKeys = Array.from(current.keys()) const upcomingKeys = Array.from(upcoming.keys()) const newKeys = without(upcomingKeys, ...currentKeys) applySchemaByKeys({ schema, keys: currentKeys, target: result })(params) applySchemaByKeys({ schema, keys: newKeys, target: result })(params) return result } module.exports = compose