You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							124 lines
						
					
					
						
							4.2 KiB
						
					
					
				
			
		
		
	
	
							124 lines
						
					
					
						
							4.2 KiB
						
					
					
				"use strict";
 | 
						|
 | 
						|
Object.defineProperty(exports, "__esModule", {
 | 
						|
  value: true
 | 
						|
});
 | 
						|
exports.mergeResourceOptions = exports.buildFeature = void 0;
 | 
						|
 | 
						|
var _uniq = _interopRequireDefault(require("lodash/uniq"));
 | 
						|
 | 
						|
var _merge = _interopRequireDefault(require("lodash/merge"));
 | 
						|
 | 
						|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 | 
						|
 | 
						|
/* eslint-disable no-nested-ternary */
 | 
						|
function mergeActionHooks(key, oldHook, newHook) {
 | 
						|
  let hooks = [];
 | 
						|
 | 
						|
  if (oldHook) {
 | 
						|
    if (Array.isArray(oldHook)) {
 | 
						|
      hooks = [...hooks, ...oldHook];
 | 
						|
    } else if (oldHook) {
 | 
						|
      hooks = [...hooks, oldHook];
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (newHook) {
 | 
						|
    if (Array.isArray(newHook)) {
 | 
						|
      hooks = [...hooks, ...newHook];
 | 
						|
    } else if (newHook) {
 | 
						|
      hooks = [...hooks, newHook];
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return hooks.length ? {
 | 
						|
    [key]: hooks
 | 
						|
  } : {};
 | 
						|
}
 | 
						|
 | 
						|
const basicOptions = ['id', 'href', 'parent', 'sort', 'navigation'];
 | 
						|
const listOptions = ['listProperties', 'showProperties', 'editProperties', 'filterProperties'];
 | 
						|
// The following check is done in typescript to ensure that the `basicOptions` and `listOptions`
 | 
						|
// contains all the keys from ResourceOptions (+ actions and properties) which are copied
 | 
						|
// separately. If type MissingKeys has any key following condition is not meet and typescript
 | 
						|
// throws an error.
 | 
						|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
						|
const hasMissingKeys = {};
 | 
						|
/**
 | 
						|
 * @name mergeResourceOptions
 | 
						|
 * @function
 | 
						|
 * @description
 | 
						|
 * Merges 2 ResourceOptions together. Used by features
 | 
						|
 *
 | 
						|
 * - 'id', 'href', 'parent', 'sort' from `newOptions` override `oldOptions`
 | 
						|
 * - 'listProperties', 'showProperties', 'editProperties', 'filterProperties'
 | 
						|
 *   are joined and made unique
 | 
						|
 * - all 'properties' from `newOptions` override properties from `oldOptions`
 | 
						|
 * - all 'actions' with their parameters from `newOptions` override `oldOptions`
 | 
						|
 *   except hooks and handler - which are chained.
 | 
						|
 *
 | 
						|
 * @param   {ResourceOptions}  oldOptions
 | 
						|
 * @param   {ResourceOptions}  newOptions
 | 
						|
 *
 | 
						|
 * @return  {ResourceOptions}
 | 
						|
 */
 | 
						|
 | 
						|
const mergeResourceOptions = (oldOptions = {}, newOptions = {}) => {
 | 
						|
  const options = { ...oldOptions
 | 
						|
  };
 | 
						|
  basicOptions.forEach(propName => {
 | 
						|
    if (propName in newOptions) {
 | 
						|
      options[propName] = newOptions[propName];
 | 
						|
    }
 | 
						|
  });
 | 
						|
  listOptions.forEach(propName => {
 | 
						|
    if (propName in newOptions) {
 | 
						|
      const mergedOptions = [...(oldOptions && propName in oldOptions ? oldOptions[propName] : []), ...(newOptions && propName in newOptions ? newOptions[propName] : [])];
 | 
						|
      options[propName] = (0, _uniq.default)(mergedOptions);
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  if (oldOptions.properties || newOptions.properties) {
 | 
						|
    options.properties = (0, _merge.default)({}, oldOptions.properties, newOptions.properties);
 | 
						|
  }
 | 
						|
 | 
						|
  if (oldOptions.actions || newOptions.actions) {
 | 
						|
    options.actions = Object.keys(newOptions.actions || {}).reduce((memo, actionName) => {
 | 
						|
      const action = (newOptions.actions || {})[actionName];
 | 
						|
      const oldAction = memo[actionName];
 | 
						|
      return { ...memo,
 | 
						|
        [actionName]: { ...memo[actionName],
 | 
						|
          ...action,
 | 
						|
          ...mergeActionHooks('before', oldAction === null || oldAction === void 0 ? void 0 : oldAction.before, action === null || action === void 0 ? void 0 : action.before),
 | 
						|
          ...mergeActionHooks('after', oldAction === null || oldAction === void 0 ? void 0 : oldAction.after, action === null || action === void 0 ? void 0 : action.after),
 | 
						|
          ...mergeActionHooks('handler', oldAction === null || oldAction === void 0 ? void 0 : oldAction.handler, action === null || action === void 0 ? void 0 : action.handler)
 | 
						|
        }
 | 
						|
      };
 | 
						|
    }, oldOptions.actions || {});
 | 
						|
  }
 | 
						|
 | 
						|
  return options;
 | 
						|
};
 | 
						|
/**
 | 
						|
 * @name buildFeature
 | 
						|
 * @function
 | 
						|
 * @description
 | 
						|
 * Higher Order Function which creates a feature
 | 
						|
 *
 | 
						|
 * @param   {ResourceOptions}  options
 | 
						|
 *
 | 
						|
 * @return  {FeatureType}
 | 
						|
 * @example
 | 
						|
 * const { buildFeature } = require('adminjs')
 | 
						|
 *
 | 
						|
 * const feature = buildFeature({
 | 
						|
 *   // resource options goes here.
 | 
						|
 * })
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
exports.mergeResourceOptions = mergeResourceOptions;
 | 
						|
 | 
						|
const buildFeature = (options = {}) => (admin, prevOptions = {}) => mergeResourceOptions(prevOptions, typeof options === 'function' ? options(admin) : options);
 | 
						|
 | 
						|
exports.buildFeature = buildFeature; |