const { extend, isFunction, isObject } = require('lodash'); export default class KnexFactory { constructor(knex) { this.knex = knex; this.factories = []; } define(name, tableName, defaultAttributes) { this.factories[name] = { tableName, defaultAttributes }; } async build(factoryName, attributes) { const factory = this.factories[factoryName]; if (!factory) { throw `Unkown factory: ${factoryName}`; } let { defaultAttributes } = factory; const insertData = {}; if( 'function' === typeof defaultAttributes) { defaultAttributes = await defaultAttributes(); } extend(insertData, defaultAttributes, attributes); for (let k in insertData) { const v = insertData[k]; if (isFunction(v)) { insertData[k] = await v(); } else { insertData[k] = await v; } if (isObject(insertData[k]) && insertData[k].id) { insertData[k] = insertData[k].id; } }; return insertData; } async create(factoryName, attributes) { const factory = this.factories[factoryName]; const insertData = await this.build(factoryName, attributes); const { tableName } = factory; const [id] = await this.knex(tableName).insert(insertData); const record = await this.knex(tableName).where({ id }).first(); return record; } }