@actonate/mirkwood
Version:
GraphQL based Rapid Server-side Development framework
273 lines (224 loc) • 8.66 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); //@ts-check
var _typeorm = require('typeorm');
var _lodash = require('lodash');
var _types = require('./types');
var _types2 = _interopRequireDefault(_types);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var DEFAULT_CONNECTION = 'development';
var DEFAULT_ADAPTER = 'postgres';
var ORM = function () {
function ORM(_ref) {
var config = _ref.config;
_classCallCheck(this, ORM);
this.entities = [];
this.config = config;
this.getConnection = this.getConnection.bind(this);
}
_createClass(ORM, [{
key: 'initialize',
value: function initialize(_ref2) {
var name = _ref2.name,
models = _ref2.models;
var tempEntities = [];
// const filteredModels = models.some(model => model.schema.name === 'User' || model.schema.name === 'Order' );
(0, _lodash.mapKeys)(models, function (model) {
var schema = model.schema;
tempEntities.push(ORM.schemaToEntity(schema));
});
(0, _lodash.map)(tempEntities, function (entity) {
//Models
var relations = entity.relations || {};
if (relations) {
(0, _lodash.mapKeys)(relations, function (relation, relationKey) {
// Model -> Relations
// find target entity
var targetEntity = tempEntities.find(function (entity) {
return relation.target === entity.name;
});
var tgRelations = targetEntity.relations || {};
var foundTargetRelation = (0, _lodash.values)(tgRelations).find(function (tgRelation) {
return tgRelation.target === entity.name && tgRelation.joinColumn.name === relation.joinColumn.name;
});
if (foundTargetRelation) {
if (foundTargetRelation.type === 'one-to-many') {
foundTargetRelation.inverseSide = relationKey;
}
} else {
if (relation.type === 'one-to-one') {
// creating relation on parent table for children
var newRelationKey = [entity.name.toLowerCase(), relation.joinColumn.name].join('_');
targetEntity.relations[newRelationKey] = {
type: "one-to-many",
target: entity.name,
joinColumn: relation.joinColumn,
inverseSide: relationKey
};
} else if (relation.type === 'one-to-many') {
// creating relation on parent table for children
var _newRelationKey = [entity.name.toLowerCase(), relation.joinColumn.name].join('_');
targetEntity.relations[_newRelationKey] = {
type: "one-to-one",
target: entity.name,
joinColumn: relation.joinColumn
};
}
}
});
}
});
this.entities = tempEntities.map(function (tempEntity) {
return new _typeorm.EntitySchema(tempEntity);
});
// create connection with typeorm
this.connect(name);
}
}, {
key: 'connect',
value: function connect(name) {
var connectionName = name || process.env['NODE_ENV'] || 'development';
var dbConfig = this.config[connectionName];
// sanitize options
var ormAdapter = dbConfig.adapter || DEFAULT_ADAPTER;
if (ormAdapter === 'postgresql') {
ormAdapter = 'postgres';
}
var connConfig = {
type: ormAdapter,
host: dbConfig.host,
port: dbConfig.port,
username: dbConfig.user,
password: dbConfig.password,
database: dbConfig.database,
subscribers: dbConfig.subscribers || [],
synchronize: false,
entities: this.entities,
logging: dbConfig.logging && true
};
return (0, _typeorm.createConnection)(connConfig);
}
}, {
key: 'getConnection',
value: function getConnection() {
return (0, _typeorm.getConnection)();
}
}], [{
key: 'schemaToEntity',
value: function schemaToEntity(schema) {
var name = schema.name,
datasource = schema.datasource,
fields = schema.fields;
var ormEntitySchema = {
name: name,
tableName: datasource.collection || name,
synchronize: datasource.synchronize || false, // forced
columns: {},
relations: _extends({}, this.generateRelations(schema.relations))
};
(0, _lodash.mapKeys)(fields, function (field, fieldKey) {
// Use columnType if specified, overriding auto mapping
var columnType = field.columnType || ORM.entityColumnType(field.type);
// skip virtualf fields
if (field.virtual) {
return;
}
var entityColumn = {
type: columnType
};
if (fieldKey === '_id') {
entityColumn.primary = true;
entityColumn.generated = 'uuid';
}
var ignoreFields = ['_parent'];
if (!ignoreFields.includes(fieldKey)) {
ormEntitySchema.columns[fieldKey] = entityColumn;
}
});
return ormEntitySchema;
}
}, {
key: 'generateRelations',
value: function generateRelations(relations) {
var newRelations = {};
if (relations && relations.children) {
var children = relations.children;
children.map(function (row) {
var _Types$model = _types2.default.model(row.model),
schema = _Types$model.schema;
newRelations[row.name] = {
type: 'one-to-many',
target: schema.name,
joinColumn: {
name: row.field,
referencedColumnName: row.joinBy
}
};
});
}
if (relations && relations.parent) {
var parent = relations.parent;
parent.map(function (row) {
var _Types$model2 = _types2.default.model(row.model),
schema = _Types$model2.schema;
newRelations[row.name] = {
type: 'one-to-one',
target: schema.name,
joinColumn: {
name: row.joinBy,
referencedColumnName: row.field
}
};
});
}
return newRelations;
}
// converts mirkwood/graphql types to orm types
}, {
key: 'entityColumnType',
value: function entityColumnType(fieldType) {
var fieldTypeString = fieldType.toString();
// check for primitive types
switch (fieldTypeString) {
case 'String':
return 'varchar';
break;
case 'Int':
return 'int';
break;
case 'Float':
return 'float';
case 'ID':
return 'varchar';
case 'Boolean':
return 'boolean';
}
// check for enum\
var isEnum = _types2.default.isOfType(fieldType, 'GraphQLEnumType');
if (isEnum) {
return 'varchar'; // not using enums as of now
}
// check for objects
if (_types2.default.isOfType(fieldType, 'GraphQLObjectType')) {
return 'simple-json';
}
// check for array
var isArray = _types2.default.isOfType(fieldType, 'GraphQLList');
if (isArray) {
var fieldBaseType = fieldType.ofType;
if (_types2.default.isOfType(fieldBaseType, 'GraphQLObjectType')) {
return 'simple-json';
}
return 'simple-array';
}
// default return type
return 'varchar';
}
}]);
return ORM;
}();
exports.default = ORM;