UNPKG

@backland/schema

Version:

TypeScript schema declaration and validation library with static type inference

453 lines (448 loc) 18.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CACHED_FIELD_INSTANCE_KEY = void 0; exports.__getCachedFieldInstance = __getCachedFieldInstance; exports._parserHooks = void 0; exports.deleteCachedFieldInstance = deleteCachedFieldInstance; exports.isObjectAsTypeDefinition = isObjectAsTypeDefinition; exports.parseField = parseField; exports.parseFieldDefinitionConfig = parseFieldDefinitionConfig; exports.parseFlattenFieldDefinition = parseFlattenFieldDefinition; exports.parseObjectDefinition = parseObjectDefinition; exports.parseObjectField = parseObjectField; exports.setParserHook = setParserHook; var _utils = require("@backland/utils"); var _GraphType = require("./GraphType/GraphType"); var _ObjectType = require("./ObjectType"); var _fieldInstanceFromDef = require("./fieldInstanceFromDef"); var _FieldType = require("./fields/FieldType"); var _LiteralField = require("./fields/LiteralField"); var _MetaFieldField = require("./fields/MetaFieldField"); var _fieldTypes = require("./fields/fieldTypes"); var _parseStringDefinition = require("./parseStringDefinition"); 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); } var _parserHooks = []; exports._parserHooks = _parserHooks; 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; } 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 = (0, _fieldInstanceFromDef.fieldInstanceFromDef)(parsed); setCachedFieldInstance(parsed, instanceFromDef); if (instanceFromDef.def) { parsed.def = instanceFromDef.def; } if (returnInstance) { return instanceFromDef; } if (parsed) return parsed; throw new _utils.RuntimeError("field \"".concat(fieldName, "\": invalid definition."), { definition: definition, parsed: parsed }); } function parseField(definition) { return parseObjectField('__parseField__', definition); } var stringifiableDefKeys = new Set(['type', 'list', 'optional' // ]); 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.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.GraphType.is(definition)) { var def = parseFieldDefinitionConfig(definition.definition, { deep: deep }); def.hidden = def.hidden || definition.hidden; return def; } if (_GraphType.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 ((0, _parseStringDefinition.isStringFieldDefinition)(definition)) { return (0, _parseStringDefinition.parseStringDefinition)(definition); } if ((0, _FieldType.isFieldInstance)(definition)) { return definition.asFinalFieldDef; } if (isFinalFieldDefinition(definition)) { if (definition.type === 'object') { if (_typeof(definition.def) !== 'object' || !definition.def) { throw new _utils.RuntimeError("Missing def for object field.", { definition: definition }); } if ((0, _ObjectType.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 ((0, _ObjectType.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((0, _utils.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; } } 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 = (0, _utils.getKeys)(input); keys.forEach(function (fieldName) { try { var _field = input[fieldName]; if ((0, _MetaFieldField.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 _utils.RuntimeError("Failed to process object field \"".concat(fieldName, "\":\n").concat(err.message), { err: err.stack, input: input }); } }); meta = meta || (0, _MetaFieldField.createEmptyMetaField)(); if (!omitMeta) { result[_MetaFieldField.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 (!(0, _utils.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' && !(0, _parseStringDefinition.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 */ function isObjectAsTypeDefinition(input) { return input && _typeof(input) === 'object' && (0, _ObjectType.isObject)(input.type); } var validFlattenDefinitionKeys = { defaultValue: 'any', description: 'string', hidden: 'boolean', list: 'boolean', name: 'string', optional: 'boolean' }; var validFlattenDefinitionKeysList = (0, _utils.getKeys)(validFlattenDefinitionKeys); function parseFlattenFieldDefinition(input) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var deep = options.deep; if ((0, _utils.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 (_fieldTypes.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 }); } var CACHED_FIELD_INSTANCE_KEY = '__cachedFieldInstance'; exports.CACHED_FIELD_INSTANCE_KEY = CACHED_FIELD_INSTANCE_KEY; 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 = (0, _fieldInstanceFromDef.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 }); } 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