@terabits/grapi
Version:
Grapi Schema Generator For GraphQL Server
373 lines (372 loc) • 20.4 kB
JavaScript
"use strict";
exports.__esModule = true;
var __1 = require("..");
var constants_1 = require("../constants");
var type_1 = require("../dataModel/type");
var lodash_1 = require("../lodash");
var constants_2 = require("./constants");
var utils_1 = require("./utils");
var UNDERSCORE = '_';
var DOUBLE_UNDERSCORE = '__';
var WhereInputPlugin = (function () {
function WhereInputPlugin() {
}
WhereInputPlugin.prototype.visitModel = function (model, context) {
if (model.isObjectType()) {
return;
}
var root = context.root;
var modelWhereInputName = this.getWhereInputName(model);
var whereInput = "input ".concat(modelWhereInputName, " {\n OR: [").concat(modelWhereInputName, "!]\n AND: [").concat(modelWhereInputName, "!]\n ").concat(this.createWhereFilter(root, model.getFields()), "\n }");
root.addInput(whereInput);
var modelWhereUniqueInputName = this.getWhereUniqueInputName(model);
var whereUniqueInput = "input ".concat(modelWhereUniqueInputName, " {\n ").concat(this.createWhereUniqueFilter(model.getName(), model.getFields()), "\n }");
root.addInput(whereUniqueInput);
};
WhereInputPlugin.prototype.getWhereInputName = function (model) {
return "".concat(model.getNamings().capitalSingular, "WhereInput");
};
WhereInputPlugin.prototype.getWhereUniqueInputName = function (model) {
return "".concat(model.getNamings().capitalSingular, "WhereUniqueInput");
};
WhereInputPlugin.prototype.parseUniqueWhere = function (where) {
if ((0, lodash_1.isEmpty)(where)) {
throw new Error('You provided an invalid argument for the where selector on Entity. Please provide exactly one unique field and value.');
}
return (0, lodash_1.mapValues)(where, function (value) {
var _a;
return _a = {}, _a[__1.Operator.eq] = value, _a;
});
};
WhereInputPlugin.prototype.parseWhere = function (where, model) {
return WhereInputPlugin.parseWhereIterate(where, model);
};
WhereInputPlugin.parseWhereIterate = function (where, model) {
var _this = this;
return (0, lodash_1.reduce)(where, function (result, value, key) {
var _a, _b;
if (key === __1.Operator.or || key === __1.Operator.and) {
value = (0, lodash_1.map)(value, function (where) {
return _this.parseWhereIterate(where, model);
});
return _a = {}, _a[key] = value, _a;
}
var operator = WhereInputPlugin.getNameAndOperator(key).operator;
var fieldName = WhereInputPlugin.getNameAndOperator(key).fieldName;
var field = model.getField(fieldName);
if (field && field.getType() === type_1.DataModelType.RELATION) {
var relationTo = field.getRelationTo();
var metadataField = (0, utils_1.parseRelationConfig)(field.getRelationConfig());
var filter = void 0;
if (field.isList()) {
if ((0, lodash_1.size)(value) > 1) {
throw new Error("There can be only one input field named Filter".concat(field.getTypename()));
}
var some = value.some, none = value.none, every = value.every;
if (some) {
filter = "some";
}
else if (none) {
filter = "none";
}
else {
filter = "every";
}
value = some || none || every;
}
result[fieldName] = {
filters: WhereInputPlugin.parseWhereIterate(value, relationTo),
sourceKey: (0, lodash_1.get)(model.getMetadata(constants_1.MODEL_DIRECTIVE), constants_1.MODEL_DIRECTIVE_SOURCE_KEY),
targetKey: (0, lodash_1.get)(relationTo.getMetadata(constants_1.MODEL_DIRECTIVE), constants_1.MODEL_DIRECTIVE_SOURCE_KEY),
relation: {
foreignKey: (0, lodash_1.get)(metadataField, "foreignKey"),
source: model.getName(),
target: relationTo.getName(),
side: (0, lodash_1.get)(metadataField, "side"),
list: field.isList(),
filter: filter,
ship: field.getRelation(),
type: field.getRelationType()
}
};
return result;
}
if (result[fieldName]) {
throw new Error("There can be only one input field named ".concat(fieldName, "_").concat(operator));
}
if (field && field.getType() === type_1.DataModelType.OBJECT) {
(0, lodash_1.forEach)(value, function (val, key) {
var _a, _b;
var operator = WhereInputPlugin.getNameAndOperator(key).operator;
var subFieldName = WhereInputPlugin.getNameAndOperator(key).fieldName;
if (key === "elementMatch") {
var emResult_1 = {};
(0, lodash_1.forEach)(val, function (val, key) {
var _a;
var operator = WhereInputPlugin.getNameAndOperator(key).operator;
var fieldName = WhereInputPlugin.getNameAndOperator(key).fieldName;
emResult_1[fieldName] = (_a = {}, _a[operator] = val, _a);
});
result[fieldName] = (_a = {}, _a["elementMatchObject"] = emResult_1, _a);
}
else
result["".concat(fieldName, ".").concat(subFieldName)] = (_b = {}, _b[operator] = val, _b);
});
return result;
}
if (field.isList()) {
if ((0, lodash_1.size)(value) > 1) {
throw new Error("There can be only one input field named Filter".concat(field.getTypename()));
}
result[fieldName] = _this.parseFilterListScalar(value);
return result;
}
result[fieldName] = (_b = {}, _b[operator] = value, _b);
return result;
}, {});
};
WhereInputPlugin.parseFilterListScalar = function (where) {
var _this = this;
var resValue = {};
(0, lodash_1.forEach)(where, function (value, filter) {
var op = '';
var val = value;
switch (filter) {
case "has":
op = __1.Operator.all;
val = value || [];
break;
case "hasNot":
op = __1.Operator.notIn;
val = value || [];
break;
case "gt":
op = __1.Operator.gt;
break;
case "gte":
op = __1.Operator.gte;
break;
case "lt":
op = __1.Operator.lt;
break;
case "lte":
op = __1.Operator.lte;
break;
case "size":
op = __1.Operator.size;
break;
case "elementMatch":
op = __1.Operator.elementMatch;
val = _this.parseFilterListScalar(val);
break;
}
resValue[op] = val;
});
return resValue;
};
WhereInputPlugin.getNameAndOperator = function (field) {
field = field.replace(DOUBLE_UNDERSCORE, '.');
var lastUnderscoreIndex = field.lastIndexOf(UNDERSCORE);
if (lastUnderscoreIndex < 0) {
return {
fieldName: field,
operator: __1.Operator.eq
};
}
var operator = field.slice(lastUnderscoreIndex + 1);
var validOperator = __1.Operator[operator];
if (!validOperator) {
throw new Error("Operator ".concat(operator, " no support"));
}
var fieldName = field.slice(0, lastUnderscoreIndex);
return { fieldName: fieldName, operator: validOperator };
};
WhereInputPlugin.prototype.createWhereFilter = function (root, fields, prefix) {
var _this = this;
if (prefix === void 0) { prefix = ''; }
var inputFields = [];
var objectFilters = [];
(0, lodash_1.forEach)(fields, function (field, name) {
var fieldName = prefix + name;
var typeName = field.getTypename();
if (field.isList()) {
switch (field.getType()) {
case type_1.DataModelType.INT:
case type_1.DataModelType.FLOAT:
root.addInput("input FilterScalar".concat(typeName, "ElementMatch {\n ").concat("gt", ": ").concat(typeName, "\n ").concat("gte", ": ").concat(typeName, "\n ").concat("lt", ": ").concat(typeName, "\n ").concat("lte", ": ").concat(typeName, "\n }"));
root.addInput("input FilterScalar".concat(typeName, "List { \n ").concat("has", ": [ ").concat(typeName, " ! ]\n ").concat("hasNot", ": [ ").concat(typeName, " ! ]\n ").concat("gt", ": ").concat(typeName, "\n ").concat("gte", ": ").concat(typeName, "\n ").concat("lt", ": ").concat(typeName, "\n ").concat("lte", ": ").concat(typeName, "\n ").concat("size", ": Int\n ").concat("elementMatch", ": FilterScalar").concat(typeName, "ElementMatch\n }"));
inputFields.push({
fieldName: fieldName,
type: "FilterScalar".concat(typeName, "List")
});
break;
case type_1.DataModelType.ENUM:
case type_1.DataModelType.STRING:
case type_1.DataModelType.ID:
root.addInput("input FilterScalar".concat(typeName, "List { \n ").concat("has", ": [ ").concat(typeName, " ! ]\n ").concat("hasNot", ": [ ").concat(typeName, " ! ]\n ").concat("size", ": Int\n }"));
inputFields.push({
fieldName: fieldName,
type: "FilterScalar".concat(typeName, "List")
});
break;
case type_1.DataModelType.CUSTOM_SCALAR:
root.addInput("input FilterScalar".concat(typeName, "List { \n ").concat("has", ": [ ").concat(typeName, " ! ]\n ").concat("hasNot", ": [ ").concat(typeName, " ! ]\n }"));
inputFields = WhereInputPlugin.createWhereFilterListCustomScalars(inputFields, typeName, fieldName);
break;
case type_1.DataModelType.RELATION:
root.addInput("input Filter".concat(typeName, " { \n some: ").concat(typeName, "WhereInput \n every: ").concat(typeName, "WhereInput \n none: ").concat(typeName, "WhereInput \n }"));
inputFields.push({
fieldName: fieldName,
type: "Filter".concat(typeName)
});
break;
case type_1.DataModelType.OBJECT:
var objectFields = field.getFields();
root.addInput("input FilterObject".concat(typeName, "ElementMatch {\n ").concat(_this.createWhereFilter(root, objectFields), "\n }"));
root.addInput("input FilterObject".concat(typeName, "List {\n ").concat(_this.createWhereFilter(root, objectFields), "\n ").concat("elementMatch", ": FilterObject").concat(typeName, "ElementMatch\n }"));
inputFields.push({
fieldName: fieldName,
type: "FilterObject".concat(typeName, "List")
});
break;
}
}
else {
switch (field.getType()) {
case type_1.DataModelType.STRING:
inputFields.push.apply(inputFields, WhereInputPlugin.parseEqFilter(fieldName, typeName));
inputFields.push.apply(inputFields, WhereInputPlugin.parseContainsFilter(fieldName, typeName));
inputFields.push.apply(inputFields, WhereInputPlugin.parseInFilter(fieldName, typeName));
break;
case type_1.DataModelType.INT:
inputFields.push.apply(inputFields, WhereInputPlugin.parseEqFilter(fieldName, typeName));
inputFields.push.apply(inputFields, WhereInputPlugin.parseGtLtInFilter(fieldName, typeName));
inputFields.push({
fieldName: "".concat(fieldName, "_between"), type: constants_2.inputIntBetweenName
});
break;
case type_1.DataModelType.FLOAT:
inputFields.push.apply(inputFields, WhereInputPlugin.parseEqFilter(fieldName, typeName));
inputFields.push.apply(inputFields, WhereInputPlugin.parseGtLtInFilter(fieldName, typeName));
inputFields.push({
fieldName: "".concat(fieldName, "_between"), type: constants_2.inputFloatBetweenName
});
break;
case type_1.DataModelType.ENUM:
inputFields.push.apply(inputFields, WhereInputPlugin.parseEqFilter(fieldName, typeName));
inputFields.push.apply(inputFields, WhereInputPlugin.parseContainsFilter(fieldName, 'String'));
break;
case type_1.DataModelType.ID:
inputFields.push.apply(inputFields, WhereInputPlugin.parseEqFilter(fieldName, typeName));
inputFields.push.apply(inputFields, WhereInputPlugin.parseInFilter(fieldName, typeName));
break;
case type_1.DataModelType.BOOLEAN:
inputFields.push.apply(inputFields, WhereInputPlugin.parseEqFilter(fieldName, typeName));
break;
case type_1.DataModelType.CUSTOM_SCALAR:
inputFields = WhereInputPlugin.createWhereFilterCustomScalars(inputFields, typeName, fieldName);
break;
case type_1.DataModelType.RELATION:
inputFields.push({
fieldName: fieldName,
type: "".concat(typeName, "WhereInput")
});
break;
case type_1.DataModelType.OBJECT:
var objectFields = field.getFields();
root.addInput("input FilterObject".concat(typeName, "List {\n ").concat(_this.createWhereFilter(root, objectFields), "\n }"));
inputFields.push({
fieldName: fieldName,
type: "FilterObject".concat(typeName, "List")
});
break;
}
}
});
var iFieldsStr = inputFields.map(function (_a) {
var fieldName = _a.fieldName, type = _a.type;
return "".concat(fieldName, ": ").concat(type);
}).join(' ');
return "".concat(iFieldsStr, " ").concat(objectFilters);
};
WhereInputPlugin.createWhereFilterListCustomScalars = function (inputFields, typeName, name) {
switch (typeName) {
case type_1.DataModelType.URL:
case type_1.DataModelType.EMAIL:
case type_1.DataModelType.JSON:
inputFields.push({
fieldName: name,
type: "FilterScalar".concat(typeName, "List")
});
break;
case type_1.DataModelType.DATE_TIME:
break;
}
return inputFields;
};
WhereInputPlugin.createWhereFilterCustomScalars = function (inputFields, typeName, name) {
switch (typeName) {
case type_1.DataModelType.URL:
case type_1.DataModelType.EMAIL:
inputFields.push.apply(inputFields, WhereInputPlugin.parseEqFilter(name, typeName));
inputFields.push.apply(inputFields, WhereInputPlugin.parseContainsFilter(name, typeName));
break;
case type_1.DataModelType.DATE_TIME:
inputFields.push.apply(inputFields, WhereInputPlugin.parseEqFilter(name, typeName));
inputFields.push.apply(inputFields, WhereInputPlugin.parseGtLtInFilter(name, typeName));
inputFields.push({
fieldName: "".concat(name, "_between"), type: constants_2.inputDateTimeBetweenName
});
break;
case type_1.DataModelType.JSON:
inputFields.push.apply(inputFields, WhereInputPlugin.parseObjectFilter(name, typeName));
break;
}
return inputFields;
};
WhereInputPlugin.prototype.createWhereUniqueFilter = function (modelName, fields) {
var inputFields = [];
(0, lodash_1.forEach)(fields, function (field, name) {
if (field.isUnique()) {
inputFields.push({
fieldName: name,
type: field.getTypename()
});
}
});
if ((0, lodash_1.isEmpty)(fields)) {
throw new Error("no unique field find in model ".concat(modelName));
}
return inputFields.map(function (_a) {
var fieldName = _a.fieldName, type = _a.type;
return "".concat(fieldName, ": ").concat(type);
}).join(' ');
};
WhereInputPlugin.parseEqFilter = function (name, type) {
return [{ fieldName: name, type: type }, { fieldName: "".concat(name, "_eq"), type: type }, { fieldName: "".concat(name, "_neq"), type: type }];
};
WhereInputPlugin.parseContainsFilter = function (name, type) {
return [{ fieldName: "".concat(name, "_contains"), type: type }, { fieldName: "".concat(name, "_notcontains"), type: type }];
};
WhereInputPlugin.parseInFilter = function (name, type) {
return [
{ fieldName: "".concat(name, "_in"), type: "[ ".concat(type, " ]") }
];
};
WhereInputPlugin.parseGtLtInFilter = function (name, type) {
return [
{ fieldName: "".concat(name, "_gt"), type: type },
{ fieldName: "".concat(name, "_gte"), type: type },
{ fieldName: "".concat(name, "_lt"), type: type },
{ fieldName: "".concat(name, "_lte"), type: type },
{ fieldName: "".concat(name, "_in"), type: "[ ".concat(type, " ]") }
];
};
WhereInputPlugin.parseObjectFilter = function (name, type) {
return [
{ fieldName: "".concat(name, "_object"), type: type }
];
};
return WhereInputPlugin;
}());
exports["default"] = WhereInputPlugin;