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
			| 
								 
											3 years ago
										 
									 | 
							
								"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;
							 |