diff --git a/package-lock.json b/package-lock.json index 1ca32a85..3756c2ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -73,7 +73,6 @@ "react-router-dom": "^5.1.2", "react-slick": "^0.28.1", "react-twitter-embed": "^3.0.3", - "reflect-metadata": "^0.1.13", "replacestream": "^4.0.3", "request-received": "0.0.3", "restful-react": "^15.2.0", diff --git a/package.json b/package.json index 0c9de53b..0db0b198 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,8 @@ "backend": { "context": "node", "distDir": "dist/backend", - "optimize": false + "optimize": false, + "scopeHoist": false }, "frontend": { "context": "browser", @@ -53,12 +54,14 @@ "migrations-script": { "context": "node", "distDir": "dist/scripts", - "optimize": false + "optimize": false, + "scopeHoist": false }, "init-script": { "context": "node", "distDir": "dist/scripts", - "optimize": false + "optimize": false, + "scopeHoist": false } }, "engines": { @@ -143,7 +146,6 @@ "react-router-dom": "^5.1.2", "react-slick": "^0.28.1", "react-twitter-embed": "^3.0.3", - "reflect-metadata": "^0.1.13", "replacestream": "^4.0.3", "request-received": "0.0.3", "restful-react": "^15.2.0", diff --git a/src/backend/controllers/preprint.js b/src/backend/controllers/preprint.js index 0efbe812..6e560951 100644 --- a/src/backend/controllers/preprint.js +++ b/src/backend/controllers/preprint.js @@ -1,5 +1,4 @@ import router from 'koa-joi-router'; -import 'reflect-metadata'; import { QueryOrder } from '@mikro-orm/core'; import { getLogger } from '../log.ts'; import { resolvePreprint } from '../utils/resolve.ts'; diff --git a/src/backend/mikro-orm.config.ts b/src/backend/mikro-orm.config.ts index f786d0d0..e54e17c4 100644 --- a/src/backend/mikro-orm.config.ts +++ b/src/backend/mikro-orm.config.ts @@ -1,26 +1,26 @@ import { Options } from '@mikro-orm/core'; import { - Badge, - BaseEntity, - Comment, - Community, - Contact, - Event, - Expertise, - FullReview, - FullReviewDraft, - Group, - Key, - Persona, - Preprint, - RapidReview, - Report, - Request, - Statement, - Tag, - Template, - User, - Work, + badgeSchema, + baseEntitySchema, + commentSchema, + communitySchema, + contactSchema, + eventSchema, + expertiseSchema, + fullReviewSchema, + fullReviewDraftSchema, + groupSchema, + keySchema, + personaSchema, + preprintSchema, + rapidReviewSchema, + reportSchema, + requestSchema, + statementSchema, + tagSchema, + templateSchema, + userSchema, + workSchema, } from './models/entities'; import config from './config'; @@ -30,27 +30,27 @@ const portString = config.dbPort ? `:${config.dbPort}` : ''; const options: Options = { entities: [ - Badge, - BaseEntity, - Comment, - Community, - Contact, - Event, - Expertise, - FullReview, - FullReviewDraft, - Group, - Key, - Persona, - Preprint, - RapidReview, - Report, - Request, - Statement, - Tag, - Template, - User, - Work, + badgeSchema, + baseEntitySchema, + commentSchema, + communitySchema, + contactSchema, + eventSchema, + expertiseSchema, + fullReviewSchema, + fullReviewDraftSchema, + groupSchema, + keySchema, + personaSchema, + preprintSchema, + rapidReviewSchema, + reportSchema, + requestSchema, + statementSchema, + tagSchema, + templateSchema, + userSchema, + workSchema, ], type: 'postgresql', debug: config.logLevel === 'trace', diff --git a/src/backend/models/badges.ts b/src/backend/models/badges.ts index 19c8acbe..b25aa2e4 100644 --- a/src/backend/models/badges.ts +++ b/src/backend/models/badges.ts @@ -1,7 +1,6 @@ -import { EntityRepository, MikroORM, Repository } from '@mikro-orm/core'; +import { EntityRepository, MikroORM } from '@mikro-orm/core'; import { Badge } from './entities'; -@Repository(Badge) export class BadgeModel extends EntityRepository {} export function badgeModelWrapper(db: MikroORM): BadgeModel { diff --git a/src/backend/models/comments.ts b/src/backend/models/comments.ts index fd1bd078..08e8b3d0 100644 --- a/src/backend/models/comments.ts +++ b/src/backend/models/comments.ts @@ -1,7 +1,6 @@ -import { EntityRepository, MikroORM, Repository } from '@mikro-orm/core'; +import { EntityRepository, MikroORM } from '@mikro-orm/core'; import { Comment } from './entities'; -@Repository(Comment) export class CommentModel extends EntityRepository {} export function commentModelWrapper(db: MikroORM): CommentModel { diff --git a/src/backend/models/communities.ts b/src/backend/models/communities.ts index c4949c00..03b3507f 100644 --- a/src/backend/models/communities.ts +++ b/src/backend/models/communities.ts @@ -1,4 +1,4 @@ -import { EntityRepository, MikroORM, Repository } from '@mikro-orm/core'; +import { EntityRepository, MikroORM } from '@mikro-orm/core'; import { ORCID as orcidUtils } from 'orcid-utils'; import { validate as uuidValidate } from 'uuid'; import { Community, User } from './entities'; @@ -6,7 +6,6 @@ import { getLogger } from '../log'; const log = getLogger('backend:models:communities'); -@Repository(Community) export class CommunityModel extends EntityRepository { async isMemberOf(communityId: string, userId: string): Promise { let user: User | null = null; diff --git a/src/backend/models/contacts.ts b/src/backend/models/contacts.ts index d6bcfeb7..c554a78d 100644 --- a/src/backend/models/contacts.ts +++ b/src/backend/models/contacts.ts @@ -1,7 +1,6 @@ -import { EntityRepository, MikroORM, Repository } from '@mikro-orm/core'; +import { EntityRepository, MikroORM } from '@mikro-orm/core'; import { Contact } from './entities'; -@Repository(Contact) export class ContactModel extends EntityRepository {} export function contactModelWrapper(db: MikroORM): ContactModel { diff --git a/src/backend/models/entities/Badge.ts b/src/backend/models/entities/Badge.ts index 25bc47f1..17fc194d 100644 --- a/src/backend/models/entities/Badge.ts +++ b/src/backend/models/entities/Badge.ts @@ -1,27 +1,11 @@ -import { - Collection, - Entity, - EntityRepositoryType, - ManyToMany, - Property, - Unique, -} from '@mikro-orm/core'; +import { Collection, EntitySchema } from '@mikro-orm/core'; import { BadgeModel } from '../badges'; import { BaseEntity } from './BaseEntity'; import { Persona } from './Persona'; -@Entity() export class Badge extends BaseEntity { - [EntityRepositoryType]?: BadgeModel; - - @Property() - @Unique() name!: string; - - @Property() color?: string; - - @ManyToMany({ entity: () => Persona, inversedBy: 'badges' }) personas: Collection = new Collection(this); constructor(name: string, color = '#FF0000') { @@ -30,3 +14,18 @@ export class Badge extends BaseEntity { this.color = color; } } + +export const badgeSchema = new EntitySchema({ + class: Badge, + + customRepository: () => BadgeModel, + properties: { + name: { type: 'string', unique: true }, + color: { type: 'string' }, + personas: { + reference: 'm:n', + entity: () => Persona, + inversedBy: (persona) => persona.badges, + }, + }, +}); diff --git a/src/backend/models/entities/BaseEntity.ts b/src/backend/models/entities/BaseEntity.ts index 5bcdbca2..8d6f4e34 100644 --- a/src/backend/models/entities/BaseEntity.ts +++ b/src/backend/models/entities/BaseEntity.ts @@ -1,17 +1,20 @@ +import { EntitySchema } from '@mikro-orm/core'; import { v4 as uuidv4 } from 'uuid'; -import { PrimaryKey, Property, Unique } from '@mikro-orm/core'; export abstract class BaseEntity { - @PrimaryKey({ hidden: true }) id!: number; - - @Property({ type: 'string' }) - @Unique() uuid = uuidv4(); - - @Property() createdAt: Date = new Date(); - - @Property({ onUpdate: () => new Date() }) updatedAt: Date = new Date(); } + +export const baseEntitySchema = new EntitySchema({ + name: 'BaseEntity', + abstract: true, + properties: { + id: { type: 'number', hidden: true, primary: true }, + uuid: { type: 'string', unique: true }, + createdAt: { type: 'Date' }, + updatedAt: { type: 'Date', onUpdate: () => new Date() }, + }, +}); diff --git a/src/backend/models/entities/Comment.ts b/src/backend/models/entities/Comment.ts index 38ef756b..4b817dc2 100644 --- a/src/backend/models/entities/Comment.ts +++ b/src/backend/models/entities/Comment.ts @@ -1,34 +1,14 @@ -import { - Entity, - EntityRepositoryType, - Index, - ManyToOne, - Property, -} from '@mikro-orm/core'; +import { EntitySchema } from '@mikro-orm/core'; import { CommentModel } from '../comments'; import { BaseEntity } from './BaseEntity'; import { FullReview } from './FullReview'; import { Persona } from './Persona'; -@Entity() -@Index({ properties: ['author'] }) -@Index({ properties: ['parent'] }) export class Comment extends BaseEntity { - [EntityRepositoryType]?: CommentModel; - - @Property({ columnType: 'text' }) contents!: string; - - @Property() isPublished: boolean = false; - - @Property() isFlagged: boolean = false; - - @ManyToOne({ entity: () => Persona }) author!: Persona; - - @ManyToOne({ entity: () => FullReview }) parent!: FullReview; constructor(contents: string, author: Persona, parent: FullReview) { @@ -38,3 +18,16 @@ export class Comment extends BaseEntity { this.parent = parent; } } + +export const commentSchema = new EntitySchema({ + class: Comment, + customRepository: () => CommentModel, + indexes: [{ properties: 'author' }, { properties: 'parent' }], + properties: { + contents: { type: 'string', columnType: 'text' }, + isPublished: { type: 'boolean' }, + isFlagged: { type: 'boolean' }, + author: { reference: 'm:1', entity: () => Persona }, + parent: { reference: 'm:1', entity: () => FullReview }, + }, +}); diff --git a/src/backend/models/entities/Community.ts b/src/backend/models/entities/Community.ts index 737d0266..c45e7dd3 100644 --- a/src/backend/models/entities/Community.ts +++ b/src/backend/models/entities/Community.ts @@ -1,12 +1,4 @@ -import { - Collection, - Entity, - EntityRepositoryType, - ManyToMany, - OneToMany, - Property, - Unique, -} from '@mikro-orm/core'; +import { Collection, EntitySchema } from '@mikro-orm/core'; import { CommunityModel } from '../communities'; import { BaseEntity } from './BaseEntity'; import { Event } from './Event'; @@ -16,46 +8,18 @@ import { Tag } from './Tag'; import { Template } from './Template'; import { User } from './User'; -@Entity() export class Community extends BaseEntity { - [EntityRepositoryType]?: CommunityModel; - - @Property() - @Unique() name!: string; - - @Property() - @Unique() slug!: string; - - @Property({ columnType: 'text', nullable: true }) description?: string; - - @Property({ nullable: true }) banner?: Buffer; - - @Property({ nullable: true }) logo?: Buffer; - - @Property({ nullable: true }) twitter?: string; - - @ManyToMany({ entity: () => Persona, inversedBy: 'communities' }) members: Collection = new Collection(this); - - @ManyToMany({ entity: () => User, inversedBy: 'owned' }) owners: Collection = new Collection(this); - - @ManyToMany({ entity: () => Preprint, inversedBy: 'communities' }) preprints: Collection = new Collection(this); - - @OneToMany({ entity: () => Event, mappedBy: 'community' }) events: Collection = new Collection(this); - - @ManyToMany({ entity: () => Tag, inversedBy: 'communities' }) tags: Collection = new Collection(this); - - @OneToMany({ entity: () => Template, mappedBy: 'community' }) templates: Collection