From e1ba4e63ca0e065d215ff9d6ca53b853ed5b76cf Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Wed, 24 Nov 2021 13:01:35 +0000 Subject: [PATCH] fix: use the public API for reading entity metadata Rather than misusing a private decorator-specific API, this change uses the ORM's metadata storage instead. A slight issue here is that accessing the entity manager from a repository is technically not a public API, but the code doing so isn't (yet) TypeScript and needs a lot of work anyway. Refs #398, #399 --- src/backend/controllers/community.js | 2 + src/backend/controllers/fullReview.js | 1 + src/backend/controllers/persona.js | 2 + src/backend/controllers/preprint.js | 2 + src/backend/controllers/rapidReview.js | 1 + src/backend/utils/getFields.ts | 55 ++++++++++++++------------ 6 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/backend/controllers/community.js b/src/backend/controllers/community.js index 5486a88e..2824b106 100644 --- a/src/backend/controllers/community.js +++ b/src/backend/controllers/community.js @@ -181,6 +181,7 @@ export default function controller( const options = { fields: getFields( 'Community', + communityModel.em.getMetadata(), ctx.query.include_images ? ctx.query.include_images.split(',') : undefined, @@ -280,6 +281,7 @@ export default function controller( const options = { fields: getFields( 'Community', + communityModel.em.getMetadata(), ctx.query.include_images ? ctx.query.include_images.split(',') : undefined, diff --git a/src/backend/controllers/fullReview.js b/src/backend/controllers/fullReview.js index 9d9759e4..782b33cc 100644 --- a/src/backend/controllers/fullReview.js +++ b/src/backend/controllers/fullReview.js @@ -73,6 +73,7 @@ export default function controller( const options = { fields: getFields( 'FullReview', + reviewModel.em.getMetadata(), ctx.query.include_images ? ctx.query.include_images.split(',') : undefined, diff --git a/src/backend/controllers/persona.js b/src/backend/controllers/persona.js index c428e5e3..87ccb332 100644 --- a/src/backend/controllers/persona.js +++ b/src/backend/controllers/persona.js @@ -101,6 +101,7 @@ export default function controller( const options = { fields: getFields( 'Persona', + personasModel.em.getMetadata(), ctx.query.include_images ? ctx.query.include_images.split(',') : undefined, @@ -235,6 +236,7 @@ export default function controller( const options = { fields: getFields( 'Persona', + personasModel.em.getMetadata(), ctx.query.include_images ? ctx.query.include_images.split(',') : undefined, diff --git a/src/backend/controllers/preprint.js b/src/backend/controllers/preprint.js index 4517936a..0efbe812 100644 --- a/src/backend/controllers/preprint.js +++ b/src/backend/controllers/preprint.js @@ -207,6 +207,7 @@ export default function controller(preprints, thisUser) { const options = { fields: getFields( 'Preprint', + preprints.em.getMetadata(), ctx.query.include_images ? ctx.query.include_images.split(',') : undefined, @@ -358,6 +359,7 @@ export default function controller(preprints, thisUser) { const options = { fields: getFields( 'Preprint', + preprints.em.getMetadata(), ctx.query.include_images ? ctx.query.include_images.split(',') : undefined, diff --git a/src/backend/controllers/rapidReview.js b/src/backend/controllers/rapidReview.js index ca870c4f..d2736819 100644 --- a/src/backend/controllers/rapidReview.js +++ b/src/backend/controllers/rapidReview.js @@ -53,6 +53,7 @@ export default function controller(rapidReviews, preprints, thisUser) { const options = { fields: getFields( 'RapidReview', + rapidReviews.em.getMetadata(), ctx.query.include_images ? ctx.query.include_images.split(',') : undefined, diff --git a/src/backend/utils/getFields.ts b/src/backend/utils/getFields.ts index 71bfe85b..d46f85d3 100644 --- a/src/backend/utils/getFields.ts +++ b/src/backend/utils/getFields.ts @@ -1,40 +1,43 @@ import 'reflect-metadata'; -import { EntityProperty, FindOptions } from '@mikro-orm/core'; +import { FindOptions, MetadataStorage } from '@mikro-orm/core'; import * as entities from '../models/entities'; type Fields = NonNullable['fields']>; export function getFields( type: T, + meta: MetadataStorage, includes?: string[], recurse = 2, ): Fields { - return Object.values(entities[type].prototype.__meta.properties).reduce< - Fields - >((props, prop: EntityProperty) => { - if (!(prop.hidden === true)) { - if (prop.reference === 'scalar') { - if ( - prop.type !== 'BlobType' || - (includes && includes.includes(prop.name)) - ) { - props.push(prop.name); + return Object.values(meta.get(type).props).reduce>( + (props, prop) => { + if (!(prop.hidden === true)) { + if (prop.reference === 'scalar') { + if ( + prop.type !== 'BlobType' || + (includes && includes.includes(prop.name)) + ) { + props.push(prop.name); + } + return props; } - return props; - } - if (recurse > 0) { - if (prop.reference === 'm:1') { - props.push(prop.name); + if (recurse > 0) { + if (prop.reference === 'm:1') { + props.push(prop.name); + } + props.push({ + [prop.name]: getFields( + prop.type as keyof typeof entities, + meta, + includes, + recurse - 1, + ), + }); } - props.push({ - [prop.name]: getFields( - prop.type as keyof typeof entities, - includes, - recurse - 1, - ), - }); } - } - return props; - }, []); + return props; + }, + [], + ); }