@grapi/server
Version:
Grapi Schema Generator For GraphQL Server
215 lines (214 loc) • 9.87 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const dataModel_1 = require("../dataModel");
const objectField_1 = __importDefault(require("../dataModel/objectField"));
const type_1 = require("../dataModel/type");
const lodash_1 = require("../lodash");
const baseType_1 = __importDefault(require("./baseType"));
const whereInput_1 = __importDefault(require("./whereInput"));
const createObjectInputField = (prefix, field, context) => {
const { root } = context;
const content = [];
(0, lodash_1.forEach)(field.getFields(), (nestedField, name) => {
if (nestedField.isScalar()) {
content.push(`${name}: ${nestedField.getTypename()}`);
return;
}
if (nestedField instanceof objectField_1.default) {
const fieldWithPrefix = `${prefix}${(0, lodash_1.upperFirst)(name)}`;
const typeFields = createObjectInputField(fieldWithPrefix, nestedField, context);
const objectInputName = `${fieldWithPrefix}CreateInput`;
root.addInput(`input ${objectInputName} {
${typeFields.join(' ')}
}`);
content.push(`${name}: ${objectInputName}`);
return;
}
});
return content;
};
const createInputField = (model, context, getCreateInputName, getWhereInputName, getWhereUniqueInputName, getMutationFactoryFromModel, withoutField = undefined, recursive = true) => {
const { root } = context;
const capName = model.getNamings().capitalSingular;
const fields = model.getFields();
const content = [];
const mutationFactory = getMutationFactoryFromModel(model);
const relationInputs = (relationNamings, relationName, relationTo, fieldName, isList, exceptionField = undefined) => {
(0, lodash_1.forEach)(relationTo.getFields(), (modelField, keyField) => {
if ((modelField instanceof dataModel_1.RelationField && modelField.getRelationName() === relationName)) {
exceptionField = keyField;
return false;
}
});
const relationField = (0, lodash_1.capitalize)(exceptionField);
const relationInput = `${relationNamings}CreateWithout${relationField}Input`;
const inputField = createInputField(relationTo, context, getCreateInputName, getWhereInputName, getWhereUniqueInputName, relationTo.getCreateMutationFactory, exceptionField, false);
const relationCreateInput = `${relationNamings}Create${isList ? `Many` : `One`}Without${relationField}Input`;
const whereUnique = `${getWhereUniqueInputName(relationTo)}`;
root.addInput(`input ${relationInput} {
${inputField}
}`);
root.addInput(`input ${relationCreateInput} {
create: ${isList ? `[${relationInput}]` : `${relationInput}`}
connect: ${isList ? `[${whereUnique}]` : `${whereUnique}`}
}`);
content.push(`${fieldName}: ${relationCreateInput}`);
};
(0, lodash_1.forEach)(fields, (field, name) => {
if (field.isAutoGenerated()) {
return;
}
if (withoutField && withoutField === name) {
return;
}
if (field.isScalar()) {
let fieldType;
if (field.isList()) {
const listOperationInput = `${field.getTypename()}ListFieldCreateInput`;
root.addInput(`input ${listOperationInput} {
set: [${field.getTypename()}]
}`);
fieldType = listOperationInput;
mutationFactory.markArrayField(name);
}
else {
fieldType = field.getTypename();
}
content.push(`${name}: ${fieldType}`);
return;
}
if (field instanceof objectField_1.default) {
const fieldWithPrefix = `${capName}${(0, lodash_1.upperFirst)(name)}`;
const typeFields = createObjectInputField(fieldWithPrefix, field, context);
const objectInputName = `${fieldWithPrefix}CreateInput`;
root.addInput(`input ${objectInputName} {
${typeFields.join(' ')}
}`);
let fieldType;
if (field.isList()) {
const listOperationInput = `${fieldWithPrefix}CreateListInput`;
root.addInput(`input ${listOperationInput} {
set: [ ${objectInputName} ]
}`);
fieldType = listOperationInput;
mutationFactory.markArrayField(name);
}
else {
fieldType = objectInputName;
}
content.push(`${name}: ${fieldType}`);
return;
}
const isRelation = field instanceof dataModel_1.RelationField;
const isList = field.isList();
if (isRelation && !isList) {
const relationTo = field.getRelationTo();
const relationType = field.getRelationType();
const relationName = field.getRelationName();
const relationNamings = relationTo.getNamings().capitalSingular;
if (recursive && relationType === dataModel_1.RelationType.biOneToOne) {
relationInputs(relationNamings, relationName, relationTo, name, false);
}
else {
const relationInputName = `${relationTo.getTypename()}CreateOneInput`;
root.addInput(`input ${relationInputName} {
create: ${getCreateInputName(relationTo)}
connect: ${getWhereUniqueInputName(relationTo)}
}`);
content.push(`${name}: ${relationInputName}`);
}
return;
}
if (isRelation && isList) {
const relationTo = field.getRelationTo();
const relationType = field.getRelationType();
const relationName = field.getRelationName();
const relationNamings = relationTo.getNamings().capitalSingular;
if (recursive && relationType === dataModel_1.RelationType.biOneToMany || relationType === dataModel_1.RelationType.biManyToMany) {
relationInputs(relationNamings, relationName, relationTo, name, true);
}
else {
const relationInputName = `${relationTo.getTypename()}CreateManyInput`;
root.addInput(`input ${relationInputName} {
create: [${getCreateInputName(relationTo)}]
connect: [${getWhereUniqueInputName(relationTo)}]
}`);
content.push(`${name}: ${relationInputName}`);
}
return;
}
});
return content;
};
class CreatePlugin {
whereInputPlugin;
baseTypePlugin;
hook;
constructor({ hook, }) {
this.hook = hook;
}
setPlugins(plugins) {
this.whereInputPlugin = plugins.find(plugin => plugin instanceof whereInput_1.default);
this.baseTypePlugin = plugins.find(plugin => plugin instanceof baseType_1.default);
}
visitModel(model, context) {
const { root } = context;
const modelType = this.baseTypePlugin.getTypename(model);
const directives = model.getDirectives(dataModel_1.DirectiveModelAction.Create);
const mutationName = CreatePlugin.getMutationName(model);
const inputName = this.generateCreateInput(model, context);
root.addMutation(`${mutationName}( data: ${inputName}! ): ${modelType}!${directives}`);
}
resolveInMutation({ model, dataSource }) {
const mutationName = CreatePlugin.getMutationName(model);
const wrapCreate = (0, lodash_1.get)(this.hook, [model.getName(), 'wrapCreate']);
return {
[mutationName]: async (root, args, context) => {
const data = this.setDateDirective(model, args.data);
if (!wrapCreate) {
return dataSource.create(this.createMutation(model, data), context);
}
const createContext = {
data,
response: {},
graphqlContext: context,
};
await wrapCreate(createContext, async (ctx) => {
ctx.response = await dataSource.create(this.createMutation(model, ctx.data), context);
});
return createContext.response;
},
};
}
getCreateInputName(model) {
return `${model.getNamings().capitalSingular}CreateInput`;
}
generateCreateInput(model, context) {
const inputName = this.getCreateInputName(model);
const inputField = createInputField(model, context, this.getCreateInputName, this.whereInputPlugin.getWhereInputName, this.whereInputPlugin.getWhereUniqueInputName, model.getCreateMutationFactory);
const input = `input ${inputName} { ${inputField} }`;
context.root.addInput(input);
return inputName;
}
static getMutationName(model) {
return `create${model.getNamings().capitalSingular}`;
}
createMutation = (model, payload) => {
const mutationFactory = model.getCreateMutationFactory();
return mutationFactory.createMutation(payload);
};
setDateDirective = (model, data) => {
const fields = model.getFields();
const now = new Date();
(0, lodash_1.forEach)(fields, (field, name) => {
if ((field.isCreatedAt() || field.isUpdatedAt()) && field.getTypename() === type_1.DataModelType.DATE_TIME) {
data[name] = now;
}
});
return data;
};
}
exports.default = CreatePlugin;