Skip to content

Commit

Permalink
Fix strict value for date and number
Browse files Browse the repository at this point in the history
  • Loading branch information
zeandcode committed Jun 25, 2018
1 parent 69a68f9 commit c92d653
Show file tree
Hide file tree
Showing 2 changed files with 543 additions and 500 deletions.
132 changes: 65 additions & 67 deletions src/utils/parser.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"use strict";
'use strict'

const loGet = require("lodash/get");
const loValues = require("lodash/values");
const moment = require("moment");
const detector = require("./detector");
const extractMapKey = require("./mapkey_extractor");
const loGet = require('lodash/get')
const loValues = require('lodash/values')
const nilValue = require('lodash/isNil')
const moment = require('moment')
const detector = require('./detector')
const extractMapKey = require('./mapkey_extractor')
const {
STRING,
STRING_ONLY,
Expand All @@ -27,70 +28,66 @@ const {
nonNullableTypes,
isPredefinedTypes,
isDeleteProperty
} = require("../datatypes");
} = require('../datatypes')

const validDateFromString = (dateVal, utcAware = true) => {
if (detector.isString(dateVal)) {
try {
// detect ISO 8601
const date = utcAware ? moment(dateVal) : moment.utc(dateVal)
if (date.isValid()) return date
} catch (err) {
return false
}
}
return false
}

const parser = {
[STRING]: val => {
if (detector.isString(val) && val.length) return val;
const parsed = val ? JSON.stringify(val) : null;
return detector.isString(parsed) && parsed.length > 0 ? parsed : null;
if (detector.isString(val) && val.length) return val
const parsed = val ? JSON.stringify(val) : null
return detector.isString(parsed) && parsed.length > 0 ? parsed : null
},
[ARRAY]: val => (detector.isArray(val) ? val : null),
[BOOLEAN]: val => (detector.isBoolean(val) ? val : null),
[DATE]: val => {
if (detector.isDate(val)) return val;
if (detector.isString(val)) {
try {
// detect ISO 8601
const date = moment(val);
if (date.isValid()) return date;
} catch (err) {
return null;
}
}
return null;
if (detector.isDate(val)) return val
return validDateFromString(val) || null
},
[DATE_PLAIN]: val => {
if (detector.isDate(val)) return val;
if (detector.isString(val)) {
try {
// detect ISO 8601
const date = moment.utc(val); // unaware timezone, all parses with utc timezone
if (date.isValid()) return date;
} catch (err) {
return null;
}
}
return null;
if (detector.isDate(val)) return val
return validDateFromString(val, false) || null
},
[FUNCTION]: val => (detector.isFunction(val) ? val : null),
[NUMBER]: val => {
if (detector.isNumber(val)) return val;
if (detector.isNumber(val)) return val
if (!isNaN(val)) {
return detector.isStringFloat(val) ? parseFloat(val) : parseInt(val);
return detector.isStringFloat(val) ? parseFloat(val) : parseInt(val)
}
return null;
return null
},
[OBJECT]: val => (detector.isObject ? val : null),
[ANY]: val => val
};
}

const nonNullableChecker = {
[STRING_ONLY]: val => detector.isString(val),
[ARRAY_ONLY]: val => detector.isArray(val),
[BOOLEAN_ONLY]: val => detector.isBoolean(val),
[DATE_ONLY]: val => detector.isDate(val),
[DATE_PLAIN_ONLY]: val => detector.isDate(val),
[DATE_ONLY]: val => detector.isDate(val) || validDateFromString(val) !== null,
[DATE_PLAIN_ONLY]: val =>
detector.isDate(val) || validDateFromString(val, false) !== null,
[FUNCTION_ONLY]: val => detector.isFunction(val),
[NUMBER_ONLY]: val => {
if (!isNaN(val)) {
return detector.isStringFloat(val) ? parseFloat(val) : parseInt(val);
return detector.isStringFloat(val) ? parseFloat(val) : parseInt(val)
}

return false;
return false
},
[OBJECT_ONLY]: val => detector.isObject(val)
};
}

const nonNullableParser = {
[STRING_ONLY]: val => parser[STRING](val),
Expand All @@ -101,66 +98,67 @@ const nonNullableParser = {
[FUNCTION_ONLY]: val => parser[FUNCTION](val),
[NUMBER_ONLY]: val => parser[NUMBER](val),
[OBJECT_ONLY]: val => parser[OBJECT](val)
};
}

const valueParser = (schema, valuesToParse) => {
const parsedValues = {};
const parsedValues = {}
Object.keys(schema).forEach(key => {
const valueType = schema[key];
if (isDeleteProperty(valueType)) return;
const valueType = schema[key]
if (isDeleteProperty(valueType)) return

const [srcKey, mapKey] = extractMapKey(key);
if (mapKey !== null) key = mapKey;
const [srcKey, mapKey] = extractMapKey(key)
if (mapKey !== null) key = mapKey

const value = detector.isUndefined(valuesToParse)
? valuesToParse
: valuesToParse[srcKey !== null ? srcKey : key];
: valuesToParse[srcKey !== null ? srcKey : key]

if (!detector.isUndefined(value) || detector.isJKTObject(valueType)) {
if (parserableTypes(valueType) && !detector.isJKTObject(valueType)) {
parsedValues[key] = parser[valueType](value);
parsedValues[key] = parser[valueType](value)
} else if (detector.isJKTObject(valueType)) {
// handle jkt obj
parsedValues[key] = valueParser(valueType.__schema, value);
parsedValues[key] = valueParser(valueType.__schema, value)
} else if (detector.isENUMObject(valueType)) {
// handle enum
const validEnumValues = loValues(valueType.j());
parsedValues[key] = validEnumValues.includes(value) ? value : null;
const validEnumValues = loValues(valueType.j())
parsedValues[key] = validEnumValues.includes(value) ? value : null
} else if (detector.isTranslatorObject(valueType)) {
// handle translator
parsedValues[key] = valueType.translate(value);
parsedValues[key] = valueType.translate(value)
} else if (nonNullableTypes(valueType)) {
if (nonNullableChecker[valueType](value))
parsedValues[key] = nonNullableParser[valueType](value);
if (!nilValue(nonNullableChecker[valueType](value))) {
parsedValues[key] = nonNullableParser[valueType](value)
}
} else if (valueType.isContainer) {
// struct inside of container
parsedValues[key] = valueType.parse(valueParser, value);
parsedValues[key] = valueType.parse(valueParser, value)
} else {
parsedValues[key] = value;
parsedValues[key] = value
}
} else if (!parserableTypes(valueType) && isPredefinedTypes(valueType)) {
// Do not parse enum value
if (!detector.isENUMObject(valueType)) {
// the predefined type is container type
// so we put value handled with its container here
if (valueType.isContainer) {
parsedValues[key] = valueType.parse(valueParser, value);
parsedValues[key] = valueType.parse(valueParser, value)
} else {
// custom defined values from the begining of struct creation
parsedValues[key] = valueType;
parsedValues[key] = valueType
}
}
} else {
// Value was undefined or not matched with available schema
if (!nonNullableTypes(valueType)) parsedValues[key] = null;
if (!nonNullableTypes(valueType)) parsedValues[key] = null
}
});
return parsedValues;
};
})
return parsedValues
}

const parse = baseSchema => {
return valuesToParse => valueParser(baseSchema, valuesToParse);
};
return valuesToParse => valueParser(baseSchema, valuesToParse)
}

module.exports = parse;
module.exports.valueParser = valueParser;
module.exports = parse
module.exports.valueParser = valueParser
Loading

0 comments on commit c92d653

Please sign in to comment.