You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
2.2 KiB
69 lines
2.2 KiB
3 years ago
|
import {BaseSerializer, ObjectSerializer} from '../../support/bus'
|
||
|
import {Model} from './Model'
|
||
|
import {Awaitable, ErrorWithContext, JSONState, Maybe} from '../../util'
|
||
|
import {QueryRow} from '../types'
|
||
|
import {Inject, Injectable, isInstantiable} from '../../di'
|
||
|
import {Canon} from '../../service/Canon'
|
||
|
|
||
|
export interface ModelSerialPayload extends JSONState {
|
||
|
canonicalResolver: string,
|
||
|
primaryKey: any,
|
||
|
objectValues: QueryRow,
|
||
|
}
|
||
|
|
||
|
@ObjectSerializer()
|
||
|
@Injectable()
|
||
|
export class ModelSerializer extends BaseSerializer<Model<any>, ModelSerialPayload> {
|
||
|
@Inject()
|
||
|
protected readonly canon!: Canon
|
||
|
|
||
|
protected async decodeSerial(serial: ModelSerialPayload): Promise<Model<any>> {
|
||
|
const ModelClass = this.canon.getFromFullyQualified(serial.canonicalResolver) as typeof Model
|
||
|
if ( !ModelClass || !(ModelClass.prototype instanceof Model) || !isInstantiable<Model<any>>(ModelClass) ) {
|
||
|
throw new ErrorWithContext('Cannot decode serialized model as canonical resolver is invalid', {
|
||
|
serial,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
let inst: Maybe<Model<any>> = this.make<Model<any>>(ModelClass)
|
||
|
if ( serial.primaryKey ) {
|
||
|
inst = await ModelClass.query()
|
||
|
.whereKey(serial.primaryKey)
|
||
|
.first()
|
||
|
}
|
||
|
|
||
|
if ( !inst ) {
|
||
|
throw new ErrorWithContext('Could not look up serialized model', {
|
||
|
serial,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
await inst.assume(serial.objectValues)
|
||
|
return inst
|
||
|
}
|
||
|
|
||
|
protected encodeActual(actual: Model<any>): Awaitable<ModelSerialPayload> {
|
||
|
const ctor = actual.constructor as typeof Model
|
||
|
const canonicalResolver = ctor.getFullyQualifiedCanonicalResolver()
|
||
|
if ( !canonicalResolver ) {
|
||
|
throw new ErrorWithContext('Unable to serialize model: no Canonical resolver', {
|
||
|
actual,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
canonicalResolver,
|
||
|
primaryKey: actual.key(),
|
||
|
objectValues: actual.toObject(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected getName(): string {
|
||
|
return '@extollo/lib.ModelSerializer'
|
||
|
}
|
||
|
|
||
|
matchActual(some: Model<any>): boolean {
|
||
|
return some instanceof Model
|
||
|
}
|
||
|
}
|