<commit_before>var _ = require('lodash');
var async = require('async');
var mongoose = require('mongoose');
var Negotiator = require('negotiator');
var contentType = require('content-type');

function isSelector(object) {
	if (_.isFunction(object))
		return true;
	if (_.isPlainObject(object))
		return _.any(object, isSelector);
}

function isOptions(object) {
	return _.isPlainObject(object) && !isSelector(object);
}

function wrapResults(resource, object, response, cb) {
	if (_.isArray(object)) {
		async.map(object, function(object, cb) {
			resource.serialize(object, response, cb);
		}, cb);
	} else {
		object ? resource.serialize(object, response, cb)
		       : _.defer(cb, null, null);
	}
}

function forwardError(err, res, response, next) {
	_.set(res, '_jsonapify.response', response);
	next(err);
}

function sendResponse(res, response) {
	res.contentType('application/vnd.api+json');
	handleErrors(res, response.errors());
	res.json(response);
	
	function genericErrorCode(code) {
		return Math.ceil(code / 100) * 100;
	}
	
	function aproximateErrorCode(codes) {
		var status = _.first(codes);
		if (codes.length > 1)
			status = genericErrorCode(status);
		return status;
	}
	
	function handleErrors(res, errors) {
		if (_.isEmpty(errors)) return;
		var codes = _.pluck(errors, 'status');
		var errCode = aproximateErrorCode(codes);
		res.status(errCode);
	}
}

function applySelectors(pairs, req, cb) {
	async.reduce(pairs, undefined, function(parent, pair, cb) {
		var resource = pair[0]; var selector = pair[1];
		var filter = resolveSelector(selector, req, parent);
		resource.model.findOne(filter, function(err, result) {
			if (err) return cb(err);
			if (!result) return cb('break', null);
			cb(null, result);
		});
	}, function(err, result) {
		(err && err !== 'break') ? cb(err) : cb(null, result);
	});
}

function resolveSelector(selector, req, parent) {
	function resolveSelectorIter(selector) {
		return _(selector).pairs().map(function(pair) {
			var first = pair[0]; var second = pair[1];
			if (_.isFunction(second))
				return [first, second(req, parent)];
			if (_.isPlainObject(second))
				return [first, resolveSelectorIter(second)];
		}).zipObject().value();
	}
	
	selector = selector || {};
	return _.isFunction(selector)
	           ? { _id: selector(req, parent) }
	           : resolveSelectorIter(selector);
}

exports.isOptions = isOptions;
exports.isSelector = isSelector;
exports.wrapResults = wrapResults;
exports.forwardError = forwardError;
exports.sendResponse = sendResponse;
exports.applySelectors = applySelectors;
exports.resolveSelector = resolveSelector;<commit_msg>Minor changes<commit_after>var _ = require('lodash');
var async = require('async');
var mongoose = require('mongoose');
var Negotiator = require('negotiator');
var contentType = require('content-type');

function isSelector(object) {
	if (_.isFunction(object))
		return true;
	if (_.isPlainObject(object))
		return _.any(object, isSelector);
}

function isOptions(object) {
	return _.isPlainObject(object) && !isSelector(object);
}

function wrapResults(resource, object, response, cb) {
	if (_.isArray(object)) {
		async.map(object, function(object, cb) {
			resource.serialize(object, response, cb);
		}, cb);
	} else {
		object ? resource.serialize(object, response, cb)
		       : _.defer(cb, null, null);
	}
}

function forwardError(err, res, response, next) {
	_.set(res, '_jsonapify.response', response);
	next(err);
}

function sendResponse(res, response) {
	res.contentType('application/vnd.api+json');
	handleErrors(res, response.errors());
	res.json(response);
	
	function genericErrorCode(code) {
		return Math.ceil(code / 100) * 100;
	}
	
	function aproximateErrorCode(codes) {
		var status = _.first(codes);
		if (codes.length > 1)
			status = genericErrorCode(status);
		return status;
	}
	
	function handleErrors(res, errors) {
		if (_.isEmpty(errors)) return;
		var codes = _.pluck(errors, 'status');
		var errCode = aproximateErrorCode(codes);
		res.status(errCode);
	}
}

function applySelectors(pairs, req, cb) {
	async.reduce(pairs, undefined, function(parent, pair, cb) {
		var resource = pair[0]; var selector = pair[1];
		var filter = resolveSelector(selector, req, parent);
		resource.model.findOne(filter, function(err, result) {
			if (err) return cb(err);
			if (!result) return cb('break', null);
			cb(null, result);
		});
	}, function(err, result) {
		(err && err !== 'break') ? cb(err) : cb(null, result);
	});
}

function resolveSelector(selector, req, parent) {
	selector = selector || {};
	return _.isFunction(selector)
	           ? { _id: selector(req, parent) }
	           : resolveSelectorIter(selector);
	
	function resolveSelectorIter(selector) {
		return _(selector).pairs().map(function(pair) {
			var first = pair[0]; var second = pair[1];
			if (_.isFunction(second))
				return [first, second(req, parent)];
			if (_.isPlainObject(second))
				return [first, resolveSelectorIter(second)];
		}).zipObject().value();
	}
}

exports.isOptions = isOptions;
exports.isSelector = isSelector;
exports.wrapResults = wrapResults;
exports.forwardError = forwardError;
exports.sendResponse = sendResponse;
exports.applySelectors = applySelectors;
exports.resolveSelector = resolveSelector;
{'fraction_non_alphanumeric': 0.15129573170731708, 'fraction_numerical': 0.004192073170731708, 'mean_word_length': 4.832222222222223, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1171688', 'n_tokens_mistral': 1781, 'n_tokens_neox': 1655, 'n_words': 380}