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.
998 lines (762 loc) • 39.4 kB
JavaScript
"use strict";
var _typeof = require("@babel/runtime-corejs3/helpers/typeof");
var _forEachInstanceProperty2 = require("@babel/runtime-corejs3/core-js-stable/instance/for-each");
var _findInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/find");
var _mapInstanceProperty2 = require("@babel/runtime-corejs3/core-js-stable/instance/map");
var _Reflect$construct = require("@babel/runtime-corejs3/core-js-stable/reflect/construct");
var _sliceInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/slice");
var _Array$from = require("@babel/runtime-corejs3/core-js-stable/array/from");
var _Symbol = require("@babel/runtime-corejs3/core-js-stable/symbol");
var _getIteratorMethod = require("@babel/runtime-corejs3/core-js/get-iterator-method");
var _Array$isArray = require("@babel/runtime-corejs3/core-js-stable/array/is-array");
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.parseModelCount = parseModelCount;
exports.parseModelDefaults = parseModelDefaults;
exports.parseModelFunctions = parseModelFunctions;
exports.parseModelInputs = parseModelInputs;
exports.parseModelReferences = parseModelReferences;
exports.parseModelSeed = parseModelSeed;
exports.parseModelTypes = parseModelTypes;
exports.resolveDependants = resolveDependants;
exports.resolveDependenciesOrder = resolveDependenciesOrder;
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs3/regenerator"));
var _reduce = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/reduce"));
var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes"));
var _filter = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/filter"));
var _assign = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/assign"));
var _forEach = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/for-each"));
var _trim = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/trim"));
var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
var _sort = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/sort"));
var _parseInt2 = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/parse-int"));
var _entries = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/entries"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/slicedToArray"));
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 _asyncArrayMethods = require("async-array-methods");
var _fsExtraPromisify = _interopRequireDefault(require("fs-extra-promisify"));
var _path = _interopRequireDefault(require("path"));
var _dependencyResolver = _interopRequireDefault(require("dependency-resolver"));
var _lodash = require("lodash");
var _toJs = _interopRequireWildcard(require("to-js"));
var _core = require("@babel/core");
var _globby = _interopRequireDefault(require("globby"));
var _findRoot = _interopRequireDefault(require("find-root"));
var _base = _interopRequireDefault(require("./base"));
var utils = _interopRequireWildcard(require("./utils"));
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 _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && _getIteratorMethod(o) || o["@@iterator"]; if (!it) { if (_Array$isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { var _context28; if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = _sliceInstanceProperty(_context28 = Object.prototype.toString.call(o)).call(_context28, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return _Array$from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
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; } }
/// /
/// @name Models
/// @page api/models
/// /
var Models = /*#__PURE__*/function (_Base) {
(0, _inherits2["default"])(Models, _Base);
var _super = _createSuper(Models);
function Models() {
var _this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
(0, _classCallCheck2["default"])(this, Models);
_this = _super.call(this, _toJs["default"].extend({
count: 0,
seed: 0,
babel_config: '+(.babelrc|package.json)'
}, options)); // holds all the inputs that are registerd
_this.inputs = {};
_this.models = []; // holds the parsed models
_this.registered_models = []; // holds the paths that have already been added
_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"])(Models, [{
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.
/// # @async
}, {
key: "setup",
value: function () {
var _setup = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
var _this2 = this,
_context;
var babel_config, file, config;
return _regenerator["default"].wrap(function _callee$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
if (!(this.preparing == null)) {
_context2.next = 2;
break;
}
return _context2.abrupt("return", this.prepare());
case 2:
babel_config = this.options.babel_config;
if (_toJs.is.string(babel_config)) {
_context2.next = 6;
break;
}
process.nextTick(function () {
_this2.prepared = true;
});
return _context2.abrupt("return");
case 6:
file = (0, _reduce["default"])(_context = [process.cwd(), this.options.root]).call(_context, function (prev, next) {
try {
return (0, _concat["default"])(prev).call(prev, _path["default"].join((0, _findRoot["default"])(next), babel_config));
} catch (e) {
return prev;
}
}, []);
_context2.next = 9;
return (0, _globby["default"])(_toJs["default"].unique(file), {
dot: true
});
case 9:
file = _context2.sent;
file = file[0]; // eslint-disable-line
if (!file) {
_context2.next = 17;
break;
}
_context2.next = 14;
return _fsExtraPromisify["default"].readJson(file);
case 14:
config = _context2.sent;
if ((0, _includes["default"])(file).call(file, 'package.json')) {
config = config.babelConfig || {};
}
this.options.babel_config = config;
case 17:
this.prepared = true;
case 18:
case "end":
return _context2.stop();
}
}
}, _callee, this);
}));
function setup() {
return _setup.apply(this, arguments);
}
return setup;
}() /// # @name update
/// # @description
/// # This updates the progress spinner to show how many models have been parsed and how many are left
}, {
key: "update",
value: function update() {
var _context3;
this.progress.text = (0, _concat["default"])(_context3 = "Models (".concat(this.models.length, "/")).call(_context3, this.registered_models.length, ")");
} /// @name filterModelFiles
/// @description This is used to filter out valid and unregistered model files
/// @returns {array}
}, {
key: "filterModelFiles",
value: function filterModelFiles(files) {
var _context4,
_this3 = this;
return (0, _filter["default"])(_context4 = _toJs["default"].flatten(files)).call(_context4, function (file) {
var _context5;
return !!file && /\.(ya?ml)$/i.test(file) && !(0, _includes["default"])(_context5 = _this3.registered_models).call(_context5, file);
});
}
}, {
key: "registerModels",
value: function () {
var _registerModels = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3(models) {
var _this4 = this;
var dependency,
files,
_args3 = arguments;
return _regenerator["default"].wrap(function _callee3$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
dependency = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : false;
this.progress = this.progress || this.spinner('Models').start(); // if models weren't passed in then don't do anything
if (models) {
_context8.next = 4;
break;
}
return _context8.abrupt("return");
case 4:
if (!(this.prepared !== true)) {
_context8.next = 8;
break;
}
if (this.preparing == null) {
this.prepare();
}
_context8.next = 8;
return this.preparing;
case 8:
_context8.t0 = this;
_context8.next = 11;
return utils.findFiles(this.resolvePaths(models));
case 11:
_context8.t1 = _context8.sent;
files = _context8.t0.filterModelFiles.call(_context8.t0, _context8.t1);
if (files.length) {
_context8.next = 17;
break;
}
if (dependency) {
_context8.next = 16;
break;
}
throw new Error('No valid model files found.');
case 16:
return _context8.abrupt("return");
case 17:
_context8.next = 19;
return (0, _forEachInstanceProperty2(_asyncArrayMethods))(files, /*#__PURE__*/function () {
var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(file) {
var _context6;
var _model, model;
return _regenerator["default"].wrap(function _callee2$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
if (!(0, _includes["default"])(_context6 = _this4.registered_models).call(_context6, file)) {
_context7.next = 3;
break;
}
if (!dependency) {
_model = (0, _findInstanceProperty(_lodash))(_this4.models, ['file', file]);
_model.is_dependency = dependency;
}
return _context7.abrupt("return");
case 3:
// add it to the models
_this4.registered_models.push(file);
_this4.update(); // read yaml file and convert it to json
_context7.t0 = utils.parsers.yaml;
_context7.t1 = _toJs["default"];
_context7.next = 9;
return _fsExtraPromisify["default"].readFile(file);
case 9:
_context7.t2 = _context7.sent;
_context7.t3 = _context7.t1.string.call(_context7.t1, _context7.t2);
_context7.next = 13;
return _context7.t0.parse.call(_context7.t0, _context7.t3);
case 13:
model = _context7.sent;
// used for debugging
model.file = file; // sets the root of the model so that we can resolve inputs and dependencies later
// sets the root of the model so that we can resolve inputs and dependencies later
model.root = _path["default"].resolve(_this4.options.root, _path["default"].dirname(model.file)); // used to determine if something is a dependency or not.
// used to determine if something is a dependency or not.
if (model.is_dependency == null) {
model.is_dependency = dependency;
}
/* istanbul ignore if : currently hard to test */
/* istanbul ignore if : currently hard to test */
if (!model.name) {
model.name = _path["default"].basename(file).split('.')[0]; // eslint-disable-line
} // validate the model
/* istanbul ignore if : currently hard to test */
// validate the model
/* istanbul ignore if : currently hard to test */
if (!model.type) {
_this4.log('error', new Error("The model ".concat(model.name, " must have a \"type\" property.")));
}
/* istanbul ignore if : currently hard to test */
/* istanbul ignore if : currently hard to test */
if (!model.key) {
_this4.log('error', new Error("The model ".concat(model.name, " must have a \"key\" property.")));
} // add the parsed model to the global object should always have a model name
_context7.next = 22;
return _this4.parseModel(model);
case 22:
_this4.models.push(model);
_this4.update();
case 24:
case "end":
return _context7.stop();
}
}
}, _callee2);
}));
return function (_x2) {
return _ref.apply(this, arguments);
};
}())["catch"](function (err) {
_this4.progress.fail(err);
});
case 19:
// update the models order
this.models = resolveDependenciesOrder(this.models);
this.models = resolveDependants(this.models);
if (this.models.length === this.registered_models.length) {
this.progress.stop();
}
return _context8.abrupt("return", this);
case 23:
case "end":
return _context8.stop();
}
}
}, _callee3, this);
}));
function registerModels(_x) {
return _registerModels.apply(this, arguments);
}
return registerModels;
}() /// # @name parseModel
/// # @description
/// # This is used to parse the model that was passed and add the functions, and fix the types, data, and defaults
/// # @arg {object} model - The model to parse.
/// # @returns {object} - The model that's been updated
}, {
key: "parseModel",
value: function () {
var _parseModel = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4(model) {
var inputs, dependencies;
return _regenerator["default"].wrap(function _callee4$(_context9) {
while (1) {
switch (_context9.prev = _context9.next) {
case 0:
// resolve the input paths
parseModelDefaults(model);
model.data.inputs = this.resolvePaths(model.data.inputs, model.root); // resolve the dependencies paths
model.data.dependencies = this.resolvePaths(model.data.dependencies, model.root);
inputs = parseModelInputs(model);
dependencies = this.parseModelDependencies(model);
parseModelFunctions(model, this.options.babel_config);
parseModelReferences(model);
parseModelTypes(model);
parseModelCount(model, this.options.count);
parseModelSeed(model, this.options.seed); // add this models inputs to the main inputs object
_context9.t0 = _assign["default"];
_context9.t1 = this.inputs || {};
_context9.next = 14;
return inputs;
case 14:
_context9.t2 = _context9.sent;
this.inputs = (0, _context9.t0)(_context9.t1, _context9.t2);
_context9.next = 18;
return dependencies;
case 18:
return _context9.abrupt("return", model);
case 19:
case "end":
return _context9.stop();
}
}
}, _callee4, this);
}));
function parseModel(_x3) {
return _parseModel.apply(this, arguments);
}
return parseModel;
}() /// # @name parseModel
/// # @description
/// # This is used to parse model dependencies if they have any
/// # @arg {object} model - The model to parse.
/// # @async
}, {
key: "parseModelDependencies",
value: function () {
var _parseModelDependencies = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5(model) {
var files;
return _regenerator["default"].wrap(function _callee5$(_context10) {
while (1) {
switch (_context10.prev = _context10.next) {
case 0:
if (!(!model.data.dependencies || !model.data.dependencies.length)) {
_context10.next = 3;
break;
}
model.data.dependencies = [];
return _context10.abrupt("return");
case 3:
_context10.t0 = _toJs["default"];
_context10.next = 6;
return utils.findFiles(model.data.dependencies);
case 6:
_context10.t1 = _context10.sent;
files = _context10.t0.flatten.call(_context10.t0, _context10.t1);
if (files.length) {
_context10.next = 11;
break;
}
model.data.dependencies = [];
return _context10.abrupt("return");
case 11:
_context10.next = 13;
return this.registerModels(files, true);
case 13:
case "end":
return _context10.stop();
}
}
}, _callee5, this);
}));
function parseModelDependencies(_x4) {
return _parseModelDependencies.apply(this, arguments);
}
return parseModelDependencies;
}()
}]);
return Models;
}(_base["default"]); /// @name parseModelInputs
/// @description
/// This is used to parse files that are used to generate specific data
/// @arg {object} model - The model to parse
/// @returns {object}
/// @async
/// @note {5} The `model.data.input` paths must already be resolved to be a absolute path.
exports["default"] = Models;
function parseModelInputs(_x5) {
return _parseModelInputs.apply(this, arguments);
} /// @name parseModelFunctions
/// @description
/// searches the model for any of the pre / post run and build functions and generates them
/// @arg {object} model - The model to update
/// @arg {string, object} babel_config [{}] - The configuration to use for babel
function _parseModelInputs() {
_parseModelInputs = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee7(model) {
var _context24;
var inputs, files;
return _regenerator["default"].wrap(function _callee7$(_context27) {
while (1) {
switch (_context27.prev = _context27.next) {
case 0:
if (!(!model.data.inputs || !model.data.inputs.length)) {
_context27.next = 3;
break;
}
model.data.inputs = [];
return _context27.abrupt("return", {});
case 3:
inputs = {}; // get list of files, flatten the array of files and filter files for valid input formats: csv, json, cson, yaml and zip
_context27.t0 = _filter["default"];
_context27.t1 = _toJs["default"];
_context27.next = 8;
return utils.findFiles(model.data.inputs);
case 8:
_context27.t2 = _context27.sent;
_context27.t3 = _context24 = _context27.t1.flatten.call(_context27.t1, _context27.t2);
files = (0, _context27.t0)(_context27.t3).call(_context24, function (file) {
return !!file && /\.(csv|json|cson|ya?ml|zip)$/i.test(file);
});
if (files.length) {
_context27.next = 13;
break;
}
throw new Error("No valid input files found for ".concat(model.file));
case 13:
_context27.next = 15;
return utils.readFiles(files);
case 15:
files = _context27.sent;
_context27.next = 18;
return (0, _mapInstanceProperty2(_asyncArrayMethods))(files, /*#__PURE__*/function () {
var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee6(file) {
var _context25;
var parser;
return _regenerator["default"].wrap(function _callee6$(_context26) {
while (1) {
switch (_context26.prev = _context26.next) {
case 0:
// get the current parser to use
parser = utils.parsers[file.ext.replace(/^\./, '')];
if (parser) {
_context26.next = 3;
break;
}
throw new Error((0, _concat["default"])(_context25 = "No valid parser could be found for \"".concat(file.name, ".")).call(_context25, file.type, "\""));
case 3:
_context26.next = 5;
return parser.parse(file.content);
case 5:
inputs[file.name] = _context26.sent;
return _context26.abrupt("return", file);
case 7:
case "end":
return _context26.stop();
}
}
}, _callee6);
}));
return function (_x6) {
return _ref2.apply(this, arguments);
};
}());
case 18:
return _context27.abrupt("return", inputs);
case 19:
case "end":
return _context27.stop();
}
}
}, _callee7);
}));
return _parseModelInputs.apply(this, arguments);
}
function parseModelFunctions(model) {
var babel_config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var paths = utils.objectSearch(model, /((pre|post)_run)|(pre_|post_)?build$/);
(0, _forEach["default"])(paths).call(paths, function (function_path) {
var _context11, _context12, _context13, _context17, _context18;
var name = _toJs["default"].camelCase(function_path); // get the function
var fn = (0, _filter["default"])(_context11 = (0, _trim["default"])(_context12 = (0, _lodash.get)(model, function_path)).call(_context12).split('\n')).call(_context11, Boolean); // if it's a single line function then ensure that the value is returned
// just like normal es6 arrow functions
if (fn.length === 1) {
fn = ["return ".concat(fn[0].replace(/^return\s+/, ''))];
} // indent each line and create a string
fn = (0, _filter["default"])(_context13 = (0, _map["default"])(fn).call(fn, function (line) {
return " ".concat(line);
})).call(_context13, Boolean).join('\n'); // wrap the users function in the function we're going to use to trigger their function
fn = "function __result(documents, globals, inputs, faker, chance, document_index, require) {\n".concat(fn, "\n}"); // if a babel config exists then transform the function
if (_toJs.is.plainObject(babel_config) && !_toJs.is.empty(babel_config)) {
try {
// transform the function and remove the `'use strict';\n` part that babel adds if it exists
fn = (0, _core.transform)(fn, babel_config).code.replace(/^.use strict.;\n+/, '');
} catch (e) {
var _context14, _context15, _context16;
var file_message = model.file ? " in ".concat(model.file) : '';
e.message = (0, _trim["default"])(_context14 = (0, _concat["default"])(_context15 = (0, _concat["default"])(_context16 = "Failed to transpile ".concat(function_path, " with babel")).call(_context16, file_message, "\n")).call(_context15, e.message)).call(_context14);
throw e;
}
} // create the main function that will be run.
/* eslint-disable indent */
fn = ["function ".concat(name, "(_documents, _globals, _inputs, _faker, _chance, _document_index, _require) {"), // indent each line and create a string
(0, _filter["default"])(_context17 = (0, _map["default"])(_context18 = fn.split('\n')).call(_context18, function (line) {
return " ".concat(line);
})).call(_context17, Boolean).join('\n'), ' return __result.apply(this, [].slice.call(arguments));', '}'].join('\n');
/* eslint-enable indent */
try {
(0, _lodash.set)(model, function_path, new Function('require', 'process', "return ".concat(fn))(require, process)); // eslint-disable-line no-new-func
} catch (e) {
var _context19, _context20;
throw new Error((0, _concat["default"])(_context19 = (0, _concat["default"])(_context20 = "Function Error in model '".concat(model.name, "', for property: ")).call(_context20, function_path, ", Reason: ")).call(_context19, e.message));
}
});
} /// @name parseModelReferences
/// @description
/// searches the model for any '$ref' values that are pointing to definitions,
/// sub_models, etc. and copies the reference to the schema
/// @arg {object} model - The model to update
function parseModelReferences(model) {
var _context21;
var pattern = /\.(schema|items).\$ref$/; // sort the array so definitions come first before properties, this allows definitions to have definitions
var paths = (0, _sort["default"])(_context21 = utils.objectSearch(model, pattern)).call(_context21);
var _iterator = _createForOfIteratorHelper(paths),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var ref = _step.value;
var set_location = ref.replace(pattern, '');
if ((0, _includes["default"])(ref).call(ref, '.items.')) {
set_location += '.items';
}
var original_property = (0, _lodash.get)(model, set_location);
var get_location = (0, _lodash.get)(model, ref).replace(/^#\//, '').replace('/', '.');
var updated_property = _toJs["default"].extend(_toJs["default"].clone(original_property), (0, _lodash.get)(model, get_location));
(0, _lodash.set)(model, set_location, updated_property);
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
} /// @name parseModelTypes
/// @description
/// Searches the model for any properties or items and makes
/// sure the default types exist
/// @arg {object} model - The model to update
function parseModelTypes(model) {
var _iterator2 = _createForOfIteratorHelper(utils.objectSearch(model, /.*properties\.[^.]+(\.items)?$/)),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var type_path = _step2.value;
var property = (0, _lodash.get)(model, type_path); // make sure there is a type property set
if (property.type == null) {
property.type = 'null';
(0, _lodash.set)(model, type_path, property);
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
} /// @name parseModelTypes
/// @description
/// Sets any model defaults that are not defined
/// @arg {object} model - The model to update
function parseModelDefaults(model) {
// make sure it has the defaults for min, max, count
model.data = _toJs["default"].extend({
min: 0,
max: 0,
count: 0
}, model.data); // find properties or items that do not have a data block and assign it
var _iterator3 = _createForOfIteratorHelper(utils.objectSearch(model, /^(.*properties\.[^.]+)$/)),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var data_path = _step3.value;
var property = (0, _lodash.get)(model, data_path) || {}; // if it's an array and has items ensure it has defaults
if (property.type === 'array' && property.items) {
property.items = _toJs["default"].extend({
data: {
min: 0,
max: 0,
count: 0
}
}, property.items);
} else {
property = _toJs["default"].extend({
data: {}
}, property);
}
(0, _lodash.set)(model, data_path, property);
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
} /// @name parseModelCount
/// @description Determines the total number of documents to run
/// @arg {object} model - The model to update
/// @arg {undefined, null, number} count - The count to override the model settings
function parseModelCount(model, count) {
var value = _toJs["default"].number(count);
var data = model.data;
if (!value) {
if (data.count > 0) {
value = data.count;
} else if (!!data.min && !!data.max) {
value = _toJs["default"].random(data.min, data.max);
}
} // if count is null or 0 then set it to 1
if (!value) {
value = 1;
}
model.data.count = value;
} /// @name parseModelSeed
/// @description Resolves the seed that was passed in
/// @arg {object} model - The model to update
/// @arg {undefined, null, number, string} seed - The seed to override the model settings
/// @note {2} - The resolved seed will either be null or a number since faker requires the seed to be a number
function parseModelSeed(model, seed) {
model.seed = seed || model.seed;
if (typeof model.seed === 'string') {
seed = '';
var _iterator4 = _createForOfIteratorHelper(model.seed),
_step4;
try {
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
var _char = _step4.value;
seed += _char.charCodeAt(0);
}
} catch (err) {
_iterator4.e(err);
} finally {
_iterator4.f();
}
model.seed = (0, _parseInt2["default"])(seed);
}
} /// @name resolveDependenciesOrder
/// @description Resolves the dependency order that file models need to run in.
/// @arg {array} models [[]] - The models to prioritize
/// @returns {array} - The models are returned in order with all the models that don't have dependencies first
function resolveDependenciesOrder() {
var _context22;
var models = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
if (models.length <= 1) {
return models;
}
var resolver = new _dependencyResolver["default"]();
var order = {};
function sortByFunction(item) {
return item.data.dependencies.length;
}
models = (0, _lodash.sortBy)(models, [sortByFunction]);
var _iterator5 = _createForOfIteratorHelper((0, _entries["default"])(_toJs["default"]).call(_toJs["default"], models)),
_step5;
try {
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
var _step5$value = (0, _slicedToArray2["default"])(_step5.value, 2),
i = _step5$value[0],
_step5$value$ = _step5$value[1],
file = _step5$value$.file,
data = _step5$value$.data;
order[file] = i;
resolver.add(file);
var dependencies = _toJs["default"].array(data && data.dependencies);
var _iterator6 = _createForOfIteratorHelper(dependencies),
_step6;
try {
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
var dependency = _step6.value;
resolver.setDependency(file, dependency);
}
} catch (err) {
_iterator6.e(err);
} finally {
_iterator6.f();
}
}
} catch (err) {
_iterator5.e(err);
} finally {
_iterator5.f();
}
return (0, _map["default"])(_context22 = (0, _sort["default"])(resolver).call(resolver)).call(_context22, function (file) {
return models[order[file]];
});
} /// @name resolveDependenciesOf
/// @description Figures out which models use the model as a dependency
/// @arg {array} models [[]] - The models to loop over
/// @returns {array} - The models are returned with the `dependants`
function resolveDependants() {
var models = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
return (0, _map["default"])(models).call(models, function (model) {
// loop over each model and find out which other models depend on the current model
model.dependants = (0, _reduce["default"])(models).call(models, function (prev, next) {
var _context23;
if ( // the next file in the loop doesn't matche the current models file
model.file !== next.file // the next models dependencies includes the current models files
&& (0, _includes["default"])(_context23 = next.data.dependencies).call(_context23, model.file)) {
prev.push(next.file);
}
return prev;
}, []);
return model;
});
}