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; |