rttc
Version:
Runtime type-checking for JavaScript.
56 lines (46 loc) • 2.06 kB
JavaScript
/**
* Module dependencies
*/
var util = require('util');
var _ = require('@sailshq/lodash');
var hydrate = require('./hydrate');
/**
* A variation on JSON.parse that also takes care of a few additional
* edge-cases including eval-ing stringified functions.
*
* TODO: if `typeSchema` is provided, also coerce the decoded value to match.
*
* @param {String} value
* @param {*} typeSchema - optionally provide `typeSchema` so that it can be used to improve the accuracy of the deserialized result (specifically it is necessary to eval lamda functions)
* @param {Boolean} unsafeMode - enable to use `eval` to hydrate stringified functions based on `typeSchema` (this is not safe to use on user-provided input and so is disabled by default)
* @return {*}
*/
module.exports = function parse (value, typeSchema, unsafeMode) {
// `unsafeMode` is disabled by default
unsafeMode = unsafeMode || false;
if (!_.isString(value)) {
throw new Error('rttc.decode() expects a string value, but a '+typeof value+' was provided:'+util.inspect(value, false, null));
}
if (unsafeMode && _.isUndefined(typeSchema)) {
throw new Error('rttc.decode() cannot enable `unsafeMode` without also providing a `typeSchema`.');
}
var deserializedVal;
// Attempt to parse provided JSON-encoded value
try {
deserializedVal = JSON.parse(value);
}
catch (e) {
throw new Error('Could not JSON.parse() provided value: '+value);
}
// Deserialize any lamda functions that exist in the provided input value
// (but only in `unsafeMode`, and if `typeSchema` is provided)
//
// If this is a lamda type, or something which MIGHT contain a lamda type
// (i.e. nested array or dictionary type schema), we must recursively iterate over the
// type schema looking for lamda types, and when we find them, parse input values as
// stringified machine fn bodies, converting them to hydrated JavaScript functions.
if (unsafeMode) {
deserializedVal = hydrate(deserializedVal, typeSchema);
}
return deserializedVal;
};