Skip to content

Commit

Permalink
fix: require generic type of ChangeSet (fixes older TS compatibility)
Browse files Browse the repository at this point in the history
  • Loading branch information
B4nan committed Mar 11, 2019
1 parent e2bf26d commit d8503d7
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 22 deletions.
2 changes: 1 addition & 1 deletion lib/decorators/Entity.ts
Expand Up @@ -52,7 +52,7 @@ export type EntityData<T extends IEntityType<T>> = { [P in keyof T]?: T[P] | IPr
export interface EntityProperty {
name: string;
fk: string;
entity: () => string | Function;
entity: () => EntityName<IEntity>;
type: string;
primary: boolean;
reference: ReferenceType;
Expand Down
3 changes: 1 addition & 2 deletions lib/unit-of-work/ChangeSet.ts
@@ -1,7 +1,6 @@
import { EntityData, IEntityType } from '../decorators';

export interface ChangeSet<T extends IEntityType<T> = IEntityType<any>> {
index: number;
export interface ChangeSet<T extends IEntityType<T>> {
name: string;
collection: string;
delete: boolean;
Expand Down
24 changes: 12 additions & 12 deletions lib/unit-of-work/ChangeSetComputer.ts
@@ -1,6 +1,6 @@
import { Utils } from '../utils';
import { MetadataStorage } from '../metadata';
import { EntityProperty, IEntity } from '../decorators';
import { EntityData, EntityProperty, IEntity, IEntityType } from '../decorators';
import { ChangeSet } from './ChangeSet';
import { Collection, EntityIdentifier, EntityValidator, ReferenceType } from '../entity';

Expand All @@ -9,11 +9,11 @@ export class ChangeSetComputer {
private readonly metadata = MetadataStorage.getMetadata();

constructor(private readonly validator: EntityValidator,
private readonly originalEntityData: Record<string, IEntity>,
private readonly originalEntityData: Record<string, EntityData<IEntity>>,
private readonly identifierMap: Record<string, EntityIdentifier>) { }

computeChangeSet(entity: IEntity): ChangeSet | null {
const changeSet = { entity } as ChangeSet;
computeChangeSet<T extends IEntityType<T>>(entity: T): ChangeSet<T> | null {
const changeSet = { entity } as ChangeSet<T>;
const meta = this.metadata[entity.constructor.name];

changeSet.name = meta.name;
Expand All @@ -33,32 +33,32 @@ export class ChangeSetComputer {
return changeSet;
}

private computePayload(entity: IEntity): Record<string, any> {
private computePayload<T extends IEntityType<T>>(entity: T): EntityData<T> {
if (entity.id && this.originalEntityData[entity.uuid]) {
return Utils.diffEntities(this.originalEntityData[entity.uuid], entity);
return Utils.diffEntities<T>(this.originalEntityData[entity.uuid] as T, entity);
} else {
return Utils.prepareEntity(entity);
}
}

private processReference(changeSet: ChangeSet, prop: EntityProperty): void {
private processReference<T extends IEntityType<T>>(changeSet: ChangeSet<T>, prop: EntityProperty): void {
if (prop.reference === ReferenceType.MANY_TO_MANY && prop.owner) {
this.processManyToMany(changeSet, prop, changeSet.entity[prop.name]);
} else if (prop.reference === ReferenceType.MANY_TO_ONE && changeSet.entity[prop.name]) {
this.processManyToMany(changeSet, prop, changeSet.entity[prop.name as keyof T]);
} else if (prop.reference === ReferenceType.MANY_TO_ONE && changeSet.entity[prop.name as keyof T]) {
this.processManyToOne(prop, changeSet);
}
}

private processManyToOne(prop: EntityProperty, changeSet: ChangeSet): void {
private processManyToOne<T extends IEntityType<T>>(prop: EntityProperty, changeSet: ChangeSet<T>): void {
const pk = this.metadata[prop.type].primaryKey;
const entity = changeSet.entity[prop.name];
const entity = changeSet.entity[prop.name as keyof T];

if (!entity[pk]) {
changeSet.payload[prop.name] = this.identifierMap[entity.uuid];
}
}

private processManyToMany(changeSet: ChangeSet, prop: EntityProperty, collection: Collection<IEntity>): void {
private processManyToMany<T extends IEntityType<T>>(changeSet: ChangeSet<T>, prop: EntityProperty, collection: Collection<IEntity>): void {
if (prop.owner && collection.isDirty()) {
const pk = this.metadata[prop.type].primaryKey as keyof IEntity;
changeSet.payload[prop.name] = collection.getItems().map(item => item[pk] || this.identifierMap[item.uuid]);
Expand Down
4 changes: 2 additions & 2 deletions lib/unit-of-work/UnitOfWork.ts
Expand Up @@ -21,7 +21,7 @@ export class UnitOfWork {

private readonly persistStack: IEntity[] = [];
private readonly removeStack: IEntity[] = [];
private readonly changeSets: ChangeSet[] = [];
private readonly changeSets: ChangeSet<IEntity>[] = [];
private readonly metadata = MetadataStorage.getMetadata();
private readonly changeSetComputer = new ChangeSetComputer(this.em.getValidator(), this.originalEntityData, this.identifierMap);
private readonly changeSetPersister = new ChangeSetPersister(this.em.getDriver(), this.identifierMap);
Expand Down Expand Up @@ -121,7 +121,7 @@ export class UnitOfWork {

for (const entity of Object.values(this.removeStack)) {
const meta = this.metadata[entity.constructor.name];
this.changeSets.push({ entity, delete: true, name: meta.name, collection: meta.collection, payload: {} } as ChangeSet);
this.changeSets.push({ entity, delete: true, name: meta.name, collection: meta.collection, payload: {} } as ChangeSet<IEntity>);
}
}

Expand Down
10 changes: 5 additions & 5 deletions lib/utils/Utils.ts
Expand Up @@ -2,7 +2,7 @@ import * as fastEqual from 'fast-deep-equal';
import * as clone from 'clone';

import { MetadataStorage } from '../metadata';
import { EntityMetadata, IEntity, IEntityType, IPrimaryKey } from '../decorators';
import { EntityData, EntityMetadata, IEntity, IEntityType, IPrimaryKey } from '../decorators';
import { ArrayCollection } from '../entity';

export class Utils {
Expand Down Expand Up @@ -47,7 +47,7 @@ export class Utils {
return Utils.merge(target, ...sources);
}

static diff(a: Record<string, any>, b: Record<string, any>): Record<string, any> {
static diff(a: Record<string, any>, b: Record<string, any>): Record<keyof (typeof a & typeof b), any> {
const ret: Record<string, any> = {};

Object.keys(b).forEach(k => {
Expand All @@ -61,11 +61,11 @@ export class Utils {
return ret;
}

static diffEntities(a: IEntity, b: IEntity): Record<string, any> {
return Utils.diff(Utils.prepareEntity(a), Utils.prepareEntity(b));
static diffEntities<T extends IEntityType<T>>(a: T, b: T): EntityData<T> {
return Utils.diff(Utils.prepareEntity(a), Utils.prepareEntity(b)) as EntityData<T>;
}

static prepareEntity<T>(e: IEntityType<T>): Record<string, any> {
static prepareEntity<T extends IEntityType<T>>(e: T): EntityData<T> {
const metadata = MetadataStorage.getMetadata();
const meta = metadata[e.constructor.name];
const ret = Utils.copy(e);
Expand Down

0 comments on commit d8503d7

Please sign in to comment.