@boostercloud/metadata-booster
Version:
Emits detailed metadata of your types. You can then get it in runtime to deal with schema-aware operation, like defining GraphQL schemas, ORM operations, etc.
54 lines (53 loc) • 3.76 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createClassMetadataDecorator = createClassMetadataDecorator;
exports.createFilterInterfaceFunction = createFilterInterfaceFunction;
function createClassMetadataDecorator(f, classInfo, filterInterfaceFunctionName, typesByModule) {
return f.createDecorator(f.createCallExpression(f.createPropertyAccessExpression(f.createIdentifier('Reflect'), 'metadata'), undefined, [
f.createStringLiteral('booster:typeinfo'),
f.createObjectLiteralExpression([
f.createPropertyAssignment('name', f.createStringLiteral(classInfo.name)),
f.createPropertyAssignment('type', f.createIdentifier(classInfo.name)),
f.createPropertyAssignment('fields', createPropertiesMetadata(f, classInfo.fields, filterInterfaceFunctionName, typesByModule)),
f.createPropertyAssignment('methods', createPropertiesMetadata(f, classInfo.methods, filterInterfaceFunctionName, typesByModule)),
], true),
]));
}
function createPropertiesMetadata(f, properties, filterInterfaceFunctionName, typesByModule) {
return f.createArrayLiteralExpression(properties.map((prop) => {
return f.createObjectLiteralExpression([
f.createPropertyAssignment('name', f.createStringLiteral(prop.name)),
f.createPropertyAssignment('typeInfo', createMetadataForTypeInfo(f, prop.typeInfo, filterInterfaceFunctionName, typesByModule)),
], true);
}, true));
}
function createMetadataForTypeInfo(f, typeInfo, filterInterfaceFunctionName, typesByModule) {
const typeModule = typeInfo.typeName && typesByModule[typeInfo.typeName];
const properties = [
f.createPropertyAssignment('name', f.createStringLiteral(typeInfo.name)),
f.createPropertyAssignment('typeGroup', f.createStringLiteral(typeInfo.typeGroup)),
f.createPropertyAssignment('isNullable', typeInfo.isNullable ? f.createTrue() : f.createFalse()),
f.createPropertyAssignment('isGetAccessor', typeInfo.isGetAccessor ? f.createTrue() : f.createFalse()),
f.createPropertyAssignment('parameters', f.createArrayLiteralExpression(typeInfo.parameters.map((param) => createMetadataForTypeInfo(f, param, filterInterfaceFunctionName, typesByModule)))),
];
if (typeModule)
properties.push(f.createPropertyAssignment('importPath', f.createStringLiteral(typeModule)));
if (typeInfo.typeName) {
properties.push(f.createPropertyAssignment('typeName', f.createStringLiteral(typeInfo.typeName)), f.createPropertyAssignment('type', typeModule
? /* eslint-disable indent */
f.createPropertyAccessExpression(f.createCallExpression(f.createIdentifier('require'), undefined, [
f.createStringLiteral(typeModule || ''),
]), f.createIdentifier(typeInfo.typeName))
: f.createCallExpression(filterInterfaceFunctionName, undefined, [f.createStringLiteral(typeInfo.typeName)])
/* eslint-enable indent */
));
}
return f.createObjectLiteralExpression(properties, true);
}
function createFilterInterfaceFunction(f, filterInterfaceFunctionName) {
return f.createFunctionDeclaration(undefined, undefined, filterInterfaceFunctionName, undefined, [f.createParameterDeclaration(undefined, undefined, 'typeName', undefined, undefined, undefined)], undefined, f.createBlock([
f.createTryStatement(f.createBlock([
f.createReturnStatement(f.createCallExpression(f.createIdentifier('eval'), undefined, [f.createIdentifier('typeName')])),
], false), f.createCatchClause(undefined, f.createBlock([f.createReturnStatement(f.createIdentifier('undefined'))], false)), undefined),
], false));
}