Add Enum and DateTime support in aggregation and drop lodash

This commit is contained in:
Kamal Bennani 2018-06-25 06:50:16 +02:00
parent fecf5c8ac4
commit aedf09bdcb
No known key found for this signature in database
GPG Key ID: 4513063CDB1A1C25
2 changed files with 47 additions and 34 deletions

View File

@ -48,4 +48,4 @@
"npm": ">= 5.3.0" "npm": ">= 5.3.0"
}, },
"license": "MIT" "license": "MIT"
} }

View File

@ -28,36 +28,57 @@ module.exports = {
type === 'Int' || type === 'Int' ||
type === 'Float' || type === 'Float' ||
type === 'String' || type === 'String' ||
type === 'Boolean' type === 'Boolean' ||
type === 'DateTime'
); );
}, },
/**
* Checks if the field is of type enum
*/
isEnumType: (_type) => {
return _.startsWith(_type, 'ENUM_');
},
/** /**
* Returns all fields that are not of type array * Returns all fields that are not of type array
* *
* @returns {Boolean} * @returns {Boolean}
* *
* @example * @example
* *
* isNotOfTypeArray([String]) * isNotOfTypeArray([String])
* // => false * // => false
* isNotOfTypeArray(String!) * isNotOfTypeArray(String!)
* // => true * // => true
*/ */
isNotOfTypeArray: (_type) => { isNotOfTypeArray: (type) => {
const arrayRegexp = /(\[\w+\])/; return !/(\[\w+!?\])/.test(type);
const type = _type.replace('!', ''); },
return !arrayRegexp.test(type);
/**
* Returns all fields of type Integer or float
*/
isNumberType: (type) => {
return type === 'Int' || type === 'Float';
}, },
/** /**
* Convert non-primitive type to string (non-primitive types corresponds to a reference to an other model) * Convert non-primitive type to string (non-primitive types corresponds to a reference to an other model)
* *
* extractType(String!)
* // => String
*
* extractType(user)
* // => ID
*
* @returns {String} * @returns {String}
*/ */
extractType: function (_type) { extractType: function (_type) {
return this.isPrimitiveType(_type) return this.isPrimitiveType(_type)
? _type.replace('!', '') ? _type.replace('!', '')
: this.isEnumType(_type)
? 'String'
: 'ID'; : 'ID';
}, },
@ -93,11 +114,12 @@ module.exports = {
* @return {Object} * @return {Object}
*/ */
createFieldsResolver: function(fields, resolver, typeCheck) { createFieldsResolver: function(fields, resolver, typeCheck) {
return _.reduce(fields, (acc, field, key) => { return Object.keys(fields).reduce((acc, fieldKey) => {
const field = fields[fieldKey];
// Check if the field is of the correct type // Check if the field is of the correct type
if (typeCheck(field)) { if (typeCheck(field)) {
return _.set(acc, key, (obj, options, context) => { return _.set(acc, fieldKey, (obj, options, context) => {
return resolver(obj, options, context, this.fieldResolver(field, key), key, obj, field); return resolver(obj, options, context, this.fieldResolver(field, fieldKey), fieldKey, obj, field);
}); });
} }
return acc; return acc;
@ -232,6 +254,10 @@ module.exports = {
* age: Float * age: Float
* } * }
* *
* type UserAggregateAvg {
* age: Float
* }
*
* type UserGroupBy { * type UserGroupBy {
* username: [UserConnectionUsername] * username: [UserConnectionUsername]
* age: [UserConnectionAge] * age: [UserConnectionAge]
@ -323,12 +349,9 @@ module.exports = {
connection: `${globalId}Connection`, connection: `${globalId}Connection`,
})); }));
let connectionFieldsTypes = ''; return Object.keys(primitiveFields).map((fieldKey) =>
_.forEach(primitiveFields, (fieldValue, fieldKey) => { `type ${globalId}Connection${_.upperFirst(fieldKey)} {${this.formatGQL(connectionFields[fieldKey])}}`
connectionFieldsTypes += `type ${globalId}Connection${_.upperFirst(fieldKey)} {${this.formatGQL(connectionFields[fieldKey])}}\n\n`; ).join('\n\n');
});
return connectionFieldsTypes;
}, },
formatConnectionGroupBy: function(fields, model, name) { formatConnectionGroupBy: function(fields, model, name) {
@ -359,9 +382,7 @@ module.exports = {
const { globalId } = model; const { globalId } = model;
// Extract all fields of type Integer and Float and change their type to Float // Extract all fields of type Integer and Float and change their type to Float
const numericFields = this.getFieldsByTypes(fields, (fieldType) => { const numericFields = this.getFieldsByTypes(fields, this.isNumberType, () => 'Float');
return fieldType === 'Int' || fieldType === 'Float';
}, () => 'Float');
// Don't create an aggregator field if the model has not number fields // Don't create an aggregator field if the model has not number fields
const aggregatorGlobalId = `${globalId}Aggregator`; const aggregatorGlobalId = `${globalId}Aggregator`;
@ -414,18 +435,10 @@ module.exports = {
resolvers = { resolvers = {
...resolvers, ...resolvers,
[`${aggregatorGlobalId}Sum`]: this.createAggregationFieldsResolver(model, fields, 'sum', (fieldType) => { [`${aggregatorGlobalId}Sum`]: this.createAggregationFieldsResolver(model, fields, 'sum', this.isNumberType),
return fieldType === 'Int' || fieldType === 'Float'; [`${aggregatorGlobalId}Avg`]: this.createAggregationFieldsResolver(model, fields, 'avg', this.isNumberType),
}), [`${aggregatorGlobalId}Min`]: this.createAggregationFieldsResolver(model, fields, 'min', this.isNumberType),
[`${aggregatorGlobalId}Avg`]: this.createAggregationFieldsResolver(model, fields, 'avg', (fieldType) => { [`${aggregatorGlobalId}Max`]: this.createAggregationFieldsResolver(model, fields, 'max', this.isNumberType)
return fieldType === 'Int' || fieldType === 'Float';
}),
[`${aggregatorGlobalId}Min`]: this.createAggregationFieldsResolver(model, fields, 'min', (fieldType) => {
return fieldType === 'Int' || fieldType === 'Float';
}),
[`${aggregatorGlobalId}Max`]: this.createAggregationFieldsResolver(model, fields, 'max', (fieldType) => {
return fieldType === 'Int' || fieldType === 'Float';
})
}; };
} }
@ -758,7 +771,7 @@ module.exports = {
ctx.params.where ctx.params.where
); );
return controller({ ...ctx, ...queryOpts }, next); return controller(Object.assign({}, ctx, queryOpts), next);
}; };
})(); })();