flow-immutable-models
Version:
Generates model classes from Flow types using Immutable.js
85 lines (74 loc) • 4.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = toJS;
var _isModelTypeReference = require('./isModelTypeReference');
var _isModelTypeReference2 = _interopRequireDefault(_isModelTypeReference);
var _flowTypes = require('./flowTypes');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function toArrayExpression(j, memberExpression, isReference) {
var arrayExpression = j.callExpression(j.memberExpression(memberExpression, j.identifier('toArray')), []);
if (isReference) {
arrayExpression = j.callExpression(j.memberExpression(arrayExpression, j.identifier('map')), [j.arrowFunctionExpression([j.identifier('item')], j.callExpression(j.memberExpression(j.identifier('item'), j.identifier('toJS')), []))]);
}
return arrayExpression;
}
function toObjectExpression(j, memberExpression, isReference) {
var mappedExpression = memberExpression;
if (isReference) {
mappedExpression = j.callExpression(j.memberExpression(memberExpression, j.identifier('map')), [j.arrowFunctionExpression([j.identifier('item')], j.callExpression(j.memberExpression(j.identifier('item'), j.identifier('toJS')), []))]);
}
return j.callExpression(j.memberExpression(mappedExpression, j.identifier('toObject')), []);
}
function getReturnObjectProp(j, prop) {
var propName = prop.key.name;
var typeAlias = prop.value;
var isReference = (0, _isModelTypeReference2.default)(typeAlias);
var memberExpression = j.memberExpression(j.identifier('this'), j.identifier(propName));
var valueExpression = memberExpression;
if (isReference) {
valueExpression = j.callExpression(j.memberExpression(memberExpression, j.identifier('toJS')), []);
} else {
valueExpression = memberExpression;
}
var isNullable = typeAlias.type === 'NullableTypeAnnotation';
var alias = isNullable ? typeAlias.typeAnnotation : typeAlias;
if ((0, _flowTypes.isArray)(alias)) {
valueExpression = toArrayExpression(j, memberExpression, isReference);
} else if ((0, _flowTypes.isObjectMap)(alias)) {
valueExpression = toObjectExpression(j, memberExpression, isReference);
}
if (valueExpression !== memberExpression && (isNullable || prop.optional)) {
valueExpression = j.conditionalExpression(memberExpression, valueExpression, memberExpression);
}
return valueExpression;
}
function toJS(j, className, props) {
var toJSIdentifier = j.identifier('toJS');
var modelTypeAnnotation = j.typeAnnotation(j.genericTypeAnnotation(j.identifier(className + 'ModelType'), null));
var maybeProps = props.filter(function (prop) {
return prop.optional;
});
var notMaybeProps = props.filter(function (prop) {
return !prop.optional;
});
var objExpression = j.objectExpression(notMaybeProps.map(function (prop) {
return j.property('init', j.identifier(prop.key.name), getReturnObjectProp(j, prop));
}));
var blockStatements = void 0;
if (maybeProps.length === 0) {
blockStatements = [j.returnStatement(objExpression)];
} else {
blockStatements = [j.variableDeclaration('const', [j.variableDeclarator(Object.assign({}, j.identifier('js'), {
typeAnnotation: modelTypeAnnotation
}), objExpression)])].concat(_toConsumableArray(maybeProps.map(function (maybeProp) {
var assignment = j.assignmentExpression('=', j.memberExpression(j.identifier('js'), j.identifier(maybeProp.key.name)), getReturnObjectProp(j, maybeProp));
return j.ifStatement(j.binaryExpression('!=', j.memberExpression(j.identifier('this'), j.identifier(maybeProp.key.name)), j.identifier('null')), j.blockStatement([j.expressionStatement(assignment)]), null);
})), [j.returnStatement(j.identifier('js'))]);
}
var func = j.functionExpression(null, [], j.blockStatement(blockStatements));
func.returnType = modelTypeAnnotation;
return j.methodDefinition('method', toJSIdentifier, func, false);
}