From 5dc839d63dc0c9dcdb362f2ca6cc99b4b0b4263d Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Thu, 11 Jul 2019 09:07:49 +0800 Subject: [PATCH] add assertShape to validate templateElement --- .../scripts/utils/stringifyValidator.js | 13 +++++++++ .../babel-types/src/definitions/es2015.js | 6 +++- packages/babel-types/src/definitions/utils.js | 29 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/babel-types/scripts/utils/stringifyValidator.js b/packages/babel-types/scripts/utils/stringifyValidator.js index ff33e8e25ade..e146dcaff56a 100644 --- a/packages/babel-types/scripts/utils/stringifyValidator.js +++ b/packages/babel-types/scripts/utils/stringifyValidator.js @@ -31,6 +31,19 @@ module.exports = function stringifyValidator(validator, nodePrefix) { return validator.type; } + if (validator.shapeOf) { + return ( + "{" + + Object.keys(validator.shapeOf) + .map( + shapeKey => + shapeKey + ":" + stringifyValidator(validator.shapeOf[shapeKey]) + ) + .join(", ") + + "}" + ); + } + return ["any"]; }; diff --git a/packages/babel-types/src/definitions/es2015.js b/packages/babel-types/src/definitions/es2015.js index fb42b1390583..ea2390d3f42a 100644 --- a/packages/babel-types/src/definitions/es2015.js +++ b/packages/babel-types/src/definitions/es2015.js @@ -1,5 +1,6 @@ // @flow import defineType, { + assertShape, assertNodeType, assertValueType, chain, @@ -537,7 +538,10 @@ defineType("TemplateElement", { builder: ["value", "tail"], fields: { value: { - // todo: flatten `raw` into main node + validate: assertShape({ + raw: assertValueType("string"), + cooked: assertValueType("string"), + }), }, tail: { validate: assertValueType("boolean"), diff --git a/packages/babel-types/src/definitions/utils.js b/packages/babel-types/src/definitions/utils.js index c1d2ce762daa..ee8541f45517 100644 --- a/packages/babel-types/src/definitions/utils.js +++ b/packages/babel-types/src/definitions/utils.js @@ -161,6 +161,35 @@ export function assertValueType(type: string): Validator { return validate; } +export function assertShape(shape: {| [string]: Validator |}): Validator { + function validate(node, key, val) { + const errors = []; + for (const property of Object.keys(shape)) { + try { + const validator = shape[property]; + validator(node, property, val[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; +} + export function chain(...fns: Array): Validator { function validate(...args) { for (const fn of fns) {