mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-04 03:43:34 +00:00 
			
		
		
		
	* fix shadow crud breaking build when resolvers are not defined in a plugin Signed-off-by: Pierre Noël <pierre.noel@strapi.io> * refacto Signed-off-by: Pierre Noël <pierre.noel@strapi.io> Co-authored-by: Pierre Noël <pierre.noel@strapi.io>
		
			
				
	
	
		
			183 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
const _ = require('lodash');
 | 
						|
 | 
						|
/**
 | 
						|
 * Merges
 | 
						|
 */
 | 
						|
const mergeSchemas = (root, ...subs) => {
 | 
						|
  subs.forEach(sub => {
 | 
						|
    if (_.isEmpty(sub)) return;
 | 
						|
    const { definition = '', query = {}, mutation = {}, resolvers = {} } = sub;
 | 
						|
 | 
						|
    root.definition += '\n' + definition;
 | 
						|
    _.merge(root, {
 | 
						|
      query,
 | 
						|
      mutation,
 | 
						|
      resolvers,
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  return root;
 | 
						|
};
 | 
						|
 | 
						|
const createDefaultSchema = () => ({
 | 
						|
  definition: '',
 | 
						|
  query: {},
 | 
						|
  mutation: {},
 | 
						|
  resolvers: {},
 | 
						|
});
 | 
						|
 | 
						|
const diffResolvers = (object, base) => {
 | 
						|
  let newObj = {};
 | 
						|
 | 
						|
  Object.keys(object).forEach(type => {
 | 
						|
    Object.keys(object[type]).forEach(resolver => {
 | 
						|
      if (type === 'Query' || type === 'Mutation') {
 | 
						|
        if (!_.has(base, [type, resolver])) {
 | 
						|
          _.set(newObj, [type, resolver], _.get(object, [type, resolver]));
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        _.set(newObj, [type, resolver], _.get(object, [type, resolver]));
 | 
						|
      }
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  return newObj;
 | 
						|
};
 | 
						|
 | 
						|
const convertToParams = params => {
 | 
						|
  return Object.keys(params).reduce((acc, current) => {
 | 
						|
    const key = current === 'id' ? 'id' : `_${current}`;
 | 
						|
    acc[key] = params[current];
 | 
						|
    return acc;
 | 
						|
  }, {});
 | 
						|
};
 | 
						|
 | 
						|
const convertToQuery = params => {
 | 
						|
  const result = {};
 | 
						|
 | 
						|
  _.forEach(params, (value, key) => {
 | 
						|
    if (_.isPlainObject(value)) {
 | 
						|
      const flatObject = convertToQuery(value);
 | 
						|
      _.forEach(flatObject, (_value, _key) => {
 | 
						|
        result[`${key}.${_key}`] = _value;
 | 
						|
      });
 | 
						|
    } else {
 | 
						|
      result[key] = value;
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  return result;
 | 
						|
};
 | 
						|
 | 
						|
const amountLimiting = (params = {}) => {
 | 
						|
  const { amountLimit } = strapi.plugins.graphql.config;
 | 
						|
 | 
						|
  if (!amountLimit) return params;
 | 
						|
 | 
						|
  if (!params.limit || params.limit === -1 || params.limit > amountLimit) {
 | 
						|
    params.limit = amountLimit;
 | 
						|
  } else if (params.limit < 0) {
 | 
						|
    params.limit = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  return params;
 | 
						|
};
 | 
						|
 | 
						|
const nonRequired = type => type.replace('!', '');
 | 
						|
 | 
						|
const actionExists = ({ resolver, resolverOf }) => {
 | 
						|
  if (isResolvablePath(resolverOf)) {
 | 
						|
    return true;
 | 
						|
  } else if (_.isFunction(resolver)) {
 | 
						|
    return true;
 | 
						|
  } else if (_.isString(resolver)) {
 | 
						|
    return _.isFunction(getActionFn(getActionDetails(resolver)));
 | 
						|
  } else {
 | 
						|
    throw new Error(
 | 
						|
      `Error building query. Expected \`resolver\` as string or a function, or \`resolverOf\` as a string. got ${{
 | 
						|
        resolver,
 | 
						|
        resolverOf,
 | 
						|
      }}`
 | 
						|
    );
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
const getAction = resolver => {
 | 
						|
  if (!_.isString(resolver)) {
 | 
						|
    throw new Error(`Error building query. Expected a string, got ${resolver}`);
 | 
						|
  }
 | 
						|
 | 
						|
  const actionDetails = getActionDetails(resolver);
 | 
						|
  const actionFn = getActionFn(actionDetails);
 | 
						|
 | 
						|
  if (!actionFn) {
 | 
						|
    throw new Error(
 | 
						|
      `[GraphQL] Cannot find action "${resolver}". Check your graphql configurations.`
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  return actionFn;
 | 
						|
};
 | 
						|
 | 
						|
const getActionFn = details => {
 | 
						|
  const { controller, action, plugin, api } = details;
 | 
						|
 | 
						|
  if (plugin) {
 | 
						|
    return _.get(strapi.plugins, [_.toLower(plugin), 'controllers', _.toLower(controller), action]);
 | 
						|
  }
 | 
						|
 | 
						|
  return _.get(strapi.api, [_.toLower(api), 'controllers', _.toLower(controller), action]);
 | 
						|
};
 | 
						|
 | 
						|
const getActionDetails = resolver => {
 | 
						|
  if (resolver.startsWith('plugins::')) {
 | 
						|
    const [, path] = resolver.split('::');
 | 
						|
    const [plugin, controller, action] = path.split('.');
 | 
						|
 | 
						|
    return { plugin, controller, action };
 | 
						|
  }
 | 
						|
 | 
						|
  if (resolver.startsWith('application::')) {
 | 
						|
    const [, path] = resolver.split('::');
 | 
						|
    const [api, controller, action] = path.split('.');
 | 
						|
 | 
						|
    return { api, controller, action };
 | 
						|
  }
 | 
						|
 | 
						|
  const args = resolver.split('.');
 | 
						|
 | 
						|
  if (args.length === 3) {
 | 
						|
    const [api, controller, action] = args;
 | 
						|
    return { api, controller, action };
 | 
						|
  }
 | 
						|
 | 
						|
  // if direct api access
 | 
						|
  if (args.length === 2) {
 | 
						|
    const [controller, action] = args;
 | 
						|
    return { api: controller, controller, action };
 | 
						|
  }
 | 
						|
 | 
						|
  throw new Error(
 | 
						|
    `[GraphQL] Could not find action for resolver "${resolver}". Check your graphql configurations.`
 | 
						|
  );
 | 
						|
};
 | 
						|
 | 
						|
const isResolvablePath = path => _.isString(path) && !_.isEmpty(path);
 | 
						|
 | 
						|
module.exports = {
 | 
						|
  diffResolvers,
 | 
						|
  mergeSchemas,
 | 
						|
  createDefaultSchema,
 | 
						|
  convertToParams,
 | 
						|
  convertToQuery,
 | 
						|
  amountLimiting,
 | 
						|
  nonRequired,
 | 
						|
  actionExists,
 | 
						|
  getAction,
 | 
						|
  getActionDetails,
 | 
						|
  getActionFn,
 | 
						|
  isResolvablePath,
 | 
						|
};
 |