| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { |
| value: true |
| }); |
| exports.VISITOR_KEYS = exports.NODE_PARENT_VALIDATIONS = exports.NODE_FIELDS = exports.FLIPPED_ALIAS_KEYS = exports.DEPRECATED_KEYS = exports.BUILDER_KEYS = exports.ALIAS_KEYS = void 0; |
| exports.arrayOf = arrayOf; |
| exports.arrayOfType = arrayOfType; |
| exports.assertEach = assertEach; |
| exports.assertNodeOrValueType = assertNodeOrValueType; |
| exports.assertNodeType = assertNodeType; |
| exports.assertOneOf = assertOneOf; |
| exports.assertOptionalChainStart = assertOptionalChainStart; |
| exports.assertShape = assertShape; |
| exports.assertValueType = assertValueType; |
| exports.chain = chain; |
| exports.default = defineType; |
| exports.defineAliasedType = defineAliasedType; |
| exports.typeIs = typeIs; |
| exports.validate = validate; |
| exports.validateArrayOfType = validateArrayOfType; |
| exports.validateOptional = validateOptional; |
| exports.validateOptionalType = validateOptionalType; |
| exports.validateType = validateType; |
| |
| var _is = require("../validators/is"); |
| |
| var _validate = require("../validators/validate"); |
| |
| const VISITOR_KEYS = {}; |
| exports.VISITOR_KEYS = VISITOR_KEYS; |
| const ALIAS_KEYS = {}; |
| exports.ALIAS_KEYS = ALIAS_KEYS; |
| const FLIPPED_ALIAS_KEYS = {}; |
| exports.FLIPPED_ALIAS_KEYS = FLIPPED_ALIAS_KEYS; |
| const NODE_FIELDS = {}; |
| exports.NODE_FIELDS = NODE_FIELDS; |
| const BUILDER_KEYS = {}; |
| exports.BUILDER_KEYS = BUILDER_KEYS; |
| const DEPRECATED_KEYS = {}; |
| exports.DEPRECATED_KEYS = DEPRECATED_KEYS; |
| const NODE_PARENT_VALIDATIONS = {}; |
| exports.NODE_PARENT_VALIDATIONS = NODE_PARENT_VALIDATIONS; |
| |
| function getType(val) { |
| if (Array.isArray(val)) { |
| return "array"; |
| } else if (val === null) { |
| return "null"; |
| } else { |
| return typeof val; |
| } |
| } |
| |
| function validate(validate) { |
| return { |
| validate |
| }; |
| } |
| |
| function typeIs(typeName) { |
| return typeof typeName === "string" ? assertNodeType(typeName) : assertNodeType(...typeName); |
| } |
| |
| function validateType(typeName) { |
| return validate(typeIs(typeName)); |
| } |
| |
| function validateOptional(validate) { |
| return { |
| validate, |
| optional: true |
| }; |
| } |
| |
| function validateOptionalType(typeName) { |
| return { |
| validate: typeIs(typeName), |
| optional: true |
| }; |
| } |
| |
| function arrayOf(elementType) { |
| return chain(assertValueType("array"), assertEach(elementType)); |
| } |
| |
| function arrayOfType(typeName) { |
| return arrayOf(typeIs(typeName)); |
| } |
| |
| function validateArrayOfType(typeName) { |
| return validate(arrayOfType(typeName)); |
| } |
| |
| function assertEach(callback) { |
| function validator(node, key, val) { |
| if (!Array.isArray(val)) return; |
| |
| for (let i = 0; i < val.length; i++) { |
| const subkey = `${key}[${i}]`; |
| const v = val[i]; |
| callback(node, subkey, v); |
| if (process.env.BABEL_TYPES_8_BREAKING) (0, _validate.validateChild)(node, subkey, v); |
| } |
| } |
| |
| validator.each = callback; |
| return validator; |
| } |
| |
| function assertOneOf(...values) { |
| function validate(node, key, val) { |
| if (values.indexOf(val) < 0) { |
| throw new TypeError(`Property ${key} expected value to be one of ${JSON.stringify(values)} but got ${JSON.stringify(val)}`); |
| } |
| } |
| |
| validate.oneOf = values; |
| return validate; |
| } |
| |
| function assertNodeType(...types) { |
| function validate(node, key, val) { |
| for (const type of types) { |
| if ((0, _is.default)(type, val)) { |
| (0, _validate.validateChild)(node, key, val); |
| return; |
| } |
| } |
| |
| throw new TypeError(`Property ${key} of ${node.type} expected node to be of a type ${JSON.stringify(types)} but instead got ${JSON.stringify(val == null ? void 0 : val.type)}`); |
| } |
| |
| validate.oneOfNodeTypes = types; |
| return validate; |
| } |
| |
| function assertNodeOrValueType(...types) { |
| function validate(node, key, val) { |
| for (const type of types) { |
| if (getType(val) === type || (0, _is.default)(type, val)) { |
| (0, _validate.validateChild)(node, key, val); |
| return; |
| } |
| } |
| |
| throw new TypeError(`Property ${key} of ${node.type} expected node to be of a type ${JSON.stringify(types)} but instead got ${JSON.stringify(val == null ? void 0 : val.type)}`); |
| } |
| |
| validate.oneOfNodeOrValueTypes = types; |
| return validate; |
| } |
| |
| function assertValueType(type) { |
| function validate(node, key, val) { |
| const valid = getType(val) === type; |
| |
| if (!valid) { |
| throw new TypeError(`Property ${key} expected type of ${type} but got ${getType(val)}`); |
| } |
| } |
| |
| validate.type = type; |
| return validate; |
| } |
| |
| function assertShape(shape) { |
| function validate(node, key, val) { |
| const errors = []; |
| |
| for (const property of Object.keys(shape)) { |
| try { |
| (0, _validate.validateField)(node, property, val[property], shape[property]); |
| } catch (error) { |
| if (error instanceof TypeError) { |
| errors.push(error.message); |
| continue; |
| } |
| |
| throw error; |
| } |
| } |
| |
| if (errors.length) { |
| throw new TypeError(`Property ${key} of ${node.type} expected to have the following:\n${errors.join("\n")}`); |
| } |
| } |
| |
| validate.shapeOf = shape; |
| return validate; |
| } |
| |
| function assertOptionalChainStart() { |
| function validate(node) { |
| var _current; |
| |
| let current = node; |
| |
| while (node) { |
| const { |
| type |
| } = current; |
| |
| if (type === "OptionalCallExpression") { |
| if (current.optional) return; |
| current = current.callee; |
| continue; |
| } |
| |
| if (type === "OptionalMemberExpression") { |
| if (current.optional) return; |
| current = current.object; |
| continue; |
| } |
| |
| break; |
| } |
| |
| throw new TypeError(`Non-optional ${node.type} must chain from an optional OptionalMemberExpression or OptionalCallExpression. Found chain from ${(_current = current) == null ? void 0 : _current.type}`); |
| } |
| |
| return validate; |
| } |
| |
| function chain(...fns) { |
| function validate(...args) { |
| for (const fn of fns) { |
| fn(...args); |
| } |
| } |
| |
| validate.chainOf = fns; |
| |
| if (fns.length >= 2 && "type" in fns[0] && fns[0].type === "array" && !("each" in fns[1])) { |
| throw new Error(`An assertValueType("array") validator can only be followed by an assertEach(...) validator.`); |
| } |
| |
| return validate; |
| } |
| |
| const validTypeOpts = ["aliases", "builder", "deprecatedAlias", "fields", "inherits", "visitor", "validate"]; |
| const validFieldKeys = ["default", "optional", "validate"]; |
| |
| function defineAliasedType(...aliases) { |
| return (type, opts = {}) => { |
| let defined = opts.aliases; |
| |
| if (!defined) { |
| var _store$opts$inherits$, _defined; |
| |
| if (opts.inherits) defined = (_store$opts$inherits$ = store[opts.inherits].aliases) == null ? void 0 : _store$opts$inherits$.slice(); |
| (_defined = defined) != null ? _defined : defined = []; |
| opts.aliases = defined; |
| } |
| |
| const additional = aliases.filter(a => !defined.includes(a)); |
| defined.unshift(...additional); |
| return defineType(type, opts); |
| }; |
| } |
| |
| function defineType(type, opts = {}) { |
| const inherits = opts.inherits && store[opts.inherits] || {}; |
| let fields = opts.fields; |
| |
| if (!fields) { |
| fields = {}; |
| |
| if (inherits.fields) { |
| const keys = Object.getOwnPropertyNames(inherits.fields); |
| |
| for (const key of keys) { |
| const field = inherits.fields[key]; |
| const def = field.default; |
| |
| if (Array.isArray(def) ? def.length > 0 : def && typeof def === "object") { |
| throw new Error("field defaults can only be primitives or empty arrays currently"); |
| } |
| |
| fields[key] = { |
| default: Array.isArray(def) ? [] : def, |
| optional: field.optional, |
| validate: field.validate |
| }; |
| } |
| } |
| } |
| |
| const visitor = opts.visitor || inherits.visitor || []; |
| const aliases = opts.aliases || inherits.aliases || []; |
| const builder = opts.builder || inherits.builder || opts.visitor || []; |
| |
| for (const k of Object.keys(opts)) { |
| if (validTypeOpts.indexOf(k) === -1) { |
| throw new Error(`Unknown type option "${k}" on ${type}`); |
| } |
| } |
| |
| if (opts.deprecatedAlias) { |
| DEPRECATED_KEYS[opts.deprecatedAlias] = type; |
| } |
| |
| for (const key of visitor.concat(builder)) { |
| fields[key] = fields[key] || {}; |
| } |
| |
| for (const key of Object.keys(fields)) { |
| const field = fields[key]; |
| |
| if (field.default !== undefined && builder.indexOf(key) === -1) { |
| field.optional = true; |
| } |
| |
| if (field.default === undefined) { |
| field.default = null; |
| } else if (!field.validate && field.default != null) { |
| field.validate = assertValueType(getType(field.default)); |
| } |
| |
| for (const k of Object.keys(field)) { |
| if (validFieldKeys.indexOf(k) === -1) { |
| throw new Error(`Unknown field key "${k}" on ${type}.${key}`); |
| } |
| } |
| } |
| |
| VISITOR_KEYS[type] = opts.visitor = visitor; |
| BUILDER_KEYS[type] = opts.builder = builder; |
| NODE_FIELDS[type] = opts.fields = fields; |
| ALIAS_KEYS[type] = opts.aliases = aliases; |
| aliases.forEach(alias => { |
| FLIPPED_ALIAS_KEYS[alias] = FLIPPED_ALIAS_KEYS[alias] || []; |
| FLIPPED_ALIAS_KEYS[alias].push(type); |
| }); |
| |
| if (opts.validate) { |
| NODE_PARENT_VALIDATIONS[type] = opts.validate; |
| } |
| |
| store[type] = opts; |
| } |
| |
| const store = {}; |