airship-server
Version:
Airship is a framework for Node.JS & TypeScript that helps you to write big, scalable and maintainable API servers.
113 lines • 6.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
require("reflect-metadata");
const VectorType_1 = require("../codeGen/domain/types/VectorType");
const CustomType_1 = require("../codeGen/domain/types/CustomType");
const AnyType_1 = require("../codeGen/domain/types/AnyType");
const ObjectType_1 = require("../codeGen/domain/types/ObjectType");
const BooleanType_1 = require("../codeGen/domain/types/BooleanType");
const NumberType_1 = require("../codeGen/domain/types/NumberType");
const StringType_1 = require("../codeGen/domain/types/StringType");
const ClassScheme_1 = require("../codeGen/domain/schema/ClassScheme");
const ClassField_1 = require("../codeGen/domain/schema/ClassField");
exports.SerializableKey = 'SerializableKey';
exports.SerializableKeys = 'SerializableKeys';
exports.SerializableTypes = 'SerializableTypes';
exports.SerializableArrayTypes = 'SerializableArrayTypes';
function serializable(name, arrayType, isAny = false) {
return (target, propertyKey) => {
const constructor = target;
name = name || propertyKey.replace('_', '');
Reflect.defineMetadata(exports.SerializableKey, name, target, propertyKey);
constructor[exports.SerializableKeys] = constructor[exports.SerializableKeys] || [];
constructor[exports.SerializableTypes] = constructor[exports.SerializableTypes] || [];
constructor[exports.SerializableArrayTypes] = constructor[exports.SerializableArrayTypes] || [];
let type = Reflect.getMetadata('design:type', target, propertyKey);
// we need new arrays here, because at this point they are references to super class arrays
// so just pushing new values would modify super (and other child) class array
constructor[exports.SerializableKeys] = [...constructor[exports.SerializableKeys], name];
constructor[exports.SerializableTypes] = [...constructor[exports.SerializableTypes], (isAny ? 'any' : type)];
constructor[exports.SerializableArrayTypes] = [...constructor[exports.SerializableArrayTypes], arrayType];
};
}
exports.serializable = serializable;
class BaseSerializer {
static serialize(entity) {
throw new Error('Not implemented');
}
static deserialize(serializableType, raw, valuePath = []) {
throw new Error('Not implemented');
}
static getClassScheme(serializableType) {
const serializableConstructor = serializableType.prototype;
let propsNames = serializableConstructor[exports.SerializableKeys];
const types = serializableConstructor[exports.SerializableTypes];
const arrayTypes = serializableConstructor[exports.SerializableArrayTypes];
let fields = [];
propsNames = propsNames || [];
propsNames.forEach((propName, index) => {
fields.push(new ClassField_1.default(propName, this.getType(types[index], arrayTypes[index]), ''));
});
return new ClassScheme_1.default(serializableConstructor.constructor.name, fields);
}
static getClassDependencies(serializableType) {
const serializableConstructor = serializableType.prototype;
const propsNames = serializableConstructor[exports.SerializableKeys] || [];
const types = serializableConstructor[exports.SerializableTypes];
const arrayTypes = serializableConstructor[exports.SerializableArrayTypes];
let dependencies = {};
let subDeps = [];
propsNames.forEach((propName, index) => {
if (this.isSerializableObject(types[index]) == true) {
dependencies[types[index].prototype.constructor.name] = types[index];
subDeps = [...subDeps, ...this.getClassDependencies(types[index])];
}
else if (arrayTypes[index] && this.isSerializableObject(arrayTypes[index]) == true) {
dependencies[arrayTypes[index].prototype.constructor.name] = arrayTypes[index];
subDeps = [...subDeps, ...this.getClassDependencies(arrayTypes[index])];
}
});
return [...Object.keys(dependencies).map(key => dependencies[key]), ...subDeps];
}
static isSerializableObject(object) {
if (object == 'any')
return false;
return !!object.prototype[exports.SerializableKeys];
}
static getType(propType, arrayType) {
if (propType == String)
return new StringType_1.default();
if (propType == Number)
return new NumberType_1.default();
if (propType == Boolean)
return new BooleanType_1.default();
if (propType == Object)
return new ObjectType_1.default();
if (propType == 'any')
return new AnyType_1.default();
if (this.isSerializableObject(propType) == true)
return new CustomType_1.default(propType.prototype.constructor.name);
if (propType == Array && arrayType)
return new VectorType_1.default(this.getType(arrayType));
throw new Error(`Model scheme generation fail, unknown type: ${propType}`);
}
static checkType(prop, value, expectedType, isSerializable) {
if (value == undefined)
throw new Error(`${prop} argument missing`);
let valueType = typeof value;
if (expectedType == Array && !Array.isArray(value))
throw new Error(`${prop} must be array`);
if (!isSerializable) {
if (expectedType == String && valueType !== 'string')
throw new Error(`${prop} must be string instead of ${valueType}`);
if (expectedType == Number && valueType !== 'number')
throw new Error(`${prop} must be number instead of ${valueType}`);
if (expectedType == Boolean && valueType !== 'boolean')
throw new Error(`${prop} must be boolean instead of ${valueType}`);
if (expectedType == Object && valueType !== 'object')
throw new Error(`${prop} must be boolean instead of ${valueType}`);
}
}
}
exports.BaseSerializer = BaseSerializer;
//# sourceMappingURL=BaseSerializer.js.map