UNPKG

@backland/schema

Version:

TypeScript schema declaration and validation library with static type inference

439 lines (435 loc) 17.4 kB
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } import { RuntimeError } from '@backland/utils'; import { isProduction } from '@backland/utils'; import { getKeys } from '@backland/utils'; import { getTypeName } from '@backland/utils'; import { inspectObject } from '@backland/utils'; import { GraphType } from './GraphType/GraphType'; import { isObject } from './ObjectType'; import { fieldInstanceFromDef } from './fieldInstanceFromDef'; import { isFieldInstance } from './fields/FieldType'; import { LiteralField } from './fields/LiteralField'; import { createEmptyMetaField, isMetaField, objectMetaFieldKey } from './fields/MetaFieldField'; import { types } from './fields/fieldTypes'; import { isStringFieldDefinition, parseStringDefinition } from './parseStringDefinition'; export var _parserHooks = []; export function setParserHook(hook) { _parserHooks.push(hook); function remove() { _parserHooks.find(function (el, index) { if (el !== hook) return false; delete _parserHooks[index]; return true; }); return _parserHooks; } return remove; } export function parseObjectField(fieldName, definition) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var _ref = options === true ? { returnInstance: true } : options, returnInstance = _ref.returnInstance, asString = _ref.asString, deep = _ref.deep, omitMeta = _ref.omitMeta; if (deep !== null && deep !== void 0 && deep.omitMeta) omitMeta = true; if (deep !== null && deep !== void 0 && deep.asString) asString = true; var parsed = parseFieldDefinitionConfig(definition, { deep: deep, omitMeta: omitMeta }); if (_parserHooks.length) { _parserHooks.forEach(function (cb) { return cb(parsed); }); } if (typeof parsed === 'string') { return parsed; } else { if (asString) return parsed; } var instanceFromDef = fieldInstanceFromDef(parsed); setCachedFieldInstance(parsed, instanceFromDef); if (instanceFromDef.def) { parsed.def = instanceFromDef.def; } if (returnInstance) { return instanceFromDef; } if (parsed) return parsed; throw new RuntimeError("field \"".concat(fieldName, "\": invalid definition."), { definition: definition, parsed: parsed }); } export function parseField(definition) { return parseObjectField('__parseField__', definition); } var stringifiableDefKeys = new Set(['type', 'list', 'optional' // ]); export function parseFieldDefinitionConfig(definition, options) { var _ref2 = options || {}, deep = _ref2.deep, asString = _ref2.asString; if (deep !== null && deep !== void 0 && deep.asString) { asString = true; } function _parseField() { if (LiteralField.isFinalTypeDef(definition)) { return { def: definition.def, defaultValue: definition.defaultValue, description: definition.description, hidden: definition.hidden, list: !!definition.list, optional: !!definition.optional, type: 'literal' }; } if (GraphType.is(definition)) { var def = parseFieldDefinitionConfig(definition.definition, { deep: deep }); def.hidden = def.hidden || definition.hidden; return def; } if (GraphType.isTypeDefinition(definition)) { var _definition$list = definition.list, list = _definition$list === void 0 ? false : _definition$list, _definition$optional = definition.optional, optional = _definition$optional === void 0 ? false : _definition$optional, description = definition.description, defaultValue = definition.defaultValue, hidden = definition.hidden, _definition$type$defi = definition.type.definition, type = _definition$type$defi.type, _def = _definition$type$defi.def, _defaultValue = _definition$type$defi.defaultValue; return { def: _def, defaultValue: defaultValue === undefined ? _defaultValue : defaultValue, description: description, hidden: hidden, list: list, optional: optional, type: type }; } if (isStringFieldDefinition(definition)) { return parseStringDefinition(definition); } if (isFieldInstance(definition)) { return definition.asFinalFieldDef; } if (isFinalFieldDefinition(definition)) { if (definition.type === 'object') { if (_typeof(definition.def) !== 'object' || !definition.def) { throw new RuntimeError("Missing def for object field.", { definition: definition }); } if (isObject(definition.def)) { definition.def = definition.def.definition; } else { definition.def = parseObjectDefinition(definition.def, { deep: deep }).definition; } } if (definition.type === 'union') { var isOptionalUnion = definition.optional; definition.def = definition.def.map(function (el) { var parsed = parseFieldDefinitionConfig(el, { deep: deep }); if (parsed.optional) isOptionalUnion = true; return parsed; }); definition.optional = isOptionalUnion; } if (definition.type === 'alias') { if (_typeof(definition.def) === 'object') { definition.def.type = parseFieldDefinitionConfig(definition.def.type, { deep: deep }); validFlattenDefinitionKeysList.forEach(function (k) { if (definition[k] !== undefined) { // @ts-ignore definition.def.type[k] = definition[k]; } }); } } return definition; } if (isListDefinition(definition)) { var parsed = parseFieldDefinitionConfig(definition[0], { deep: deep }); parsed.list = true; parsed.optional = false; return parsed; } if (isObject(definition)) { return { def: deep ? parseObjectDefinition(definition.definition, { deep: deep }) : definition.definition, defaultValue: undefined, description: definition.description, hidden: definition.hidden, type: 'object' }; } if (isObjectAsTypeDefinition(definition)) { return { def: deep ? parseObjectDefinition(definition.type.definition, { deep: deep }) : definition.type.definition, defaultValue: undefined, description: definition.type.description, hidden: definition.hidden || definition.type.hidden, list: !!definition.list, name: definition.name, optional: !!definition.optional, type: 'object' }; } var keyObjectDefinition = parseFlattenFieldDefinition(definition, { deep: deep }); if (keyObjectDefinition) { return keyObjectDefinition; } throw new Error("Unexpected field definition: ".concat(inspectObject(definition))); } try { var result = _parseField(); if (definition && _typeof(definition) === 'object') { if ('name' in definition && definition.name && typeof definition.name === 'string') { result.name = definition.name; } } var hasNotStringifiableKeys = false; var hasDef = false; Object.entries(result).forEach(function (_ref3) { var _ref4 = _slicedToArray(_ref3, 2), k = _ref4[0], v = _ref4[1]; if (v === undefined || v === false) { delete result[k]; // deleting nullish values return; } if (k === 'def') { hasDef = true; return; } if (hasNotStringifiableKeys || !stringifiableDefKeys.has(k)) { hasNotStringifiableKeys = true; } }); if (asString && !hasNotStringifiableKeys) { var type = result.type, list = result.list, optional = result.optional, def = result.def; var _type = type; if (list) _type = "[".concat(_type, "]"); if (optional) _type = "".concat(_type, "?"); if (hasDef) { // @ts-ignore return _defineProperty({}, _type, def); } else { // @ts-ignore return _type; } } // return simpleObjectClone(result); return result; } catch (e) { debugger; console.error(e, definition); throw e; } } export function parseObjectDefinition(input) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var deep = options.deep, omitMeta = options.omitMeta; if (deep !== null && deep !== void 0 && deep.omitMeta) { omitMeta = true; } var result = {}; var meta = undefined; var keys = getKeys(input); keys.forEach(function (fieldName) { try { var _field = input[fieldName]; if (isMetaField(_field, fieldName)) { return meta = _field; } var cached = hasCachedFieldInstance(_field); if (cached) { return result[fieldName] = cached; } return result[fieldName] = parseObjectField(fieldName, _field, { deep: deep }); } catch (err) { debugger; throw new RuntimeError("Failed to process object field \"".concat(fieldName, "\":\n").concat(err.message), { err: err.stack, input: input }); } }); meta = meta || createEmptyMetaField(); if (!omitMeta) { result[objectMetaFieldKey] = meta; } return { definition: result, meta: meta }; } function isFinalFieldDefinition(input) { return typeof (input === null || input === void 0 ? void 0 : input.type) === 'string'; } function isListDefinition(input) { if (Array.isArray(input) && input.length === 1) return true; if (!isProduction()) { var _input$forEach; // verify against old enum definition input === null || input === void 0 ? void 0 : (_input$forEach = input.forEach) === null || _input$forEach === void 0 ? void 0 : _input$forEach.call(input, function (el) { if (typeof el === 'string' && !isStringFieldDefinition(el)) { throw new Error("Plain array is used only for union definitions.\n" + " \"".concat(el, "\" is not valid as union item.\n") + " You can use { enum: ['".concat(el, "'] } instead of ['").concat(el, "'].")); } }); } return false; } /** * Object as field['type'] is deprecated * @param input */ export function isObjectAsTypeDefinition(input) { return input && _typeof(input) === 'object' && isObject(input.type); } var validFlattenDefinitionKeys = { defaultValue: 'any', description: 'string', hidden: 'boolean', list: 'boolean', name: 'string', optional: 'boolean' }; var validFlattenDefinitionKeysList = getKeys(validFlattenDefinitionKeys); export function parseFlattenFieldDefinition(input) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var deep = options.deep; if (getTypeName(input) !== 'Object') return false; if (input.type !== undefined) return false; var type; var def; for (var k in input) { var valueOfDefOrOptionalOrListOrDescription = input[k]; if (types[k]) { type = k; def = valueOfDefOrOptionalOrListOrDescription; if (k !== 'object' && def && _typeof(def) === 'object') { for (var defKey in def) { if (defKey === 'def' || validFlattenDefinitionKeys[defKey]) { console.warn("using field def as type definition?\n", { def: def, type: k }); return false; } } } } else { if (valueOfDefOrOptionalOrListOrDescription !== undefined) { var acceptAny = validFlattenDefinitionKeys[k] === 'any'; if (!acceptAny && // checking if the de `optional` or `list` or `description` // has the expected types _typeof(valueOfDefOrOptionalOrListOrDescription) !== validFlattenDefinitionKeys[k]) { return false; } } } } var description = input.description, _input$optional = input.optional, optional = _input$optional === void 0 ? false : _input$optional, _input$list = input.list, list = _input$list === void 0 ? false : _input$list, defaultValue = input.defaultValue, name = input.name, hidden = input.hidden; return parseFieldDefinitionConfig({ def: def, defaultValue: defaultValue, description: description, hidden: hidden, list: list, name: name, optional: optional, type: type }, { deep: deep }); } export var CACHED_FIELD_INSTANCE_KEY = '__cachedFieldInstance'; export function __getCachedFieldInstance(field) { if (field !== null && field !== void 0 && field[CACHED_FIELD_INSTANCE_KEY]) { return field[CACHED_FIELD_INSTANCE_KEY]; } var parsed = parseFieldDefinitionConfig(field); var instanceFromDef = fieldInstanceFromDef(parsed); setCachedFieldInstance(parsed, instanceFromDef); return instanceFromDef; } function hasCachedFieldInstance(field) { return !!(field !== null && field !== void 0 && field[CACHED_FIELD_INSTANCE_KEY]) ? field : null; } function setCachedFieldInstance(field, instanceFromDef) { if (hasCachedFieldInstance(field)) return; Object.defineProperty(field, CACHED_FIELD_INSTANCE_KEY, { configurable: false, enumerable: false, value: instanceFromDef, writable: false }); } export function deleteCachedFieldInstance(def) { if (!def || _typeof(def) !== 'object') return def; var _ref6 = def, _ = _ref6[CACHED_FIELD_INSTANCE_KEY], rest = _objectWithoutProperties(_ref6, [CACHED_FIELD_INSTANCE_KEY].map(_toPropertyKey)); return rest; // if (currentDepth > depth) return def; // // Object.entries(rest).reduce((acc, [key, value]) => { // return { // ...acc, // [key]: value, // }; // }, rest); // // return rest; } //# sourceMappingURL=parseObjectDefinition.js.map