simple-graphql
Version:
The simple way to generates GraphQL schemas and Sequelize models from your models definition.
216 lines • 7.86 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const lodash_1 = __importDefault(require("lodash"));
function fieldToSelection(field) {
const index = field.indexOf('.');
if (index === -1) {
return { name: field };
}
else {
return {
name: field.substr(0, index),
selections: [fieldToSelection(field.substr(index + 1))]
};
}
}
function getOrderFields(order) {
if (Array.isArray(order)) {
return order
.map((orderItem) => {
if (Array.isArray(orderItem)) {
const column = orderItem[0];
if (typeof column === 'string') {
return column;
}
}
//避免null的检查
return '&#$&';
})
.filter((orderItem) => orderItem !== '&#$&');
}
else {
return [];
}
}
/*
排序设置中的字段, 如果是["a.b.c", "desc"]格式, 转换成
[{ model: A; as: 'a' }, { model: B; as: 'b' } ,"c","desc"]
*/
function convertOrderItem(sgContext, schema, orderItem) {
const [column, sort] = orderItem;
const [first, ...other] = column.split('.');
const ass = schema.config.associations;
const iConfig = ass.belongsTo[first] || ass.hasOne[first] || ass.hasMany[first];
if (iConfig) {
const model = sgContext.models[iConfig.target];
return [
{
model: model,
as: first
},
...convertOrderItem(sgContext, model.sgSchema, [other.join('.'), sort])
];
}
else {
return orderItem;
}
}
function convertOrder(sgContext, schema, order, parents) {
function patchParent(item) {
if (Array.isArray(item)) {
return [...parents, ...item];
}
else {
return [...parents, item];
}
}
if (Array.isArray(order)) {
return order.map((orderItem) => {
if (Array.isArray(orderItem)) {
const [column, sort] = orderItem;
if (typeof column === 'string') {
return patchParent(convertOrderItem(sgContext, schema, [column, sort]));
}
else {
return patchParent(orderItem);
}
}
else {
return patchParent([orderItem]);
}
});
}
return [patchParent(order)];
}
const buildQueryOption = function (args) {
const { sgContext, schema, attributes, selections, eagerHasMany, parents = [] } = args;
const parseAttributesOption = sgContext.models[schema.name].parseAttributes({
attributes: attributes || [],
selections: selections
});
let additionOrder = [];
const include = (() => {
const copy = (i) => {
if (typeof i === 'object' && i.as != null) {
return Object.assign({}, i);
}
else {
return i;
}
};
if (Array.isArray(args.include)) {
return args.include.map((i) => copy(i));
}
else if (args.include) {
return [copy(args.include)];
}
else {
return [];
}
})();
for (let selection of [
...(selections || []),
...parseAttributesOption.additionSelections
]) {
const hasOneOrBelongsToConfig = schema.config.associations.belongsTo[selection.name] ||
schema.config.associations.hasOne[selection.name];
const hasManyConfig = schema.config.associations.hasMany[selection.name];
let config = hasOneOrBelongsToConfig;
if (!hasOneOrBelongsToConfig && eagerHasMany) {
if ((hasManyConfig === null || hasManyConfig === void 0 ? void 0 : hasManyConfig.outputStructure) === 'Array' &&
(hasManyConfig.conditionFields == null ||
lodash_1.default.keys(hasManyConfig.conditionFields).length === 0)) {
config = hasManyConfig;
// add hasManyConfig order config
const targetModel = sgContext.models[hasManyConfig.target];
additionOrder.push(...convertOrder(sgContext, targetModel.sgSchema, hasManyConfig.order || [['id', 'ASC']], [
{
model: targetModel,
as: selection.name
}
]));
}
}
if (config) {
const exit = (() => {
return include.find((i) => i.as === selection.name);
})();
const targetModel = sgContext.models[config.target];
const option = buildQueryOption({
sgContext: sgContext,
attributes: (exit === null || exit === void 0 ? void 0 : exit.attributes) || [],
include: (exit === null || exit === void 0 ? void 0 : exit.include) || [],
schema: targetModel.sgSchema,
selections: selection.selections,
parents: [
...parents,
{
model: targetModel,
as: selection.name
}
],
eagerHasMany: eagerHasMany
});
if (exit) {
exit.include = option.include;
exit.attributes = option.attributes;
additionOrder = lodash_1.default.unionBy(additionOrder, option.additionOrder, JSON.stringify);
}
else {
include.push({
model: sgContext.models[config.target],
as: selection.name,
include: option.include,
attributes: option.attributes,
required: false
});
additionOrder = lodash_1.default.unionBy(additionOrder, option.additionOrder, JSON.stringify);
}
}
}
return {
include: include,
attributes: parseAttributesOption.attributes,
additionOrder: additionOrder
};
};
function default_1(args) {
const dbModel = this;
const { include = [], attributes = [], order = [], info, path, eagerHasMany = true } = args;
const fragments = (info === null || info === void 0 ? void 0 : info.fragments) || {};
const sgContext = this.getSGContext();
let selections = [];
if (info === null || info === void 0 ? void 0 : info.fieldNodes) {
info.fieldNodes.forEach((node) => {
selections = lodash_1.default.union(selections, dbModel.parseSelections(fragments, node.selectionSet && node.selectionSet.selections));
});
}
if (path) {
path.split('.').forEach((p) => {
selections = lodash_1.default.flatten(selections.filter((s) => s.name === p).map((t) => t.selections || []));
});
}
selections = [
...selections,
...lodash_1.default.union(attributes || [], getOrderFields(order)).map((field) => fieldToSelection(field))
];
const mainOrder = convertOrder(sgContext, dbModel.sgSchema, order, []);
const option = buildQueryOption({
sgContext: sgContext,
include: include,
schema: dbModel.sgSchema,
selections: selections,
eagerHasMany: eagerHasMany
});
// console.log(require('util').inspect(option, {depth: 20}))
return {
include: option.include,
attributes: option.attributes,
order: lodash_1.default.unionBy(mainOrder, option.additionOrder, JSON.stringify)
};
}
exports.default = default_1;
//# sourceMappingURL=resolveQueryOption.js.map