fakeit-facet
Version:
Command-line utility that generates fake data which can be output as JSON, YAML, CSON, or CSV formats based on models defined in YAML.
636 lines (514 loc) • 25.4 kB
JavaScript
"use strict";
var _typeof = require("@babel/runtime-corejs3/helpers/typeof");
var _Reflect$construct = require("@babel/runtime-corejs3/core-js-stable/reflect/construct");
var _WeakMap = require("@babel/runtime-corejs3/core-js-stable/weak-map");
var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor");
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
_Object$defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
exports.isServer = isServer;
exports.isString = isString;
exports.validate = exports.output_types = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs3/regenerator"));
var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes"));
var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/asyncToGenerator"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/inherits"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/getPrototypeOf"));
var _path = _interopRequireDefault(require("path"));
var _lodash = require("lodash");
var _toJs = _interopRequireWildcard(require("to-js"));
var _perfy = _interopRequireDefault(require("perfy"));
var _base = _interopRequireDefault(require("../base"));
var _utils = require("../utils");
var _defaultOptions = _interopRequireDefault(require("./default-options"));
function _getRequireWildcardCache(nodeInterop) { if (typeof _WeakMap !== "function") return null; var cacheBabelInterop = new _WeakMap(); var cacheNodeInterop = new _WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = _Object$defineProperty && _Object$getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? _Object$getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { _Object$defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
var output_types = ['return', 'console', 'couchbase', 'sync-gateway']; /// @name Output
/// @description
/// This is used to output data into different environments
exports.output_types = output_types;
var Output = /*#__PURE__*/function (_Base) {
(0, _inherits2["default"])(Output, _Base);
var _super = _createSuper(Output);
/// # @name constructor
/// # @arg {object} options [{}] - The options that apply to Base
/// # @arg {object} output_options - The options for how you want save data
/// # {
/// #
/// # }
/// # @todo update the output_options to have the final options and descriptions of each
function Output() {
var _this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var output_options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _classCallCheck2["default"])(this, Output);
_this = _super.call(this, options);
_this.output_options = (0, _lodash.extend)({}, _defaultOptions["default"], output_options);
_this.validateOutputOptions();
_this.prepared = false;
return _this;
} /// # @name prepare
/// # @description
/// # This is used to prepare the saving functionality that is determined by the
/// # options that were passed to the constructor.
/// # It sets a variable of `this.preparing` that ultimately calls `this.setup` that returns a promise.
/// # This way when you go to save data it, that function will know if the setup is complete or not and
/// # wait for it to be done before it starts saving data.
/// # @returns {promise} - The setup function that was called
/// # @async
(0, _createClass2["default"])(Output, [{
key: "prepare",
value: function prepare() {
this.preparing = true;
this.preparing = this.setup();
return this.preparing;
} /// # @name setup
/// # @description
/// # This is used to setup the saving function that will be used.
}, {
key: "setup",
value: function () {
var _setup = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
var _this2 = this;
var output, archive, Outputter;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!(this.preparing == null)) {
_context.next = 2;
break;
}
return _context.abrupt("return", this.prepare());
case 2:
output = this.output_options.output;
archive = this.output_options.archive;
if (!(0, _includes["default"])(output_types).call(output_types, output)) {
output = archive ? 'zip' : 'folder';
} // get the outputter to use
if (!(output !== 'return')) {
_context.next = 13;
break;
}
Outputter = require("./".concat(output))["default"]; // creates a new instance of it so that we can use it to output the data in
// what ever way that the user wants to output it in.
this.outputter = new Outputter(this.options, this.output_options); // if the outputter has a prepare function call it and await for it to be done
if (!(typeof this.outputter.prepare === 'function')) {
_context.next = 11;
break;
}
_context.next = 11;
return this.outputter.prepare();
case 11:
this.prepared = true;
return _context.abrupt("return");
case 13:
process.nextTick(function () {
_this2.prepared = true;
});
case 14:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
function setup() {
return _setup.apply(this, arguments);
}
return setup;
}() /// # @name output
/// # @description
/// # This is used to save data to any place that was passed in the constructor
/// # @arg {array, object} documents - The data that you want to be saved
/// # @arg {object} options - Options needed by the output such as scope or collection
/// # @returns {array, object, string} - This is determined by the output type that's passed and the format that's used.
/// # @async
// eslint-disable-next-line max-statements
}, {
key: "output",
value: function () {
var _output = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3(documents) {
var _context5,
_this3 = this;
var outputOptions,
count,
_this$output_options,
format,
spacing,
limit,
output,
name,
spinner,
times,
update,
parser,
parsed,
_context6,
result,
_args3 = arguments;
return _regenerator["default"].wrap(function _callee3$(_context9) {
while (1) {
switch (_context9.prev = _context9.next) {
case 0:
outputOptions = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {};
count = 0;
if (documents) {
_context9.next = 4;
break;
}
return _context9.abrupt("return", this.log('error', 'You must pass in documents to the output'));
case 4:
documents = _toJs["default"].array(documents);
if (!(this.prepared !== true)) {
_context9.next = 9;
break;
}
if (this.preparing == null) {
this.prepare();
}
_context9.next = 9;
return this.preparing;
case 9:
_this$output_options = this.output_options, format = _this$output_options.format, spacing = _this$output_options.spacing, limit = _this$output_options.limit, output = _this$output_options.output;
name = documents[0].__name; // eslint-disable-line
spinner = this.spinner("Outputting ".concat(name));
times = [];
update = function update() {
var _context2, _context3, _context4;
spinner.text = (0, _concat["default"])(_context2 = (0, _concat["default"])(_context3 = (0, _concat["default"])(_context4 = "Outputting ".concat(name, " to ")).call(_context4, output, " (")).call(_context3, count, "/")).call(_context2, documents.length, ")");
if (times.length) {
spinner.text += " (".concat((0, _lodash.mean)(times).toFixed(2), "ms on average)");
}
};
parser = this.getParser(output, format); // if the output type is `return` or `console` then this will return the complete
// data set instead of running them individually
if (!(0, _includes["default"])(_context5 = ['return', 'console']).call(_context5, output)) {
_context9.next = 29;
break;
}
_context9.next = 18;
return parser(documents, spacing);
case 18:
parsed = _context9.sent;
if (!(output === 'console')) {
_context9.next = 28;
break;
}
spinner.start();
_context9.next = 23;
return this.outputter.output(null, parsed, outputOptions);
case 23:
result = _context9.sent;
spinner.text = (0, _concat["default"])(_context6 = "Outputting ".concat(name, " to ")).call(_context6, output);
spinner.stopAndPersist();
console.log(result);
return _context9.abrupt("return", result);
case 28:
return _context9.abrupt("return", parsed);
case 29:
// if the output isn't `return` or `console` and the `format` is `csv`
// then it needs to be updated
if (format === 'csv') {
documents = [documents];
} // reformat the data into the output type
spinner.start();
return _context9.abrupt("return", (0, _utils.pool)(documents, /*#__PURE__*/function () {
var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(document, i) {
var _context7;
var label, key, result;
return _regenerator["default"].wrap(function _callee2$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
label = (0, _lodash.uniqueId)((0, _concat["default"])(_context7 = "document ".concat(name, " ")).call(_context7, i));
_perfy["default"].start(label);
key = document.__key || document.__name || (document[0] || {}).__name || ''; // eslint-disable-line no-underscore-dangle
// use the outputter's output function to output the data
_context8.t0 = _this3.outputter;
_context8.t1 = key;
_context8.next = 7;
return parser(document, spacing);
case 7:
_context8.t2 = _context8.sent;
_context8.t3 = outputOptions;
_context8.next = 11;
return _context8.t0.output.call(_context8.t0, _context8.t1, _context8.t2, _context8.t3);
case 11:
result = _context8.sent;
update(count++);
times.push(_perfy["default"].end(label).milliseconds);
return _context8.abrupt("return", result);
case 15:
case "end":
return _context8.stop();
}
}
}, _callee2);
}));
return function (_x2, _x3) {
return _ref.apply(this, arguments);
};
}(), limit).then(function (result) {
spinner.stop();
return result;
})["catch"](function (err) {
spinner.fail(err);
}));
case 32:
case "end":
return _context9.stop();
}
}
}, _callee3, this);
}));
function output(_x) {
return _output.apply(this, arguments);
}
return output;
}() /// # @name finalize
/// # @description
/// # This is used to clean up anything that needs to be cleaned up
/// # like a connection to a data base, any event listeners, or finish outputting a zip file.
/// # @async
}, {
key: "finalize",
value: function () {
var _finalize = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4() {
return _regenerator["default"].wrap(function _callee4$(_context10) {
while (1) {
switch (_context10.prev = _context10.next) {
case 0:
if (!(this.outputter && _toJs.is["function"](this.outputter.finalize))) {
_context10.next = 3;
break;
}
_context10.next = 3;
return this.outputter.finalize();
case 3:
case "end":
return _context10.stop();
}
}
}, _callee4, this);
}));
function finalize() {
return _finalize.apply(this, arguments);
}
return finalize;
}() /// # @name validateOutputOptions
/// # @description This is used to validate the output options
/// # @throws {error} - If an option that was passed is invalid.
}, {
key: "validateOutputOptions",
value: function validateOutputOptions() {
var _this4 = this;
_toJs["default"].each(this.output_options, function (_ref2) {
var key = _ref2.key,
value = _ref2.value;
try {
validate[key](value, _this4.output_options);
} catch (e) {
_this4.log('error', e);
}
});
} /// # @name getParser
/// # @description Returns a parser function for the given output type and format
/// # @arg {string} output - Output type
/// # @arg {string} format - Output format
/// # @returns {function} - Function to format a document
}, {
key: "getParser",
value: function getParser(output, format) {
if (output === 'couchbase' && format === 'json') {
return function (obj) {
return obj;
};
}
return _utils.parsers[format].stringify;
}
}]);
return Output;
}(_base["default"]); /// @name Output validate
/// @description This holds the different options that can be passed to the Output constructor
/// @type {object}
exports["default"] = Output;
var validate = {
/// # @name format
/// # @description Used to validate the format option
/// # @arg {string} option - The option to validate against
/// # @throws {error} - If the format option that was pass was invalid
format: function format(option) {
var formats = ['json', 'csv', 'yaml', 'yml', 'cson'];
if (isString(option, 'format') && (0, _includes["default"])(formats).call(formats, option)) {
return;
}
throw new Error("You must use one of the following formats ".concat(formats, ". You passed ").concat(option));
},
/// # @name spacing
/// # @description Used to validate the spacing option
/// # @arg {number} option - The option to validate against
/// # @throws {error} - If the spacing option that was pass was invalid
spacing: function spacing(option) {
if (option === '0' || option === 'null') {
option = 0;
}
if (!_toJs.is.number(option)) {
throw new Error('The spacing option must be a number');
}
},
/// # @name output
/// # @description Used to validate the output option
/// # @arg {string} option - The option to validate against
/// # @throws {error} - If the output option that was pass was invalid
output: function output(option) {
if (!isString(option, 'output')) return;
if ((0, _includes["default"])(output_types).call(output_types, option) || !_path["default"].extname(option)) {
return;
}
throw new Error("The output option must be ".concat(output_types.join(', '), ", or a folder path"));
},
/// # @name highlight
/// # @description Used to validate the highlight option
/// # @arg {boolean} option - The option to validate against
/// # @throws {error} - If the highlight option that was pass was invalid
highlight: function highlight(option) {
if (!_toJs.is["boolean"](option)) {
throw new Error('The highlight option must be a boolean');
}
},
/// # @name limit
/// # @description Used to validate the limit option
/// # @arg {number} option - The option to validate against
/// # @throws {error} - If the limit option that was pass was invalid
limit: function limit(option) {
if (!_toJs.is.number(option)) {
throw new Error('The limit option must be a number');
}
},
/// # @name archive
/// # @description Used to validate the archive option
/// # @arg {boolean} option - The option to validate against
/// # @throws {error} - If the archive option that was pass was invalid
archive: function archive(option, _ref3) {
var _context11;
var output = _ref3.output;
if (!_toJs.is.string(option)) {
throw new Error('The archive option must be a string');
} // there's no archive file specified
if (!option.length) return;
if (option && (0, _includes["default"])(_context11 = ['return', 'console']).call(_context11, output)) {
throw new Error("You can't have an archive file when you have the output option set to ".concat(output));
} else if (_path["default"].extname(option) !== '.zip') {
throw new Error('The archive file must have a file extention of `.zip`');
}
},
/// # @name server
/// # @description Used to validate the server option
/// # @arg {string} option - The option to validate against
/// # @arg {object} options - The other options for that are being validated
/// # @throws {error} - If the server option that was pass was invalid
server: function server(option, _ref4) {
var output = _ref4.output,
archive = _ref4.archive;
// ignore this validation if the output isn't one of these
if (!isServer(output)) return;
if (archive === true) {
throw new Error("The archive option can't be used with ".concat(option));
}
isString(option, 'server');
},
/// # @name bucket
/// # @description Used to validate the bucket option
/// # @arg {string} option - The option to validate against
/// # @arg {object} options - The other options for that are being validated
/// # @throws {error} - If the bucket option that was pass was invalid
bucket: function bucket(option, _ref5) {
var output = _ref5.output;
// ignore this validation if the output isn't one of these
if (!isServer(output)) return;
isString(option, 'bucket');
},
/// # @name username
/// # @description Used to validate the username option
/// # @arg {string} option - The option to validate against
/// # @arg {object} options - The other options for that are being validated
/// # @throws {error} - If the username option that was pass was invalid
username: function username(option) {
if (!_toJs.is.string(option)) {
throw new Error('The username option must be a string');
}
},
/// # @name password
/// # @description Used to validate the password option
/// # @arg {string} option - The option to validate against
/// # @arg {object} options - The other options for that are being validated
/// # @throws {error} - If the password option that was pass was invalid
password: function password(option) {
if (!_toJs.is.string(option)) {
throw new Error('The password option must be a string');
}
},
/// # @name limit
/// # @description Used to validate the limit option
/// # @arg {number} option - The option to validate against
/// # @throws {error} - If the limit option that was pass was invalid
timeout: function timeout(option) {
if (!_toJs.is.number(option)) {
throw new Error('The timeout option must be a number');
}
},
/// # @name useStreams
/// # @description Used to validate the useStreams option
/// # @arg {boolean} option - The option to validate against
/// # @throws {error} - If the useStreams option that was pass was invalid
useStreams: function useStreams(option) {
if (!_toJs.is["boolean"](option)) {
throw new Error('The useStreams option must be a boolean');
}
},
/// # @name highWaterMark
/// # @description Used to validate the highWaterMark option
/// # @arg {number} option - The option to validate against
/// # @throws {error} - If the highWaterMark option that was pass was invalid
highWaterMark: function highWaterMark(option) {
if (!_toJs.is.number(option)) {
throw new Error('The highWaterMark option must be a number');
}
}
}; /// @name isServer
/// @description This is used to check if the output is `sync-gateway` or `couchbase`
/// @arg {string} output - The output that's being used
/// @returns {boolean} - If true the output option is a server
exports.validate = validate;
function isServer(output) {
var _context12;
return (0, _includes["default"])(_context12 = ['sync-gateway', 'couchbase']).call(_context12, output);
} /// @name isString
/// @description This is used to check if an option is a string and that it has a length
/// @arg {*} option - The option that's passed
/// @arg {string} name - The name of the validate function that this is called in
/// @returns {boolean} - If true the option that was passed is a string and has a length.
/// @throws {error} - If the option isn't a string
/// @throws {error} - If the option is a string and doesn't have a length
function isString(option) {
var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
if (name) {
name = " ".concat(name, " ");
}
if (!_toJs.is.string(option)) {
throw new Error("The".concat(name, "option must be a string"));
} else if (_toJs.is.string(option) && !option.length) {
throw new Error("The".concat(name, "option must have a length"));
}
return true;
}