<commit_before>const $fs = require('fs');
const $path = require('path');
const $lodash = require('lodash');
const $util = require('../util');
const $mock = require('mockjs');
const $colors = require('colors/safe');
const $stacktracey = require('stacktracey');

const getFile = (filepath, extname) => {
	const obj = $path.parse(filepath);
	filepath = $path.format({
		dir: obj.dir,
		root: obj.root,
		name: obj.base,
		ext: extname
	});

	if ($fs.existsSync(filepath)) {
		return filepath;
	} else {
		return '';
	}
};

const execErrMsg = (err, title) => {
	const stack = new $stacktracey(err);
	const msglist = [
		'[spore-mock] ' + title + ':',
		err.message,
		stack.pretty
	];
	msglist.forEach(msg => {
		console.error($colors.red(msg));
	});
	return msglist.join('\n');
};

const mockEntry = options => {

	const conf = $lodash.assign({
		debug: false,
		template: './',
		templateRoute: '/',
		mock: './',
		render: [],
		// Format output data for template files
		mockFormat: mockData => ({
			htmlWebpackPlugin: {
				options: {
					mock: mockData
				}
			}
		})
	}, options);

	return (req, res, next) => {

		if (conf.debug) {
			console.log('req.path:', req.path);
		}

		// Get relative path from root
		let reqCleanPath = '';
		if (conf.templateRoute && req.path.indexOf(conf.templateRoute) >= 0) {
			let relativePath = $path.relative(conf.templateRoute, req.path);
			if (conf.debug) {
				console.log('relativePath:', relativePath);
			}
			reqCleanPath = $util.cleanPath(relativePath);
		} else {
			reqCleanPath = $util.cleanPath(req.path);
		}

		let templateFilePath = $path.resolve(conf.template, reqCleanPath);
		let mockFilePath = $path.resolve(conf.mock, reqCleanPath);

		if (conf.debug) {
			console.log('reqCleanPath:', reqCleanPath);
			console.log('templateFilePath:', templateFilePath);
			console.log('mockFilePath:', mockFilePath);
		}

		let templateFile = '';
		let mockFile = '';

		mockFile = getFile(mockFilePath, '.js');

		// Support multi type template
		$util.eachRender(conf.render, item => {
			let file = getFile(templateFilePath, '.' + item.extname);
			if (file) {
				templateFile = file;
				return false;
			}
		});

		if (conf.debug) {
			console.log('templateFile:', templateFile);
			console.log('mockFile:', mockFile);
		}

		// Get mock data from local file
		// Clear require cache
		let mockData = null;
		if (mockFile) {
			$util.clearRequireCache();

			try {
				mockData = require(mockFile);

				// Execute if module.exports is function
				if (typeof mockData === 'function') {
					mockData = mockData(req, res);
				}
			} catch (err) {
				mockData = null;
				execErrMsg(err, 'Get mock data error');
			}

			// By pass if mockData is undefined or null
			if (mockData == null) {
				next();
				return;
			}

			// Gnenete mock data by mockjs
			mockData = $mock.mock(mockData);
		}

		let html = null;

		// Wrap mock data by config
		let htmlData = conf.mockFormat(mockData);

		if (templateFile) {
			// Has same relative path template
			// Render the template<commit_msg>合并 req.query, req.body 到 req.para, 方便 mock 数据开发<commit_after>const $fs = require('fs');
const $path = require('path');
const $lodash = require('lodash');
const $util = require('../util');
const $mock = require('mockjs');
const $colors = require('colors/safe');
const $stacktracey = require('stacktracey');

const getFile = (filepath, extname) => {
	const obj = $path.parse(filepath);
	filepath = $path.format({
		dir: obj.dir,
		root: obj.root,
		name: obj.base,
		ext: extname
	});

	if ($fs.existsSync(filepath)) {
		return filepath;
	} else {
		return '';
	}
};

const execErrMsg = (err, title) => {
	const stack = new $stacktracey(err);
	const msglist = [
		'[spore-mock] ' + title + ':',
		err.message,
		stack.pretty
	];
	msglist.forEach(msg => {
		console.error($colors.red(msg));
	});
	return msglist.join('\n');
};

const mockEntry = options => {

	const conf = $lodash.assign({
		debug: false,
		template: './',
		templateRoute: '/',
		mock: './',
		render: [],
		// Format output data for template files
		mockFormat: mockData => ({
			htmlWebpackPlugin: {
				options: {
					mock: mockData
				}
			}
		})
	}, options);

	return (req, res, next) => {

		if (conf.debug) {
			console.log('req.path:', req.path);
		}

		req.query = req.query || {};
		req.body = req.body || {};
		req.para = Object.assign(
			{},
			$lodash.cloneDeep(req.query),
			$lodash.cloneDeep(req.body)
		);

		// Get relative path from root
		let reqCleanPath = '';
		if (conf.templateRoute && req.path.indexOf(conf.templateRoute) >= 0) {
			let relativePath = $path.relative(conf.templateRoute, req.path);
			if (conf.debug) {
				console.log('relativePath:', relativePath);
			}
			reqCleanPath = $util.cleanPath(relativePath);
		} else {
			reqCleanPath = $util.cleanPath(req.path);
		}

		let templateFilePath = $path.resolve(conf.template, reqCleanPath);
		let mockFilePath = $path.resolve(conf.mock, reqCleanPath);

		if (conf.debug) {
			console.log('reqCleanPath:', reqCleanPath);
			console.log('templateFilePath:', templateFilePath);
			console.log('mockFilePath:', mockFilePath);
		}

		let templateFile = '';
		let mockFile = '';

		mockFile = getFile(mockFilePath, '.js');

		// Support multi type template
		$util.eachRender(conf.render, item => {
			let file = getFile(templateFilePath, '.' + item.extname);
			if (file) {
				templateFile = file;
				return false;
			}
		});

		if (conf.debug) {
			console.log('templateFile:', templateFile);
			console.log('mockFile:', mockFile);
		}

		// Get mock data from local file
		// Clear require cache
		let mockData = null;
		if (mockFile) {
			$util.clearRequireCache();

			try {
				mockData = require(mockFile);

				// Execute if module.exports is function
				if (typeof mockData === 'function') {
					mockData = mockData(req, res);
				}
			} catch (err) {
				mockData = null;
				execErrMsg(err, 'Get mock data error');
			}

			// By pass if mockData is undefined or null
			if (mockData == null) {
				next();
				return;
			}

			// Gnenete mock data by mockjs
			mockData = $mock.mock(mockData);
		}

		let html = null;

		// Wrap mock data with config mockFormat option
		let htmlData = conf.mockFormat(mockData);

		if (templateFile) {
			// Has same relative path template
			// Render the template
{'fraction_non_alphanumeric': 0.1608812807100967, 'fraction_numerical': 0.0003170074496750674, 'mean_word_length': 3.2405913978494625, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, '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': '3191675', 'n_tokens_mistral': 2461, 'n_tokens_neox': 2114, 'n_words': 504}