mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-04 11:54:10 +00:00 
			
		
		
		
	initial commit
This commit is contained in:
		
							parent
							
								
									a7d616e158
								
							
						
					
					
						commit
						7747d1d3d1
					
				@ -18,6 +18,7 @@ const {
 | 
			
		||||
  cloneDeep,
 | 
			
		||||
  get,
 | 
			
		||||
  mergeAll,
 | 
			
		||||
  isString,
 | 
			
		||||
} = require('lodash/fp');
 | 
			
		||||
const _ = require('lodash');
 | 
			
		||||
const parseType = require('./parse-type');
 | 
			
		||||
@ -46,7 +47,7 @@ class InvalidSortError extends Error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const validateOrder = (order) => {
 | 
			
		||||
  if (!['asc', 'desc'].includes(order.toLocaleLowerCase())) {
 | 
			
		||||
  if (!isString(order) || !['asc', 'desc'].includes(order.toLocaleLowerCase())) {
 | 
			
		||||
    throw new InvalidOrderError();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
@ -80,6 +81,13 @@ const convertSortQueryParams = (sortQuery) => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const convertSingleSortQueryParam = (sortQuery) => {
 | 
			
		||||
  if (!sortQuery) {
 | 
			
		||||
    return {};
 | 
			
		||||
  }
 | 
			
		||||
  if (!isString(sortQuery)) {
 | 
			
		||||
    throw new Error('Invalid sort query');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // split field and order param with default order to ascending
 | 
			
		||||
  const [field, order = 'asc'] = sortQuery.split(':');
 | 
			
		||||
 | 
			
		||||
@ -89,6 +97,8 @@ const convertSingleSortQueryParam = (sortQuery) => {
 | 
			
		||||
 | 
			
		||||
  validateOrder(order);
 | 
			
		||||
 | 
			
		||||
  // TODO: field should be a valid path on an object model
 | 
			
		||||
 | 
			
		||||
  return _.set({}, field, order);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -368,6 +378,7 @@ const convertNestedPopulate = (subPopulate, schema) => {
 | 
			
		||||
  return query;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  // TODO: ensure field is valid in content types (will probably have to check strapi.contentTypes since it can be a string.path)
 | 
			
		||||
const convertFieldsQueryParams = (fields, depth = 0) => {
 | 
			
		||||
  if (depth === 0 && fields === '*') {
 | 
			
		||||
    return undefined;
 | 
			
		||||
@ -387,6 +398,33 @@ const convertFieldsQueryParams = (fields, depth = 0) => {
 | 
			
		||||
  throw new Error('Invalid fields parameter. Expected a string or an array of strings');
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// TODO: this is temporary as a POC, get operators from @strapi/database (will likely require refactoring)
 | 
			
		||||
const isOperator = (key) => {
 | 
			
		||||
  return key.startsWith('$');
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const isValidSchemaAttribute = (key, schema) => {
 | 
			
		||||
  if (key.trim().toLowerCase() === 'id') {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!schema) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // case insensitive check if the attribute exists in the schema
 | 
			
		||||
  const findAttribute = key.toLowerCase();
 | 
			
		||||
  if (
 | 
			
		||||
    Object.keys(schema.attributes)
 | 
			
		||||
      .map((attributeName) => attributeName.toLowerCase())
 | 
			
		||||
      .includes(findAttribute)
 | 
			
		||||
  ) {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const convertFiltersQueryParams = (filters, schema) => {
 | 
			
		||||
  // Filters need to be either an array or an object
 | 
			
		||||
  // Here we're only checking for 'object' type since typeof [] => object and typeof {} => object
 | 
			
		||||
@ -401,10 +439,6 @@ const convertFiltersQueryParams = (filters, schema) => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const convertAndSanitizeFilters = (filters, schema) => {
 | 
			
		||||
  if (!isPlainObject(filters)) {
 | 
			
		||||
    return filters;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (Array.isArray(filters)) {
 | 
			
		||||
    return (
 | 
			
		||||
      filters
 | 
			
		||||
@ -415,14 +449,23 @@ const convertAndSanitizeFilters = (filters, schema) => {
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // This must come after check for Array or else arrays are not filtered
 | 
			
		||||
  if (!isPlainObject(filters)) {
 | 
			
		||||
    return filters;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const removeOperator = (operator) => delete filters[operator];
 | 
			
		||||
 | 
			
		||||
  // Here, `key` can either be an operator or an attribute name
 | 
			
		||||
  for (const [key, value] of Object.entries(filters)) {
 | 
			
		||||
    const attribute = get(key, schema?.attributes);
 | 
			
		||||
    const validKey = isOperator(key) || isValidSchemaAttribute(key, schema);
 | 
			
		||||
 | 
			
		||||
    if (!validKey) {
 | 
			
		||||
      removeOperator(key);
 | 
			
		||||
    }
 | 
			
		||||
    // Handle attributes
 | 
			
		||||
    if (attribute) {
 | 
			
		||||
    else if (attribute) {
 | 
			
		||||
      // Relations
 | 
			
		||||
      if (attribute.type === 'relation') {
 | 
			
		||||
        filters[key] = convertAndSanitizeFilters(value, strapi.getModel(attribute.target));
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,7 @@ const defaultSanitizeOutput = async (schema, entity) => {
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// TODO: remove fields that don't exist on the schema
 | 
			
		||||
const defaultSanitizeFilters = curry((schema, filters) => {
 | 
			
		||||
  return pipeAsync(
 | 
			
		||||
    // Remove dynamic zones from filters
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user