claire-framework
Version:
- được viết bằng TypeScript - hỗ trợ websocket và HTTP request - hỗ trợ CLI để generate base project (claire-cli)
218 lines • 15.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const ModelMetadata_1 = require("./ModelMetadata");
const DataType_1 = require("../enum/DataType");
const FieldValidationMetadata_1 = require("../validator/FieldValidationMetadata");
const core_1 = require("../decorator/core");
/**
* Init the model prototype of the class if not exist.
* @param prototype class object prototype.
*/
const init_class_sql_prototype = (prototype) => {
if (!prototype[core_1.METADATA]) {
prototype[core_1.METADATA] = new ModelMetadata_1.ModelMetadata();
}
return prototype[core_1.METADATA];
};
const getReflectDataType = (prototype, propertyKey) => {
let t = Reflect.getMetadata("design:type", prototype, propertyKey);
if (t) {
switch (t.name) {
case "Boolean":
return DataType_1.DataType.BOOL;
case "Number":
return DataType_1.DataType.INTEGER;
case "String":
return DataType_1.DataType.STRING;
case "Array":
return DataType_1.DataType.ARRAY;
default:
return DataType_1.DataType.TEXT;
}
}
return undefined;
};
/**
* Init the logic field of the class if not exist or append properties to the existed field.
* @param prototype class object prototype.
* @param propertyKey logic name of the field.
* @param addedProperties the overriding properties.
*/
exports.check_for_field = (prototype, propertyKey, addedProperties) => {
let meta = init_class_sql_prototype(prototype);
let field = meta.getFieldByLogicName(propertyKey);
if (!field) {
field = new FieldValidationMetadata_1.FieldValidationMetadata();
field.fieldLogicName = propertyKey;
let dataType = getReflectDataType(prototype, propertyKey);
if (dataType) {
field.dataType = dataType;
}
meta.addField(field);
}
else {
Object.assign(field, addedProperties);
}
Object.assign(field, addedProperties);
return field;
};
/**
* Mark a field of the model having a corresponding logic 'getter/setter' name.
* @param fieldLogicName the logic name of the field
*/
exports.GetSet = (fieldLogicName) => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { getSetField: fieldLogicName });
};
};
/**
* Mark a field of the model as the data field, which will be used to store the data.
* @param fieldDataName name of the field in the database table.
* @param innerDataType explicit data type to support the database engine.
*/
exports.DataField = (fieldDataName, innerDataType) => {
return (prototype, propertyKey) => {
let addedProperties = {};
if (fieldDataName) {
addedProperties.fieldDataName = fieldDataName;
}
if (innerDataType) {
addedProperties.innerDataType = innerDataType;
}
let field = exports.check_for_field(prototype, propertyKey, addedProperties);
//-- data field should be not nullable, but can be overwritten by other decorators
if (field.nullable === undefined) {
field.nullable = false;
}
};
};
/**
* Mark a field of the model as primary key. If autoInc is true, the field is auto incremental.
* @param autoInc whether the key is auto-incremented.
*/
exports.PrimaryKey = (autoInc) => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { isPrimaryKey: true, isAutoIncrement: autoInc, nullable: false });
};
};
/**
* Mark a field of the model as foreign key. The referred model must be supplied.
* @param model the model to refer of which this field is primary key.
*/
exports.ForeignKey = (model) => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { isForeignKey: true, referModel: model && model.name });
};
};
/**
* Mark the field with unique constraint.
*/
exports.Unique = () => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { isUnique: true });
};
};
/**
* Mark the field with can-be-null constraint.
*/
exports.Optional = () => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { nullable: true });
};
};
/**
* Mark the field with can-not-be-null constraint.
*/
exports.Required = () => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { nullable: false });
};
};
/**
* Default value of the field.
* @param value the default value.
*/
exports.DefaultValue = (value) => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { defaultValue: value });
};
};
/**
* Mark the field as auto-generated. This field can be populate from the business logic but from the user.
*/
exports.AutoGen = () => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { isAutoGen: true });
};
};
exports.IsFile = () => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { isFile: true });
};
};
/**
* Add description meta info for this field.
* @param comment the field description info.
*/
exports.Comment = (comment) => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { description: comment });
};
};
/**
* Mark the model that validation should be checked.
* @constructor
*/
exports.Validate = () => {
return (constructor) => {
let modelMetaData = init_class_sql_prototype(constructor.prototype);
modelMetaData.needValidate = true;
return constructor;
};
};
exports.Range = (from, to) => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { inRange: { from, to } });
};
};
exports.InSet = (set) => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { inSet: set });
};
};
exports.SubSet = (set, allowEmpty = true) => {
return (prototype, propertyKey) => {
exports.IsArray(allowEmpty)(prototype, propertyKey);
exports.check_for_field(prototype, propertyKey, { subSet: set });
};
};
exports.Match = (regex) => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { match: regex });
};
};
exports.IsInteger = () => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { isInteger: true });
};
};
exports.IsArray = (allowEmpty = true) => {
return (prototype, propertyKey) => {
let field = exports.check_for_field(prototype, propertyKey, { allowEmptyArray: allowEmpty });
if (field.dataType && !field.innerDataType) {
field.innerDataType = field.dataType;
}
field.dataType = DataType_1.DataType.ARRAY;
};
};
exports.GreaterThan = (value) => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { greaterThan: value });
};
};
exports.LessThan = (value) => {
return (prototype, propertyKey) => {
exports.check_for_field(prototype, propertyKey, { lessThan: value });
};
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGFibGVNYXBwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9saWIvbW9kZWwvVGFibGVNYXBwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFDQSxtREFBOEM7QUFDOUMsK0NBQTBDO0FBQzFDLGtGQUE2RTtBQUM3RSw0Q0FBMkM7QUFFM0M7OztHQUdHO0FBQ0gsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLFNBQWMsRUFBaUIsRUFBRTtJQUMvRCxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQVEsQ0FBQyxFQUFFO1FBQ3RCLFNBQVMsQ0FBQyxlQUFRLENBQUMsR0FBRyxJQUFJLDZCQUFhLEVBQUUsQ0FBQztLQUM3QztJQUNELE9BQU8sU0FBUyxDQUFDLGVBQVEsQ0FBQyxDQUFDO0FBQy9CLENBQUMsQ0FBQztBQUVGLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxTQUFjLEVBQUUsV0FBbUIsRUFBd0IsRUFBRTtJQUNyRixJQUFJLENBQUMsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxTQUFTLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDbkUsSUFBSSxDQUFDLEVBQUU7UUFDSCxRQUFRLENBQUMsQ0FBQyxJQUFJLEVBQUU7WUFDWixLQUFLLFNBQVM7Z0JBQ1YsT0FBTyxtQkFBUSxDQUFDLElBQUksQ0FBQztZQUN6QixLQUFLLFFBQVE7Z0JBQ1QsT0FBTyxtQkFBUSxDQUFDLE9BQU8sQ0FBQztZQUM1QixLQUFLLFFBQVE7Z0JBQ1QsT0FBTyxtQkFBUSxDQUFDLE1BQU0sQ0FBQztZQUMzQixLQUFLLE9BQU87Z0JBQ1IsT0FBTyxtQkFBUSxDQUFDLEtBQUssQ0FBQztZQUMxQjtnQkFDSSxPQUFPLG1CQUFRLENBQUMsSUFBSSxDQUFDO1NBQzVCO0tBQ0o7SUFDRCxPQUFPLFNBQVMsQ0FBQztBQUNyQixDQUFDLENBQUM7QUFFRjs7Ozs7R0FLRztBQUNVLFFBQUEsZUFBZSxHQUFHLENBQUMsU0FBYyxFQUFFLFdBQW1CLEVBQUUsZUFB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