UNPKG

node-web-mvc

Version:
193 lines (192 loc) 8.33 kB
"use strict"; /** * @module TypeConverter * @description 类型转换 */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TypedArray = void 0; const SerializationCreateInstanceError_1 = __importDefault(require("../errors/SerializationCreateInstanceError")); const ValueConvertError_1 = __importDefault(require("../errors/ValueConvertError")); const Javascript_1 = __importDefault(require("../interface/Javascript")); const RuntimeAnnotation_1 = __importDefault(require("../servlets/annotations/annotation/RuntimeAnnotation")); const BasicTypeConverter_1 = require("./BasicTypeConverter"); const DateConverter_1 = __importDefault(require("./date/DateConverter")); const JsonDeserialize_1 = __importDefault(require("./JsonDeserialize")); const JsonFormat_1 = __importDefault(require("./JsonFormat")); const ConvertPropertyTypeError_1 = __importDefault(require("../errors/ConvertPropertyTypeError")); exports.TypedArray = Uint8Array.prototype.__proto__.constructor; class TypeConverter { createInstance(type, ...args) { try { if (!type) { return null; } return new type(...args); } catch (ex) { throw new SerializationCreateInstanceError_1.default(type, ex.message); } } isInstanceof(v, type) { return (typeof v === 'object' && !!v && v instanceof type); } convert(value, type, runtimeType) { if (value === null || value === undefined) { return null; } else if (!type) { return value; // throw new Error(`dataType not present`); } const clazzType = Javascript_1.default.createTyper(type); if (runtimeType === null || runtimeType === void 0 ? void 0 : runtimeType.enum) { return this.toEnum(value, type); } else if (clazzType.isType(BigInt)) { return (0, BasicTypeConverter_1.toBigInt)(value); } else if (clazzType.isType(String)) { return (0, BasicTypeConverter_1.toString)(value, type); } else if (clazzType.isType(Number)) { return (0, BasicTypeConverter_1.toNumber)(value, type); } else if (clazzType.isType(Boolean)) { return (0, BasicTypeConverter_1.toBoolean)(value); } else if (clazzType.isType(Date)) { return (0, BasicTypeConverter_1.toDate)(value, type); } else if (clazzType.isType(Array)) { return this.toArray(value, type, runtimeType); } else if (clazzType.isType(Set) || clazzType.isType(WeakSet)) { return this.toSet(value, type, runtimeType); } else if (clazzType.isType(Map) || clazzType.isType(WeakMap)) { return this.toMap(value, type, runtimeType); } else if (this.isInstanceof(value, type)) { return value; } else if (clazzType.isType(exports.TypedArray)) { return this.toTypedArray(value, type); } else if (runtimeType === null || runtimeType === void 0 ? void 0 : runtimeType.array) { return this.toArray(value, Array, { args: [runtimeType], clazz: Array, name: 'Array', array: true, fullName: 'Array' }); } else { return this.toClass(value, type, runtimeType); } } toEnum(value, type) { if (value in type) { return value; } throw new Error(`${value} is not enum value`); } toSet(value, type, runtimeType) { var _a, _b; const set = new type(); const items = value instanceof Array ? value : [value]; const itemType = (_b = (_a = runtimeType === null || runtimeType === void 0 ? void 0 : runtimeType.args) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.clazz; items.forEach((value) => { set.add(itemType ? this.convert(value, itemType) : value); }); return set; } toMap(data, type, runtimeType) { var _a, _b; if (typeof data !== 'object' || !data || data instanceof Array) { throw new ValueConvertError_1.default(data, Map); } const itemType = (_b = (_a = runtimeType === null || runtimeType === void 0 ? void 0 : runtimeType.args) === null || _a === void 0 ? void 0 : _a[1]) === null || _b === void 0 ? void 0 : _b.clazz; const map = new type(); Object.keys(data).forEach((key) => { const value = itemType ? this.convert(data[key], itemType) : data[key]; map.set(key, value); }); return map; } toArray(value, type, runtimeType) { var _a, _b; const values = value instanceof Array ? value : [value]; const itemType = (_b = (_a = runtimeType === null || runtimeType === void 0 ? void 0 : runtimeType.args) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.clazz; const instance = this.createInstance(type); if (value == null) { return instance; } else if (itemType) { values.forEach((item, i) => { instance[i] = this.convert(item, itemType); }); } else { values.forEach((item, i) => { instance[i] = item; }); } return instance; } toTypedArray(data, type) { return new type(data); } getDescriptor(instance, key) { if (!instance) return null; return Object.getOwnPropertyDescriptor(instance, key) || Object.getOwnPropertyDescriptor(instance.__proto__, key); } toClass(data, dataType, runtimeType) { // TODO: runtimeType补充 if (dataType === Object && (typeof data !== 'object' || !data)) { return data; } const instance = this.createInstance(dataType); const keys = Object.keys(data); for (const key of keys) { const value = data[key]; const descriptor = this.getDescriptor(instance, key) || {}; if (descriptor.writable === false || ('set' in descriptor && descriptor.set == undefined)) { // 如果是只读属性 continue; } try { instance[key] = this.handlePropertyValue(dataType, key, value); } catch (ex) { throw new ConvertPropertyTypeError_1.default(key, ex); } } return instance; } handlePropertyValue(clazz, name, value) { var _a, _b, _c; const basicProperty = RuntimeAnnotation_1.default.getPropertyAnnotations(clazz, name)[0]; if (!basicProperty) { return value; } const deserializer = (_c = (_b = (_a = RuntimeAnnotation_1.default.getPropertyAnnotation(clazz, name, JsonDeserialize_1.default)) === null || _a === void 0 ? void 0 : _a.nativeAnnotation) === null || _b === void 0 ? void 0 : _b.getDeserializer) === null || _c === void 0 ? void 0 : _c.call(_b); if (deserializer) { // 自定义反序列化 return deserializer.deserialize(value, clazz, name); } const clazzType = basicProperty.dataType.clazz; if (Javascript_1.default.createTyper(clazzType).isType(Date)) { return this.handleDateProperty(clazz, clazzType, name, value); } const metaProperty = RuntimeAnnotation_1.default.getPropertyAnnotation(clazz, name, Object); return this.convert(value, clazzType, metaProperty === null || metaProperty === void 0 ? void 0 : metaProperty.dataType); } handleDateProperty(clazz, dataType, name, value) { const jsonFormat = RuntimeAnnotation_1.default.getPropertyAnnotation(clazz, name, JsonFormat_1.default); if (!jsonFormat) { return (0, BasicTypeConverter_1.toDate)(value, dataType); } const converter = DateConverter_1.default.of(jsonFormat.nativeAnnotation.pattern, jsonFormat.nativeAnnotation.locale); return converter.parse(value); } } exports.default = TypeConverter;