UNPKG

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
"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; }