mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-30 17:37:26 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			98 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| const { Kind, valueFromASTUntyped } = require('graphql');
 | |
| const { omit } = require('lodash/fp');
 | |
| const { unionType, scalarType } = require('nexus');
 | |
| const { ApplicationError } = require('@strapi/utils').errors;
 | |
| 
 | |
| module.exports = ({ strapi }) => {
 | |
|   const buildTypeDefinition = (name, components) => {
 | |
|     const { ERROR_TYPE_NAME } = strapi.plugin('graphql').service('constants');
 | |
|     const isEmpty = components.length === 0;
 | |
| 
 | |
|     const componentsTypeNames = components.map((componentUID) => {
 | |
|       const component = strapi.components[componentUID];
 | |
| 
 | |
|       if (!component) {
 | |
|         throw new ApplicationError(
 | |
|           `Trying to create a dynamic zone type with an unknown component: "${componentUID}"`
 | |
|         );
 | |
|       }
 | |
| 
 | |
|       return component.globalId;
 | |
|     });
 | |
| 
 | |
|     return unionType({
 | |
|       name,
 | |
| 
 | |
|       resolveType(obj) {
 | |
|         if (isEmpty) {
 | |
|           return ERROR_TYPE_NAME;
 | |
|         }
 | |
| 
 | |
|         return strapi.components[obj.__component].globalId;
 | |
|       },
 | |
| 
 | |
|       definition(t) {
 | |
|         t.members(...componentsTypeNames, ERROR_TYPE_NAME);
 | |
|       },
 | |
|     });
 | |
|   };
 | |
| 
 | |
|   const buildInputDefinition = (name, components) => {
 | |
|     const parseData = (value) => {
 | |
|       const component = Object.values(strapi.components).find(
 | |
|         (component) => component.globalId === value.__typename
 | |
|       );
 | |
| 
 | |
|       if (!component) {
 | |
|         throw new ApplicationError(
 | |
|           `Component not found. expected one of: ${components
 | |
|             .map((uid) => strapi.components[uid].globalId)
 | |
|             .join(', ')}`
 | |
|         );
 | |
|       }
 | |
| 
 | |
|       return {
 | |
|         __component: component.uid,
 | |
|         ...omit(['__typename'], value),
 | |
|       };
 | |
|     };
 | |
| 
 | |
|     return scalarType({
 | |
|       name,
 | |
| 
 | |
|       serialize: (value) => value,
 | |
| 
 | |
|       parseValue: (value) => parseData(value),
 | |
| 
 | |
|       parseLiteral(ast, variables) {
 | |
|         if (ast.kind !== Kind.OBJECT) {
 | |
|           return undefined;
 | |
|         }
 | |
| 
 | |
|         const value = valueFromASTUntyped(ast, variables);
 | |
|         return parseData(value);
 | |
|       },
 | |
|     });
 | |
|   };
 | |
| 
 | |
|   return {
 | |
|     /**
 | |
|      * Build a Nexus dynamic zone type from a Strapi dz attribute
 | |
|      * @param {object} definition - The definition of the dynamic zone
 | |
|      * @param {string} name - the name of the dynamic zone
 | |
|      * @param {string} inputName - the name of the dynamic zone's input
 | |
|      * @return {[NexusUnionTypeDef, NexusScalarTypeDef]}
 | |
|      */
 | |
|     buildDynamicZoneDefinition(definition, name, inputName) {
 | |
|       const { components } = definition;
 | |
| 
 | |
|       const typeDefinition = buildTypeDefinition(name, components);
 | |
|       const inputDefinition = buildInputDefinition(inputName, components);
 | |
| 
 | |
|       return [typeDefinition, inputDefinition];
 | |
|     },
 | |
|   };
 | |
| };
 | 
