UNPKG

@grapi/server

Version:

Grapi Schema Generator For GraphQL Server

215 lines (214 loc) 9.87 kB
"use strict"; 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;