UNPKG

typea

Version:

JS 数据结构验证、转换器

111 lines (110 loc) 3.08 kB
import { entry } from './router.js'; import { methodKey, optionalKey, indexKey, extensionKey } from './common.js'; const { hasOwnProperty } = Object.prototype; /** * 定义对象结构体中的可选属性,接收任意数据类型,表示 optional() 返回值关联的属性为可选属性 * 通常用于将对象和数组包装为可选 */ export function optional(node) { const newNode = { [indexKey]: node }; Object.defineProperty(newNode, optionalKey, { value: node }); return newNode; } /** * 将传入结构体对象内的所有属性全部定义为可选 */ export function partial(node) { const newNode = {}; for (const name in node) { const subNode = node[name]; if (subNode && hasOwnProperty.call(subNode, optionalKey)) { newNode[name] = subNode; } else { newNode[name] = { [optionalKey]: subNode }; } } return newNode; } /** * 对象必选属性,将所有可选属性转为必选类型 */ export function required(node) { const newNode = {}; for (const name in node) { const subNode = node[name]; if (subNode && hasOwnProperty.call(subNode, optionalKey)) { newNode[name] = subNode[optionalKey]; } else { newNode[name] = subNode; } } return newNode; } /** * 从已有模型中选取属性,创建新的模型 */ export function pick(node, ...keys) { const newNode = {}; for (const key of keys) { if (hasOwnProperty.call(node, key)) { newNode[key] = node[key]; } else { throw new Error(`pick(node) 中 ${key} 属性不存在`); } } return newNode; } /** * 对象省略类型 * @param node schema 节点 * @param keys 忽略属性名 * @returns */ export function omit(node, ...keys) { const newNode = { ...node }; for (const key of keys) { delete newNode[key]; } return newNode; } /** * 联合类型 * @param nodes 指定多个可选类型,顺序匹配其中的一个类型 */ export function union(...nodes) { const newNode = { [methodKey](options, value) { let errorInfo = ''; for (const item of nodes) { const { error, data } = entry(item, value); if (error) { errorInfo = error; } else { return { data }; } } return { error: `${errorInfo},联合类型匹配失败` }; }, [Symbol.iterator]() { return { end: false, next() { if (this.end) { this.end = false; return { done: true }; } else { this.end = true; return { value: { [extensionKey]: newNode } }; } } }; }, }; newNode[indexKey] = newNode; return newNode; }