import { DMMF } from '@prisma/generator-helper'; import { checkIsModelRelationField, checkModelHasManyModelRelation } from './model-helpers'; export function addMissingInputObjectTypesForSelect( inputObjectTypes: DMMF.InputType[], outputObjectTypes: DMMF.OutputType[], models: DMMF.Model[], ) { // generate input object types necessary to support ModelSelect._count const modelCountOutputTypes = getModelCountOutputTypes(outputObjectTypes); const modelCountOutputTypeSelectInputObjectTypes = generateModelCountOutputTypeSelectInputObjectTypes(modelCountOutputTypes); const modelCountOutputTypeArgsInputObjectTypes = generateModelCountOutputTypeArgsInputObjectTypes(modelCountOutputTypes); const modelSelectInputObjectTypes = generateModelSelectInputObjectTypes(models); const generatedInputObjectTypes = [ modelCountOutputTypeSelectInputObjectTypes, modelCountOutputTypeArgsInputObjectTypes, modelSelectInputObjectTypes, ].flat(); for (const inputObjectType of generatedInputObjectTypes) { inputObjectTypes.push(inputObjectType); } } function getModelCountOutputTypes(outputObjectTypes: DMMF.OutputType[]) { return outputObjectTypes.filter(({ name }) => name.includes('CountOutputType'), ); } function generateModelCountOutputTypeSelectInputObjectTypes( modelCountOutputTypes: DMMF.OutputType[], ) { const modelCountOutputTypeSelectInputObjectTypes: DMMF.InputType[] = []; for (const modelCountOutputType of modelCountOutputTypes) { const { name: modelCountOutputTypeName, fields: modelCountOutputTypeFields, } = modelCountOutputType; const modelCountOutputTypeSelectInputObjectType: DMMF.InputType = { name: `${modelCountOutputTypeName}Select`, constraints: { maxNumFields: null, minNumFields: null, }, fields: modelCountOutputTypeFields.map(({ name }) => ({ name, isRequired: false, isNullable: false, inputTypes: [ { isList: false, type: `Boolean`, location: 'scalar', }, ], })), }; modelCountOutputTypeSelectInputObjectTypes.push( modelCountOutputTypeSelectInputObjectType, ); } return modelCountOutputTypeSelectInputObjectTypes; } function generateModelCountOutputTypeArgsInputObjectTypes( modelCountOutputTypes: DMMF.OutputType[], ) { const modelCountOutputTypeArgsInputObjectTypes: DMMF.InputType[] = []; for (const modelCountOutputType of modelCountOutputTypes) { const { name: modelCountOutputTypeName } = modelCountOutputType; const modelCountOutputTypeArgsInputObjectType: DMMF.InputType = { name: `${modelCountOutputTypeName}Args`, constraints: { maxNumFields: null, minNumFields: null, }, fields: [ { name: 'select', isRequired: false, isNullable: false, inputTypes: [ { isList: false, type: `${modelCountOutputTypeName}Select`, location: 'inputObjectTypes', namespace: 'prisma', }, ], }, ], }; modelCountOutputTypeArgsInputObjectTypes.push( modelCountOutputTypeArgsInputObjectType, ); } return modelCountOutputTypeArgsInputObjectTypes; } function generateModelSelectInputObjectTypes(models: DMMF.Model[]) { const modelSelectInputObjectTypes: DMMF.InputType[] = []; for (const model of models) { const { name: modelName, fields: modelFields } = model; const fields: DMMF.SchemaArg[] = []; for (const modelField of modelFields) { const { name: modelFieldName, isList, type } = modelField; const isRelationField = checkIsModelRelationField(modelField); const field: DMMF.SchemaArg = { name: modelFieldName, isRequired: false, isNullable: false, inputTypes: [{ isList: false, type: 'Boolean', location: 'scalar' }], }; if (isRelationField) { let schemaArgInputType: DMMF.SchemaArgInputType = { isList: false, type: isList ? `${type}FindManyArgs` : `${type}Args`, location: 'inputObjectTypes', namespace: 'prisma', }; field.inputTypes.push(schemaArgInputType); } fields.push(field); } const hasManyRelationToAnotherModel = checkModelHasManyModelRelation(model); const shouldAddCountField = hasManyRelationToAnotherModel; if (shouldAddCountField) { const _countField: DMMF.SchemaArg = { name: '_count', isRequired: false, isNullable: false, inputTypes: [ { isList: false, type: 'Boolean', location: 'scalar' }, { isList: false, type: `${modelName}CountOutputTypeArgs`, location: 'inputObjectTypes', namespace: 'prisma', }, ], }; fields.push(_countField); } const modelSelectInputObjectType: DMMF.InputType = { name: `${modelName}Select`, constraints: { maxNumFields: null, minNumFields: null, }, fields, }; modelSelectInputObjectTypes.push(modelSelectInputObjectType); } return modelSelectInputObjectTypes; }