UNPKG

@muban/muban

Version:

Writing components for server-rendered HTML

84 lines (83 loc) 3.67 kB
import parseJson from 'json-parse-better-errors'; import dedent from 'ts-dedent'; export function convertSourceValue(propInfo, value) { switch (propInfo.type) { // eslint-disable-next-line default-case-last default: case String: { return value; } case Number: { if (!value) { return undefined; } // TODO, (how) should we support integers? // maybe allow convertors as well, and use type to set some default convertors? // or are validators enough? const converted = parseFloat(value); // eslint-disable-next-line no-restricted-globals if (isNaN(converted) || !isFinite(converted)) { // eslint-disable-next-line no-console console.warn(dedent `The property "${propInfo.name}" of type "${propInfo.type.name}" has possible invalid value. Received "${value}", parsed into "${converted}". Returning "undefined"`); return undefined; } return converted; } case Boolean: { if (value === '') { // Developers might expect boolean attributes to work: // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes // but we choose to be explicit to make this easier to implement in the CMS // eslint-disable-next-line no-console console.warn(dedent `The property "${propInfo.name}" of type "${propInfo.type.name}" has an empty value, so is set to "false". Please provide explicit "true" or "false" as a value for booleans.`); } return value.toLowerCase() === 'true'; } case Date: { if (!value) { return undefined; } const converted = new Date(value); // eslint-disable-next-line no-restricted-globals if (isNaN(converted.getTime())) { // eslint-disable-next-line no-console console.warn(dedent `The property "${propInfo.name}" of type "${propInfo.type.name}" has possible invalid value. Received "${value}", parsed into "${converted}". Returning "undefined".`); return undefined; } return converted; } case Array: case Object: { if (!value) { return undefined; } try { const converted = parseJson(value); if (propInfo.type === Array && !Array.isArray(converted)) { // eslint-disable-next-line no-console console.warn(dedent `The property "${propInfo.name}" of type "${propInfo.type.name}" is not an Array. Received "${value}", parsed into "${converted}. Returning "undefined""`); return []; } if (propInfo.type === Object && !(converted instanceof Object)) { // eslint-disable-next-line no-console console.warn(dedent `The property "${propInfo.name}" of type "${propInfo.type.name}" is not an Object. Received "${value}", parsed into "${converted}. Returning "undefined""`); } return converted; } catch (error) { // eslint-disable-next-line no-console console.error(error); return undefined; } } } }