UNPKG

@ilhamtahir/ts-mapper

Version:

[![npm version](https://img.shields.io/npm/v/@ilhamtahir/ts-mapper.svg)](https://www.npmjs.com/package/@ilhamtahir/ts-mapper) [![npm downloads](https://img.shields.io/npm/dm/@ilhamtahir/ts-mapper.svg)](https://www.npmjs.com/package/@ilhamtahir/ts-mapper)

92 lines 3.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createMapperProxy = createMapperProxy; exports.isAbstractClass = isAbstractClass; require("reflect-metadata"); const transformer_1 = require("./transformer"); /** * Create Mapper proxy object, supporting auto transform and custom method preservation * * @param MapperClass Mapper class constructor (supports abstract class) * @returns Proxied Mapper instance */ function createMapperProxy(MapperClass) { // Create instance (even abstract class can be instantiated) const instance = new MapperClass(); return new Proxy(instance, { get(target, propKey, receiver) { const original = Reflect.get(target, propKey, receiver); // Only handle function type properties if (typeof original === 'function') { return function (...args) { // Check if it's an empty method body or abstract method const shouldAutoTransform = isEmptyOrAbstractMethod(original, target, propKey); if (shouldAutoTransform) { // Automatically execute transform return executeAutoTransform(target, String(propKey), args[0]); } else { // Preserve original method logic return original.apply(this, args); } }; } return original; }, }); } /** * Determine if method is empty implementation or abstract method */ function isEmptyOrAbstractMethod(method, _target, _propKey) { try { // Get method source code const methodSource = method.toString(); // Simplified detection logic: check if it only contains return {} or return {} as Type const isEmptyBody = // Only contains return {}; /{\s*(?:\/\/[^\n]*\n\s*)*(?:\/\*[\s\S]*?\*\/\s*)*return\s*\{\s*\}\s*;\s*}/.test(methodSource) || // Only contains return {} as Type; /{\s*(?:\/\/[^\n]*\n\s*)*(?:\/\*[\s\S]*?\*\/\s*)*return\s*\{\s*\}\s*as\s+\w+\s*;\s*}/.test(methodSource) || // Completely empty method body /{\s*(?:\/\/[^\n]*\n\s*)*(?:\/\*[\s\S]*?\*\/\s*)*\s*}/.test(methodSource); return isEmptyBody; } catch (error) { // If unable to get method source code, default to not auto transform return false; } } /** * Execute auto transform */ function executeAutoTransform(target, methodName, input) { try { // Get method return type const returnType = Reflect.getMetadata('design:returntype', target, methodName); if (!returnType) { throw new Error(`Unable to get return type for method ${methodName}. Please ensure TypeScript's experimentalDecorators and emitDecoratorMetadata options are enabled.`); } // Call transform function return (0, transformer_1.transform)(target, methodName, input, returnType); } catch (error) { throw new Error(`Auto transform failed (method: ${methodName}): ${error instanceof Error ? error.message : String(error)}`); } } /** * Check if class is abstract class * Note: This function is mainly used for debugging and logging, actual Proxy logic doesn't depend on this */ function isAbstractClass(constructor) { // Cannot directly detect abstract keyword at JavaScript runtime // But we can infer through other means, such as checking for unimplemented methods try { new constructor(); return false; // If instantiation succeeds, it's not abstract or is an instantiable abstract } catch (error) { return true; // If instantiation fails, it might be an abstract class } } //# sourceMappingURL=mapper-factory.js.map