<commit_before>'use strict'

var express = require('express'),
	versions = require('./versions'),
	scrub = require('./scrub'),
	genId = require('./genId'),
	APIError = require('./APIError'),
	openAPI = require('./openAPI'),
	bodyParser = require('body-parser')

/**
 * Represent a lifted API
 *
 * Instances of this class are created internally for you.
 * *You don't need to use this constructor directly.*
 *
 * @class
 * @param {external:lift-it.Lifted} lifted
 * @param {Object} options
 * @param {Array<RegExp>} options.dataScrub
 * @param {number} options.timeout
 * @param {Function} options.callToJSON
 * @param {?Function} options.onsuccess
 * @param {?Function} options.onfailure
 * @param {?Function} options.ontimeout
 */
function API(lifted, options) {
	/** @member {external:express.Router} */
	this.router = new express.Router

	/** @member {number} */
	this.minVersion = 0

	/** @member {number} */
	this.maxVersion = 0

	/**
	 * The list of supported versions, ordered from oldest to newest.
	 * Example: `['v3', 'v4']`
	 * @member {Array<string>}
	 */
	this.versions = 0

	/** @member {Array<Endpoint>} */
	this.endpoints = []

	/**
	 * The map from url to an Endpoint instance
	 * @member {Object<Endpoint>}
	 */
	this.endpointByUrl = Object.create(null)

	/**
	 * @member {lift-it:Lifted}
	 * @private
	 */
	this._lifted = lifted

	/**
	 * @member {Object}
	 * @private
	 */
	this._options = options

	/**
	 * @member {Array<RegExp>}
	 * @private
	 */
	this._dataScrub = options.dataScrub

	/**
	 * @member {number}
	 * @private
	 */
	this._timeout = options.timeout

	/**
	 * @member {Function}
	 * @private
	 */
	this._callToJSON = options.callToJSON

	/**
	 * @member {?Function}
	 * @private
	 */
	this._onsuccess = options.onsuccess

	/**
	 * @member {?Function}
	 * @private
	 */
	this._onfailure = options.onfailure

	/**
	 * @member {?Function}
	 * @private
	 */
	this._ontimeout = options.ontimeout

	/**
	 * @member {Function}
	 * @private
	 */
	this._bodyParser = bodyParser.json(options.bodyParser)
}

module.exports = API

/**
 * Execute an endpoint in this api
 * @param {string} url - like '/v1/user/create' or '/v-last/user/create'
 * @param {Object} body
 * @param {Object} [runInfo={}] - data available as `process.domain.runInfo`. See more info in {@link https://www.npmjs.com/package/run-it|run-it} module
 * @param {number} [runInfo.beginTime=Date.now()]
 * @param {string} [runInfo.requestId=genId()]
 * @param {Function} callback - async cb(out)
 */
API.prototype.run = function (url, body, runInfo, callback) {
	// runInfo is optional
	if (typeof runInfo === 'function') {
		callback = runInfo
		runInfo = {}
	}

	runInfo = this._prepareRunInfo(runInfo)
	var that = this,
		endpoint = this._getEndpoint(url)

	if (!endpoint) {
		// Always async
		return process.nextTick(function () {
			that._handleNotFound(url, body, runInfo, callback)
		})
	}
	this._runEndpoint(endpoint, body, runInfo, callback)
}

/**
 * Return the OpenAPI (Swagger) description object of this api.
 * Both prepareEndpoint and prepareSpec will be applied.
 * @param {number} [version] - version to consider (if empty, returns all versions)
 * @returns {Object}
 */
API.prototype.getOpenAPISpec = function (version) {
	return openAPI(this, version)
}

/**
 * Translates a web request into an endpoint execution in this api
 * @param {Object} req
 * @param {Object} [req.runInfo]
 * @param {Object} res
 * @param {Function} callback - async cb(err, out)
 * @private
 */
API.prototype._runRequest = function (req, res, callback) {
	req.runInfo = this._prepareRunInfo(req.runInfo)

	var endpoint = this._getEndpoint(req.url),
		that = this

	if (!endpoint) {
		// If endpoint is not found, we parse the body with component's
		// default parser for logging pourposes
		that._bodyParser(req, res, callback)
		return process.nextTick(function () {
			that._handleNotFound(req.url, req.body, req.runInfo, function (out) {
				callback(null, out)
			})
		})
	}

	endpoint.action.module.bodyParser(req, res, function (err) {
		if (err || !req.body) {
			return callback(err)
		}

		that._runEndpoint(endpoint, req.body, req.runInfo, function (out) {
			callback(null, out)
		})
	})
}

/**<commit_msg>Fix duplicate callback for two handlers in not found endpoint<commit_after>'use strict'

var express = require('express'),
	versions = require('./versions'),
	scrub = require('./scrub'),
	genId = require('./genId'),
	APIError = require('./APIError'),
	openAPI = require('./openAPI'),
	bodyParser = require('body-parser')

/**
 * Represent a lifted API
 *
 * Instances of this class are created internally for you.
 * *You don't need to use this constructor directly.*
 *
 * @class
 * @param {external:lift-it.Lifted} lifted
 * @param {Object} options
 * @param {Array<RegExp>} options.dataScrub
 * @param {number} options.timeout
 * @param {Function} options.callToJSON
 * @param {?Function} options.onsuccess
 * @param {?Function} options.onfailure
 * @param {?Function} options.ontimeout
 */
function API(lifted, options) {
	/** @member {external:express.Router} */
	this.router = new express.Router

	/** @member {number} */
	this.minVersion = 0

	/** @member {number} */
	this.maxVersion = 0

	/**
	 * The list of supported versions, ordered from oldest to newest.
	 * Example: `['v3', 'v4']`
	 * @member {Array<string>}
	 */
	this.versions = 0

	/** @member {Array<Endpoint>} */
	this.endpoints = []

	/**
	 * The map from url to an Endpoint instance
	 * @member {Object<Endpoint>}
	 */
	this.endpointByUrl = Object.create(null)

	/**
	 * @member {lift-it:Lifted}
	 * @private
	 */
	this._lifted = lifted

	/**
	 * @member {Object}
	 * @private
	 */
	this._options = options

	/**
	 * @member {Array<RegExp>}
	 * @private
	 */
	this._dataScrub = options.dataScrub

	/**
	 * @member {number}
	 * @private
	 */
	this._timeout = options.timeout

	/**
	 * @member {Function}
	 * @private
	 */
	this._callToJSON = options.callToJSON

	/**
	 * @member {?Function}
	 * @private
	 */
	this._onsuccess = options.onsuccess

	/**
	 * @member {?Function}
	 * @private
	 */
	this._onfailure = options.onfailure

	/**
	 * @member {?Function}
	 * @private
	 */
	this._ontimeout = options.ontimeout

	/**
	 * @member {Function}
	 * @private
	 */
	this._bodyParser = bodyParser.json(options.bodyParser)
}

module.exports = API

/**
 * Execute an endpoint in this api
 * @param {string} url - like '/v1/user/create' or '/v-last/user/create'
 * @param {Object} body
 * @param {Object} [runInfo={}] - data available as `process.domain.runInfo`. See more info in {@link https://www.npmjs.com/package/run-it|run-it} module
 * @param {number} [runInfo.beginTime=Date.now()]
 * @param {string} [runInfo.requestId=genId()]
 * @param {Function} callback - async cb(out)
 */
API.prototype.run = function (url, body, runInfo, callback) {
	// runInfo is optional
	if (typeof runInfo === 'function') {
		callback = runInfo
		runInfo = {}
	}

	runInfo = this._prepareRunInfo(runInfo)
	var that = this,
		endpoint = this._getEndpoint(url)

	if (!endpoint) {
		// Always async
		return process.nextTick(function () {
			that._handleNotFound(url, body, runInfo, callback)
		})
	}
	this._runEndpoint(endpoint, body, runInfo, callback)
}

/**
 * Return the OpenAPI (Swagger) description object of this api.
 * Both prepareEndpoint and prepareSpec will be applied.
 * @param {number} [version] - version to consider (if empty, returns all versions)
 * @returns {Object}
 */
API.prototype.getOpenAPISpec = function (version) {
	return openAPI(this, version)
}

/**
 * Translates a web request into an endpoint execution in this api
 * @param {Object} req
 * @param {Object} [req.runInfo]
 * @param {Object} res
 * @param {Function} callback - async cb(err, out)
 * @private
 */
API.prototype._runRequest = function (req, res, callback) {
	req.runInfo = this._prepareRunInfo(req.runInfo)

	var endpoint = this._getEndpoint(req.url),
		that = this,
		parseBody = endpoint ? endpoint.action.module.bodyParser : that._bodyParser

	return parseBody(req, res, function (err) {
		if (err || !req.body) {
			return callback(err)
		}

		if (!endpoint) {
			return that._handleNotFound(req.url, req.body, req.runInfo, function (out) {
				callback(null, out)
			})
		}

		that._runEndpoint(endpoint, req.body, req.runInfo, function (out) {
			callback(null, out)
		})

	})
}

/**
{'fraction_non_alphanumeric': 0.1568791946308725, 'fraction_numerical': 0.0014381591562799617, 'mean_word_length': 3.6283971159179145, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, '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': '6143270', 'n_tokens_mistral': 2888, 'n_tokens_neox': 2700, 'n_words': 706}