You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			92 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
		
		
			
		
	
	
			92 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
| 
											9 months ago
										 | /* | ||
|  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | ||
|  | 	Author Tobias Koppers @sokra | ||
|  | */ | ||
|  | 
 | ||
|  | "use strict"; | ||
|  | 
 | ||
|  | /** @template T @typedef {(string | Record<string, string | string[] | T>)[] | Record<string, string | string[] | T>} ContainerOptionsFormat */ | ||
|  | 
 | ||
|  | /** | ||
|  |  * @template T | ||
|  |  * @template N | ||
|  |  * @param {ContainerOptionsFormat<T>} options options passed by the user | ||
|  |  * @param {function(string | string[], string) : N} normalizeSimple normalize a simple item | ||
|  |  * @param {function(T, string) : N} normalizeOptions normalize a complex item | ||
|  |  * @param {function(string, N): void} fn processing function | ||
|  |  * @returns {void} | ||
|  |  */ | ||
|  | const process = (options, normalizeSimple, normalizeOptions, fn) => { | ||
|  | 	const array = items => { | ||
|  | 		for (const item of items) { | ||
|  | 			if (typeof item === "string") { | ||
|  | 				fn(item, normalizeSimple(item, item)); | ||
|  | 			} else if (item && typeof item === "object") { | ||
|  | 				object(item); | ||
|  | 			} else { | ||
|  | 				throw new Error("Unexpected options format"); | ||
|  | 			} | ||
|  | 		} | ||
|  | 	}; | ||
|  | 	const object = obj => { | ||
|  | 		for (const [key, value] of Object.entries(obj)) { | ||
|  | 			if (typeof value === "string" || Array.isArray(value)) { | ||
|  | 				fn(key, normalizeSimple(value, key)); | ||
|  | 			} else { | ||
|  | 				fn(key, normalizeOptions(value, key)); | ||
|  | 			} | ||
|  | 		} | ||
|  | 	}; | ||
|  | 	if (!options) { | ||
|  | 		return; | ||
|  | 	} else if (Array.isArray(options)) { | ||
|  | 		array(options); | ||
|  | 	} else if (typeof options === "object") { | ||
|  | 		object(options); | ||
|  | 	} else { | ||
|  | 		throw new Error("Unexpected options format"); | ||
|  | 	} | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * @template T | ||
|  |  * @template R | ||
|  |  * @param {ContainerOptionsFormat<T>} options options passed by the user | ||
|  |  * @param {function(string | string[], string) : R} normalizeSimple normalize a simple item | ||
|  |  * @param {function(T, string) : R} normalizeOptions normalize a complex item | ||
|  |  * @returns {[string, R][]} parsed options | ||
|  |  */ | ||
|  | const parseOptions = (options, normalizeSimple, normalizeOptions) => { | ||
|  | 	/** @type {[string, R][]} */ | ||
|  | 	const items = []; | ||
|  | 	process(options, normalizeSimple, normalizeOptions, (key, value) => { | ||
|  | 		items.push([key, value]); | ||
|  | 	}); | ||
|  | 	return items; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * @template T | ||
|  |  * @param {string} scope scope name | ||
|  |  * @param {ContainerOptionsFormat<T>} options options passed by the user | ||
|  |  * @returns {Record<string, string | string[] | T>} options to spread or pass | ||
|  |  */ | ||
|  | const scope = (scope, options) => { | ||
|  | 	/** @type {Record<string, string | string[] | T>} */ | ||
|  | 	const obj = {}; | ||
|  | 	process( | ||
|  | 		options, | ||
|  | 		item => /** @type {string | string[] | T} */ (item), | ||
|  | 		item => /** @type {string | string[] | T} */ (item), | ||
|  | 		(key, value) => { | ||
|  | 			obj[ | ||
|  | 				key.startsWith("./") ? `${scope}${key.slice(1)}` : `${scope}/${key}` | ||
|  | 			] = value; | ||
|  | 		} | ||
|  | 	); | ||
|  | 	return obj; | ||
|  | }; | ||
|  | 
 | ||
|  | exports.parseOptions = parseOptions; | ||
|  | exports.scope = scope; |