mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-03 19:36:20 +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');
 | 
						|
 | 
						|
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];
 | 
						|
    },
 | 
						|
  };
 | 
						|
};
 |