miter
Version:
A typescript web framework based on ExpressJs based loosely on SailsJs
201 lines • 10.2 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
require("reflect-metadata");
const injectable_decorator_1 = require("../decorators/services/injectable.decorator");
const name_decorator_1 = require("../decorators/services/name.decorator");
const orm_1 = require("../metadata/server/orm");
const model_1 = require("../metadata/orm/model");
const prop_1 = require("../metadata/orm/prop");
const has_many_1 = require("../metadata/orm/associations/has-many");
const belongs_to_1 = require("../metadata/orm/associations/belongs-to");
const has_one_1 = require("../metadata/orm/associations/has-one");
const logger_core_1 = require("../services/logger-core");
const logger_1 = require("../services/logger");
const sequelize_1 = require("./sequelize");
const orm_transform_service_1 = require("../services/orm-transform.service");
const transaction_service_1 = require("../services/transaction.service");
const db_impl_1 = require("./impl/db-impl");
let OrmReflector = class OrmReflector {
constructor(logger, loggerCore, ormMeta, transactionService, ormTransform, sql) {
this.logger = logger;
this.loggerCore = loggerCore;
this.ormMeta = ormMeta;
this.transactionService = transactionService;
this.ormTransform = ormTransform;
this.sql = sql;
this.models = new Map();
this.modelsByTableName = new Map();
this.dbImplLogger = this.loggerCore.getSubsystem('db-impl');
}
init() {
return __awaiter(this, void 0, void 0, function* () {
this.logger.verbose(`Initializing ORM...`);
yield this.sql.init();
let models = this.ormMeta.models;
this.reflectModels(models);
this.reflectAssociations(models);
this.createDbImpls(models);
yield this.sql.sync();
this.logger.info(`Finished initializing ORM.`);
});
}
reflectModels(models) {
for (let q = 0; q < models.length; q++) {
this.reflectModel(models[q]);
}
}
reflectModel(modelFn) {
if (this.models.has(modelFn))
throw new Error(`A model was passed to the orm-reflector twice: ${modelFn.name || modelFn}.`);
let modelProto = modelFn.prototype;
let meta = Reflect.getOwnMetadata(model_1.ModelMetadataSym, modelProto);
if (!meta)
throw new Error(`Expecting class with @Model decorator, could not reflect model properties for ${modelProto}.`);
let modelOptions = meta;
modelOptions = this.ormTransform.transformModel(modelOptions) || modelOptions;
modelOptions.tableName = modelOptions.tableName || this.ormTransform.transformModelName(modelFn.name) || modelFn.name;
let dupTable = this.modelsByTableName.get(modelOptions.tableName);
if (dupTable)
throw new Error(`Defining multiple models with the same table name! ${dupTable.name || dupTable} and ${modelFn.name || modelFn}`);
this.modelsByTableName.set(modelOptions.tableName, modelFn);
let columns = {};
let props = Reflect.getOwnMetadata(model_1.ModelPropertiesSym, modelProto) || [];
for (let q = 0; q < props.length; q++) {
let propName = props[q];
let propMeta = Reflect.getOwnMetadata(prop_1.PropMetadataSym, modelProto, propName);
if (!propMeta)
throw new Error(`Could not find model property metadata for property ${modelFn.name || modelFn}.${propName}.`);
let columnMeta = propMeta;
columnMeta = this.ormTransform.transformColumn(columnMeta) || columnMeta;
columnMeta.field = columnMeta.columnName || this.ormTransform.transformColumnName(propName) || propName;
columns[propName] = columnMeta;
}
let model = this.sql.define(modelOptions.tableName, columns, modelOptions);
this.models.set(modelFn, model);
}
reflectAssociations(models) {
for (let q = 0; q < models.length; q++) {
this.reflectModelAssociations(models[q]);
}
}
reflectModelAssociations(modelFn) {
let model = this.models.get(modelFn);
if (!model)
throw new Error(`Could not reflect model associations for a model that failed to be reflected: ${modelFn.name || modelFn}.`);
let modelProto = modelFn.prototype;
let meta = Reflect.getOwnMetadata(model_1.ModelMetadataSym, modelProto);
if (!meta)
throw new Error(`Expecting class with @Model decorator, could not reflect model properties for ${modelProto}.`);
let associationTypes = [
{
sqlName: 'hasMany',
msgName: 'has-many',
associationsSym: has_many_1.ModelHasManyAssociationsSym,
metadataSym: has_many_1.HasManyMetadataSym,
transform: (propMeta, propName) => {
}
},
{
sqlName: 'belongsTo',
msgName: 'belongs-to',
associationsSym: belongs_to_1.ModelBelongsToAssociationsSym,
metadataSym: belongs_to_1.BelongsToMetadataSym,
transform: (propMeta, propName) => {
propMeta.foreignKey = propMeta.foreignKey || this.ormTransform.transformAssociationColumnName(propName) || propName;
}
},
{
sqlName: 'hasOne',
msgName: 'has-one',
associationsSym: has_one_1.ModelHasOneAssociationsSym,
metadataSym: has_one_1.HasOneMetadataSym,
transform: (propMeta, propName) => {
}
}
];
for (let q = 0; q < associationTypes.length; q++) {
let def = associationTypes[q];
let associationNames = Reflect.getOwnMetadata(def.associationsSym, modelProto) || [];
for (let w = 0; w < associationNames.length; w++) {
let propName = associationNames[w];
let propMeta = Reflect.getOwnMetadata(def.metadataSym, modelProto, propName);
if (!propMeta)
throw new Error(`Could not find model ${def.msgName} metadata for property ${modelFn.name || modelFn}.${propName}`);
let foreignModelFn = this.resolveForeignModelFn(propMeta);
if (!foreignModelFn)
throw new Error(`Could not resolve foreign model for ${def.msgName} association ${modelFn.name || modelFn}.${propName}`);
let foreignModel = this.models.get(foreignModelFn);
if (!foreignModel)
throw new Error(`Could not create ${def.msgName} association ${modelFn.name || modelFn}.${propName} to model that has not been reflected: ${foreignModelFn.name || foreignModelFn}`);
let sqlMeta = propMeta;
sqlMeta = this.ormTransform.transformAssociation(sqlMeta) || sqlMeta;
if (def.transform)
def.transform(sqlMeta, propName);
model[def.sqlName](foreignModel, propMeta);
}
}
}
createDbImpls(models) {
for (let q = 0; q < models.length; q++) {
let modelFn = models[q];
let model = this.models.get(modelFn);
if (!model)
throw new Error(`Could not reflect model associations for a model that failed to be reflected: ${modelFn.name || modelFn}.`);
let db = new db_impl_1.DbImpl(modelFn, model, this.sql, this.dbImplLogger, this.transactionService);
modelFn.db = db;
}
}
isStaticModelT(test) {
return test && !!test.db;
}
isTableNameRef(test) {
return test.tableName;
}
isModelNameRef(test) {
return test.modelName;
}
resolveForeignModelFn(meta) {
let fmod = meta.foreignModel;
if (!fmod)
return undefined;
if (this.isStaticModelT(fmod))
return fmod;
if (typeof fmod === 'function')
return meta.foreignModel = fmod();
else if (this.isTableNameRef(fmod))
return meta.foreignModel = this.modelsByTableName.get(fmod.tableName);
else if (this.isModelNameRef(fmod)) {
let modelName = fmod.modelName;
return meta.foreignModel = [...this.models.keys()].find(model => model.name == modelName);
}
}
};
OrmReflector = __decorate([
injectable_decorator_1.Injectable(),
name_decorator_1.Name('orm'),
__metadata("design:paramtypes", [logger_1.Logger,
logger_core_1.LoggerCore,
orm_1.OrmMetadata,
transaction_service_1.TransactionService,
orm_transform_service_1.OrmTransformService,
sequelize_1.Sequelize])
], OrmReflector);
exports.OrmReflector = OrmReflector;
//# sourceMappingURL=reflector.js.map