| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const { camelCase, upperFirst, lowerFirst, pipe, get } = require('lodash/fp'); | 
					
						
							| 
									
										
										
										
											2021-09-23 17:25:25 +02:00
										 |  |  | const { singular } = require('pluralize'); | 
					
						
							| 
									
										
										
										
											2021-10-27 18:54:58 +02:00
										 |  |  | const { ApplicationError } = require('@strapi/utils').errors; | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | module.exports = ({ strapi }) => { | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build a type name for a enum based on a content type & an attribute name | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @param {string} attributeName | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getEnumName = (contentType, attributeName) => { | 
					
						
							| 
									
										
										
										
											2021-09-30 15:25:33 +02:00
										 |  |  |     const { attributes } = contentType; | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  |     const { enumName } = attributes[attributeName]; | 
					
						
							| 
									
										
										
										
											2021-09-30 15:25:33 +02:00
										 |  |  |     const { modelType } = contentType; | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-30 15:25:33 +02:00
										 |  |  |     const typeName = | 
					
						
							|  |  |  |       modelType === 'component' ? getComponentName(contentType) : getTypeName(contentType); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const defaultEnumName = `ENUM_${typeName.toUpperCase()}_${attributeName.toUpperCase()}`; | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return enumName || defaultEnumName; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build the base type name for a given content type | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							| 
									
										
										
										
											2021-09-07 11:23:49 +02:00
										 |  |  |    * @param {object} options | 
					
						
							|  |  |  |    * @param {'singular' | 'plural'} options.plurality | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2021-09-07 11:23:49 +02:00
										 |  |  |   const getTypeName = (contentType, { plurality = 'singular' } = {}) => { | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  |     const plugin = get('plugin', contentType); | 
					
						
							|  |  |  |     const modelName = get('modelName', contentType); | 
					
						
							| 
									
										
										
										
											2021-09-07 11:23:49 +02:00
										 |  |  |     const name = | 
					
						
							|  |  |  |       plurality === 'singular' | 
					
						
							|  |  |  |         ? get('info.singularName', contentType) | 
					
						
							|  |  |  |         : get('info.pluralName', contentType); | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const transformedPlugin = upperFirst(camelCase(plugin)); | 
					
						
							| 
									
										
										
										
											2021-09-23 17:25:25 +02:00
										 |  |  |     const transformedModelName = upperFirst(camelCase(name || singular(modelName))); | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return `${transformedPlugin}${transformedModelName}`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build the entity's type name for a given content type | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getEntityName = contentType => { | 
					
						
							|  |  |  |     return `${getTypeName(contentType)}Entity`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build the entity meta type name for a given content type | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getEntityMetaName = contentType => { | 
					
						
							|  |  |  |     return `${getEntityName(contentType)}Meta`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build the entity response's type name for a given content type | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getEntityResponseName = contentType => { | 
					
						
							|  |  |  |     return `${getEntityName(contentType)}Response`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build the entity response collection's type name for a given content type | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getEntityResponseCollectionName = contentType => { | 
					
						
							|  |  |  |     return `${getEntityName(contentType)}ResponseCollection`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-28 12:02:26 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Build the relation response collection's type name for a given content type | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getRelationResponseCollectionName = contentType => { | 
					
						
							|  |  |  |     return `${getTypeName(contentType)}RelationResponseCollection`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Build a component type name based on its definition | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getComponentName = contentType => { | 
					
						
							|  |  |  |     return contentType.globalId; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build a component type name based on a content type's attribute | 
					
						
							|  |  |  |    * @param {object} attribute | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getComponentNameFromAttribute = attribute => { | 
					
						
							|  |  |  |     return strapi.components[attribute.component].globalId; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build a dynamic zone type name based on a content type and an attribute name | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @param {string} attributeName | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getDynamicZoneName = (contentType, attributeName) => { | 
					
						
							|  |  |  |     const typeName = getTypeName(contentType); | 
					
						
							|  |  |  |     const dzName = upperFirst(camelCase(attributeName)); | 
					
						
							|  |  |  |     const suffix = 'DynamicZone'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return `${typeName}${dzName}${suffix}`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build a dynamic zone input type name based on a content type and an attribute name | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @param {string} attributeName | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getDynamicZoneInputName = (contentType, attributeName) => { | 
					
						
							|  |  |  |     const dzName = getDynamicZoneName(contentType, attributeName); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return `${dzName}Input`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build a component input type name based on a content type and an attribute name | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getComponentInputName = contentType => { | 
					
						
							|  |  |  |     const componentName = getComponentName(contentType); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return `${componentName}Input`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build a content type input name based on a content type and an attribute name | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getContentTypeInputName = contentType => { | 
					
						
							|  |  |  |     const typeName = getTypeName(contentType); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return `${typeName}Input`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build the queries type name for a given content type | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getEntityQueriesTypeName = contentType => { | 
					
						
							|  |  |  |     return `${getEntityName(contentType)}Queries`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build the mutations type name for a given content type | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getEntityMutationsTypeName = contentType => { | 
					
						
							|  |  |  |     return `${getEntityName(contentType)}Mutations`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build the filters type name for a given content type | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getFiltersInputTypeName = contentType => { | 
					
						
							| 
									
										
										
										
											2021-09-28 17:03:35 +02:00
										 |  |  |     const isComponent = contentType.modelType === 'component'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const baseName = isComponent ? getComponentName(contentType) : getTypeName(contentType); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return `${baseName}FiltersInput`; | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build a filters type name for a given GraphQL scalar type | 
					
						
							|  |  |  |    * @param {NexusGenScalars} scalarType | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getScalarFilterInputTypeName = scalarType => { | 
					
						
							|  |  |  |     return `${scalarType}FilterInput`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build a type name for a given content type & polymorphic attribute | 
					
						
							|  |  |  |    * @param {object} contentType | 
					
						
							|  |  |  |    * @param {string} attributeName | 
					
						
							|  |  |  |    * @return {string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const getMorphRelationTypeName = (contentType, attributeName) => { | 
					
						
							|  |  |  |     const typeName = getTypeName(contentType); | 
					
						
							|  |  |  |     const formattedAttr = upperFirst(camelCase(attributeName)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return `${typeName}${formattedAttr}Morph`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Build a custom type name generator with different customization options | 
					
						
							|  |  |  |    * @param {object} options | 
					
						
							|  |  |  |    * @param {string} [options.prefix] | 
					
						
							|  |  |  |    * @param {string} [options.suffix] | 
					
						
							|  |  |  |    * @param {'upper' | 'lower'} [options.firstLetterCase] | 
					
						
							|  |  |  |    * @param {'plural' | 'singular'} [options.plurality] | 
					
						
							|  |  |  |    * @return {function(*=): string} | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const buildCustomTypeNameGenerator = (options = {}) => { | 
					
						
							|  |  |  |     // todo[v4]: use singularName & pluralName is available
 | 
					
						
							|  |  |  |     const { prefix = '', suffix = '', plurality = 'singular', firstLetterCase = 'upper' } = options; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!['plural', 'singular'].includes(plurality)) { | 
					
						
							| 
									
										
										
										
											2021-10-27 18:54:58 +02:00
										 |  |  |       throw new ApplicationError( | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  |         `"plurality" param must be either "plural" or "singular", but got: "${plurality}"` | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const getCustomTypeName = pipe( | 
					
						
							| 
									
										
										
										
											2021-09-07 11:23:49 +02:00
										 |  |  |       ct => getTypeName(ct, { plurality }), | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  |       firstLetterCase === 'upper' ? upperFirst : lowerFirst | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2021-09-07 11:23:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  |     return contentType => `${prefix}${getCustomTypeName(contentType)}${suffix}`; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const getFindQueryName = buildCustomTypeNameGenerator({ | 
					
						
							|  |  |  |     plurality: 'plural', | 
					
						
							|  |  |  |     firstLetterCase: 'lower', | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const getFindOneQueryName = buildCustomTypeNameGenerator({ firstLetterCase: 'lower' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const getCreateMutationTypeName = buildCustomTypeNameGenerator({ | 
					
						
							|  |  |  |     prefix: 'create', | 
					
						
							| 
									
										
										
										
											2021-08-25 17:50:27 +02:00
										 |  |  |     firstLetterCase: 'upper', | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const getUpdateMutationTypeName = buildCustomTypeNameGenerator({ | 
					
						
							|  |  |  |     prefix: 'update', | 
					
						
							| 
									
										
										
										
											2021-08-25 17:50:27 +02:00
										 |  |  |     firstLetterCase: 'upper', | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const getDeleteMutationTypeName = buildCustomTypeNameGenerator({ | 
					
						
							|  |  |  |     prefix: 'delete', | 
					
						
							| 
									
										
										
										
											2021-08-25 17:50:27 +02:00
										 |  |  |     firstLetterCase: 'upper', | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     getEnumName, | 
					
						
							|  |  |  |     getTypeName, | 
					
						
							|  |  |  |     getEntityName, | 
					
						
							|  |  |  |     getEntityMetaName, | 
					
						
							|  |  |  |     getEntityResponseName, | 
					
						
							|  |  |  |     getEntityResponseCollectionName, | 
					
						
							| 
									
										
										
										
											2021-09-28 12:02:26 +02:00
										 |  |  |     getRelationResponseCollectionName, | 
					
						
							| 
									
										
										
										
											2021-08-24 17:56:44 +02:00
										 |  |  |     getComponentName, | 
					
						
							|  |  |  |     getComponentNameFromAttribute, | 
					
						
							|  |  |  |     getDynamicZoneName, | 
					
						
							|  |  |  |     getDynamicZoneInputName, | 
					
						
							|  |  |  |     getComponentInputName, | 
					
						
							|  |  |  |     getContentTypeInputName, | 
					
						
							|  |  |  |     getEntityQueriesTypeName, | 
					
						
							|  |  |  |     getEntityMutationsTypeName, | 
					
						
							|  |  |  |     getFiltersInputTypeName, | 
					
						
							|  |  |  |     getScalarFilterInputTypeName, | 
					
						
							|  |  |  |     getMorphRelationTypeName, | 
					
						
							|  |  |  |     buildCustomTypeNameGenerator, | 
					
						
							|  |  |  |     getFindQueryName, | 
					
						
							|  |  |  |     getFindOneQueryName, | 
					
						
							|  |  |  |     getCreateMutationTypeName, | 
					
						
							|  |  |  |     getUpdateMutationTypeName, | 
					
						
							|  |  |  |     getDeleteMutationTypeName, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; |