{"size": 3010, "ext": "js", "max_stars_repo_path": "lib/ebi/ebi-results.js", "max_stars_repo_name": "Financial-Times/ebi", "max_stars_repo_stars_event_min_datetime": "2019-02-26T13:57:45.000Z", "max_stars_repo_stars_event_max_datetime": "2021-12-12T01:39:58.000Z", "max_issues_repo_path": "lib/ebi/ebi-results.js", "max_issues_repo_name": "Financial-Times/ebi", "max_issues_repo_issues_event_min_datetime": "2019-02-25T10:24:46.000Z", "max_issues_repo_issues_event_max_datetime": "2022-03-30T11:23:48.000Z", "max_forks_repo_path": "lib/ebi/ebi-results.js", "max_forks_repo_name": "Financial-Times/github-repositories-contents-search", "max_forks_repo_forks_event_min_datetime": "2020-07-31T15:02:13.000Z", "max_forks_repo_forks_event_max_datetime": "2020-07-31T15:02:13.000Z"}
{"max_stars_count": 8, "max_issues_count": 54, "max_forks_count": 1, "avg_line_length": 25.9482758621, "max_line_length": 85, "alphanum_fraction": 0.6970099668}
const { RESULT_TYPES } = require('../../lib/ebi/result-types');
const { createResult, withErrorMessage } = require('../../lib/create-result');

/**
 * Ebi result
 *
 * @typedef {Object} EbiResult
 * @property {'match'|'no-match'|'error'} type Type of result
 * @property {string} repository Full repository path
 * @property {string} filepath The filepath searched for
 * @property {string} fileContents The file contents serialized as a string
 * @property {string} [search] The search term
 * @property {string} [regex] The regex used for search
 * @property {string} [error] The error message if the result is of type `error`
 * @property {string} [message] Extra information about the result
 */

/**
 * Ebi results
 *
 * @typedef {Object} EbiResults
 * @property {EbiResult[]} allResults All search results
 * @property {EbiResult[]} searchMatches All search results that match
 * @property {EbiResult[]} searchNoMatches All search results that do not match
 * @property {EbiResult[]} searchErrors All search errors
 */

/**
 * Ebi results function
 *
 * @typedef {() => EbiResults} EbiResultsFunction
 */

/**
 * Get a function that returns ebi results in a synchronous format
 *
 * @param {Promise<EbiResult>[]} resultsAsync An array of asynchronous ebi results
 * @returns {EbiResultsFunction}
 */
const getSyncResults = resultsAsync => async () => {
	const allResults = await Promise.all(
		resultsAsync.map(promise => {
			return promise.catch(e => e);
		})
	);

	const searchMatches = allResults.filter(
		({ type }) => type === RESULT_TYPES.match
	);
	const searchNoMatches = allResults.filter(
		({ type }) => type === RESULT_TYPES.noMatch
	);
	const searchErrors = allResults.filter(
		({ type }) => type === RESULT_TYPES.error
	);

	return {
		allResults,
		searchMatches,
		searchNoMatches,
		searchErrors
	};
};

/**
 * Ebi results input
 *
 * @typedef {Object} EbiResultsInput
 * @property {Array} errors
 * @property {string} [search]
 * @property {string} [regex]
 * @property {string} filepath
 * @property {Promise<EbiResult>[]} searchResults
 */

/**
 * Ebi results object
 *
 * @typedef {Object} EbiResultsObject
 * @property {Promise<EbiResult>[]} resultsAsync An array of asynchronous ebi results
 * @property {EbiResultsFunction} getResults Function to get synchronous ebi results
 */

/**
 * Get ebi results in an asynchronous and synchronous format
 *
 * @param {EbiResultsInput} config
 * @returns {EbiResultsObject}
 */
exports.getEbiResults = ({
	errors,
	search,
	regex,
	filepath,
	searchResults
}) => {
	const invalidRepos = errors.map(error => {
		const { repository, line } = error;
		const result = createResult({
			search,
			regex,
			filepath,
			repository
		});
		const message = `ERROR: invalid repository '${repository}' on line ${line}`;
		const output = result(withErrorMessage(message));
		return Promise.reject(output);
	});

	const resultsAsync = invalidRepos.concat(searchResults);
	return {
		resultsAsync,
		getResults: getSyncResults(resultsAsync)
	};
};
