Simon Priet e69a613a37 feat: Created a mini nodeJS server with NewMan for testing without PostMan GUI.
This will mimic a run in a CD/CI environment or docker container.
2021-09-08 14:01:19 +02:00

137 lines
4.9 KiB
JavaScript

var fs = require('fs'),
nodePath = require('path'),
_ = require('lodash'),
async = require('async'),
mkdirp = require('mkdirp'),
// @todo: ES6: Change the sequence below to use object destructuring when Node v4 support is dropped
joinPath = nodePath.join,
parsePath = nodePath.parse,
resolvePath = nodePath.resolve,
/**
* The root path specifier
*
* @const
* @private
* @type {string}
*/
E = '',
/**
* Default timestamp separator.
*
* @const
* @private
* @type {string}
*/
TS_SEP = '-',
/**
* Writes the specified content to a file at the provided path.
*
* @param {Object} path - A set of path details for file writing.
* @param {String|Buffer} content - The content to be written to the file.
* @param {Object} options - A set of options for the current file write.
* @param {Function} cb - The callback invoked when the file writing operation has completed, with/without errors.
*/
writeFile = function (path, content, options, cb) {
fs.writeFile(path.unparsed, content, function (err) {
cb(_.set(err, 'help',
`error writing file "${path.unparsed}" for ${options.name || 'unknown-source'}`), path);
});
},
/**
* Generate a timestamp from date
*
* @param {Date=} date - The timestamp used to mark the exported file.
* @param {String=} separator - The optional string with which to separate different sections of the timestamp,
* defaults to TS_SEP
* @returns {String} - yyyy-mm-dd-HH-MM-SS-MS-0
*/
timestamp = function (date, separator) {
// use the iso string to ensure left padding and other stuff is taken care of
return (date || new Date()).toISOString().replace(/[^\d]+/g, _.isString(separator) ? separator : TS_SEP);
};
/**
* Module whose job is to export a file which is in an export format.
*
* @param {Object} options - The set of file export options.
* @param {String} options.path - The path to the exported file.
* @param {String|Object} options.content - The JSON / stringified content that is to be written to the file.
* @param {Function} done - The callback whose invocation marks the end of the file export routine.
* @returns {*}
*/
module.exports = function (options, done) {
// parse the path if one is available as string
var path = _.isString(options.path) && parsePath(resolvePath(options.path)),
content = _.isPlainObject(options.content) ? JSON.stringify(options.content, 0, 2) : (options.content || E);
// if a path was not provided by user, we need to prepare the default path. but create the default path only if one
// is provided.
if (!path && _.isString(options.default)) {
path = parsePath(options.default);
// delete the path and directory if one is detected when parsing defaults
path.root = E;
path.dir = 'newman';
// append timestamp
path.name = `${path.name}-${timestamp()}0`; // @todo make -0 become incremental if file name exists
path.base = path.name + path.ext;
}
// final check that path is valid
if (!(path && path.base)) {
return;
}
// now sore the unparsed result back for quick re-use during writing and a single place for unparsing
path.unparsed = joinPath(path.dir, path.base);
// in case the path has a directory, ensure that the directory is available
if (path.dir) {
async.waterfall([
function (next) {
mkdirp(path.dir)
.then(() => {
return next();
})
.catch((err) => {
return next(_.set(err, 'help',
`error creating path for file "${path.unparsed}" for ${options.name || 'unknown-source'}`));
});
},
function (next) {
fs.stat(path.unparsed, function (err, stat) { // eslint-disable-line handle-callback-err
next(null, stat);
});
},
function (stat, next) {
var target;
// handle cases where the specified export path is a pre-existing directory
if (stat && stat.isDirectory()) {
target = parsePath(options.default);
// append timestamp
// @todo make -0 become incremental if file name exists
target.name += '-' + timestamp() + '0';
target.base = target.name + target.ext;
path.unparsed = joinPath(path.unparsed, target.base);
}
next(null, path);
},
function (path, next) {
writeFile(path, content, options, next);
}
], done);
}
else {
writeFile(path, content, options, done);
}
};