ORM type refactor
This commit is contained in:
parent
f6a7cac05c
commit
395e8e4d1c
@ -8,7 +8,7 @@ import {Awaitable, JSONState} from '../../../util'
|
||||
* A basic ORM-driven user class.
|
||||
*/
|
||||
@Injectable()
|
||||
export class ORMUser extends Model<ORMUser> implements Authenticatable {
|
||||
export class ORMUser extends Model implements Authenticatable {
|
||||
|
||||
protected static table = 'users'
|
||||
|
||||
|
@ -18,7 +18,7 @@ export class ORMUserRepository extends AuthenticatableRepository {
|
||||
|
||||
/** Look up the user by their username. */
|
||||
getByIdentifier(id: AuthenticatableIdentifier): Awaitable<Maybe<Authenticatable>> {
|
||||
return (this.injector.getStaticOverride(ORMUser) as typeof ORMUser).query<ORMUser>()
|
||||
return (this.injector.getStaticOverride(ORMUser) as typeof ORMUser).query()
|
||||
.where('username', '=', id)
|
||||
.first()
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {Field, FieldType, Model} from '../../../orm'
|
||||
import {OAuth2Token} from '../types'
|
||||
|
||||
export class OAuth2TokenModel extends Model<OAuth2TokenModel> implements OAuth2Token {
|
||||
export class OAuth2TokenModel extends Model implements OAuth2Token {
|
||||
public static table = 'oauth2_tokens'
|
||||
|
||||
public static key = 'oauth2_token_id'
|
||||
|
@ -14,7 +14,7 @@ export class ORMTokenRepository extends TokenRepository {
|
||||
async find(id: string): Promise<Maybe<OAuth2Token>> {
|
||||
const idNum = parseInt(id, 10)
|
||||
if ( !isNaN(idNum) ) {
|
||||
return OAuth2TokenModel.query<OAuth2TokenModel>()
|
||||
return OAuth2TokenModel.query()
|
||||
.whereKey(idNum)
|
||||
.first()
|
||||
}
|
||||
|
@ -36,7 +36,13 @@ export function isInstantiableOf<T>(what: unknown, type: StaticClass<T, any>): w
|
||||
/**
|
||||
* Type that identifies a value as a static class, even if it is not instantiable.
|
||||
*/
|
||||
export type StaticClass<T, T2, TCtorParams extends any[] = any[]> = Function & {prototype: T} & { new (...args: TCtorParams) : T } & T2 // eslint-disable-line @typescript-eslint/ban-types
|
||||
export type StaticClass<T, T2, TCtorParams extends any[] = any[]> = T2 & StaticThis<T, TCtorParams> // eslint-disable-line @typescript-eslint/ban-types
|
||||
|
||||
/**
|
||||
* Quasi-reference to a `this` type w/in a static member.
|
||||
* @see https://github.com/microsoft/TypeScript/issues/5863#issuecomment-302861175
|
||||
*/
|
||||
export type StaticThis<T, TCtorParams extends any[]> = { new (...args: TCtorParams): T }
|
||||
|
||||
/**
|
||||
* Type that identifies a value as a static class that instantiates to itself
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {ModelKey, QueryRow, QuerySource} from '../types'
|
||||
import {Container, Inject, Instantiable, isInstantiable} from '../../di'
|
||||
import {Container, Inject, Instantiable, isInstantiable, StaticClass, StaticThis} from '../../di'
|
||||
import {DatabaseService} from '../DatabaseService'
|
||||
import {ModelBuilder} from './ModelBuilder'
|
||||
import {getFieldsMeta, ModelField} from './Field'
|
||||
@ -19,13 +19,13 @@ import {HasOne} from './relation/HasOne'
|
||||
import {HasMany} from './relation/HasMany'
|
||||
import {HasOneOrMany} from './relation/HasOneOrMany'
|
||||
import {Scope, ScopeClosure} from './scope/Scope'
|
||||
import {LocalBus} from '../../support/bus/LocalBus'
|
||||
import {LocalBus} from '../../support/bus'
|
||||
import {ModelEvent} from './events/ModelEvent'
|
||||
|
||||
/**
|
||||
* Base for classes that are mapped to tables in a database.
|
||||
*/
|
||||
export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>> {
|
||||
export abstract class Model extends LocalBus<ModelEvent> {
|
||||
@Inject()
|
||||
protected readonly logging!: Logging
|
||||
|
||||
@ -88,7 +88,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
* Relations that should be eager-loaded by default.
|
||||
* @protected
|
||||
*/
|
||||
protected with: (keyof T)[] = []
|
||||
protected with: (keyof this)[] = []
|
||||
|
||||
/**
|
||||
* The original row fetched from the database.
|
||||
@ -100,7 +100,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
* Cache of relation instances by property accessor.
|
||||
* This is used by the `@Relation()` decorator to cache Relation instances.
|
||||
*/
|
||||
public relationCache: Collection<{ accessor: string | symbol, relation: Relation<T, any, any> }> = new Collection<{accessor: string | symbol; relation: Relation<T, any, any>}>()
|
||||
public relationCache: Collection<{ accessor: string | symbol, relation: Relation<any, any, any> }> = new Collection<{accessor: string | symbol; relation: Relation<any, any, any>}>()
|
||||
|
||||
protected scopes: Collection<{ accessor: string | Instantiable<Scope>, scope: ScopeClosure }> = new Collection<{accessor: string | Instantiable<Scope>; scope: ScopeClosure}>()
|
||||
|
||||
@ -148,7 +148,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
* const user = await UserModel.query<UserModel>().where('name', 'LIKE', 'John Doe').first()
|
||||
* ```
|
||||
*/
|
||||
public static query<T2 extends Model<T2>>(): ModelBuilder<T2> {
|
||||
public static query<T2 extends Model>(this: StaticThis<T2, any[]> & typeof Model): ModelBuilder<T2> {
|
||||
const builder = <ModelBuilder<T2>> Container.getContainer().make<ModelBuilder<T2>>(ModelBuilder, this)
|
||||
const source: QuerySource = this.querySource()
|
||||
|
||||
@ -174,7 +174,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
} else if ( this.constructor.length < 1 ) {
|
||||
// Otherwise, if we can instantiate the model without any arguments,
|
||||
// do that and get the eager-loaded relations directly.
|
||||
const inst = Container.getContainer().make<Model<any>>(this)
|
||||
const inst = Container.getContainer().make<Model>(this)
|
||||
if ( Array.isArray(inst.with) ) {
|
||||
for (const relation of inst.with) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
@ -189,7 +189,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
builder.withScopes(this.prototype.scopes)
|
||||
} else if ( this.constructor.length < 1 ) {
|
||||
// Otherwise, try to instantiate the model if possible and load the scopes that way
|
||||
const inst = Container.getContainer().make<Model<any>>(this)
|
||||
const inst = Container.getContainer().make<Model>(this)
|
||||
builder.withScopes(inst.scopes)
|
||||
}
|
||||
|
||||
@ -247,7 +247,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
this.setFieldFromObject(field.modelKey, field.databaseKey, row)
|
||||
})
|
||||
|
||||
await this.push(new ModelRetrievedEvent<T>(this as any))
|
||||
await this.push(new ModelRetrievedEvent<this>(this as any))
|
||||
return this
|
||||
}
|
||||
|
||||
@ -329,9 +329,9 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
* .update({ username: 'jdoe' })
|
||||
* ```
|
||||
*/
|
||||
public query(): ModelBuilder<T> {
|
||||
public query(): ModelBuilder<this> {
|
||||
const ModelClass = this.constructor as typeof Model
|
||||
const builder = <ModelBuilder<T>> this.app().make<ModelBuilder<T>>(ModelBuilder, ModelClass)
|
||||
const builder = <ModelBuilder<this>> this.app().make<ModelBuilder<this>>(ModelBuilder, ModelClass)
|
||||
const source: QuerySource = ModelClass.querySource()
|
||||
|
||||
builder.connection(ModelClass.getConnection())
|
||||
@ -352,6 +352,15 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
|
||||
builder.withScopes(this.scopes)
|
||||
|
||||
return this.newBuilderInstance(builder)
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure ModelBuilder instances that query this model.
|
||||
* @param builder
|
||||
* @protected
|
||||
*/
|
||||
protected newBuilderInstance(builder: ModelBuilder<this>): ModelBuilder<this> {
|
||||
return builder
|
||||
}
|
||||
|
||||
@ -365,7 +374,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
public static async findByKey<T2 extends Model<T2>>(key: ModelKey): Promise<undefined | T2> {
|
||||
public static async findByKey<T2 extends Model>(this: StaticThis<T2, any[]> & typeof Model, key: ModelKey): Promise<undefined | T2> {
|
||||
return this.query<T2>()
|
||||
.where(this.qualifyKey(), '=', key)
|
||||
.limit(1)
|
||||
@ -376,7 +385,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
/**
|
||||
* Get an array of all instances of this model.
|
||||
*/
|
||||
public async all(): Promise<T[]> {
|
||||
public async all(): Promise<this[]> {
|
||||
return this.query().get()
|
||||
.all()
|
||||
}
|
||||
@ -616,12 +625,12 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
*
|
||||
* @param withoutTimestamps
|
||||
*/
|
||||
public async save({ withoutTimestamps = false } = {}): Promise<Model<T>> {
|
||||
await this.push(new ModelSavingEvent<T>(this as any))
|
||||
public async save({ withoutTimestamps = false } = {}): Promise<this> {
|
||||
await this.push(new ModelSavingEvent<this>(this))
|
||||
const ctor = this.constructor as typeof Model
|
||||
|
||||
if ( this.exists() && this.isDirty() ) {
|
||||
await this.push(new ModelUpdatingEvent<T>(this as any))
|
||||
await this.push(new ModelUpdatingEvent<this>(this))
|
||||
|
||||
if ( !withoutTimestamps && ctor.timestamps && ctor.UPDATED_AT ) {
|
||||
(this as any)[ctor.UPDATED_AT] = new Date()
|
||||
@ -642,9 +651,9 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
await this.assumeFromSource(data)
|
||||
}
|
||||
|
||||
await this.push(new ModelUpdatedEvent<T>(this as any))
|
||||
await this.push(new ModelUpdatedEvent<this>(this))
|
||||
} else if ( !this.exists() ) {
|
||||
await this.push(new ModelCreatingEvent<T>(this as any))
|
||||
await this.push(new ModelCreatingEvent<this>(this))
|
||||
|
||||
if ( !withoutTimestamps ) {
|
||||
if ( ctor.timestamps && ctor.CREATED_AT ) {
|
||||
@ -675,10 +684,10 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
await this.assumeFromSource(data)
|
||||
}
|
||||
|
||||
await this.push(new ModelCreatedEvent<T>(this as any))
|
||||
await this.push(new ModelCreatedEvent<this>(this))
|
||||
}
|
||||
|
||||
await this.push(new ModelSavedEvent<T>(this as any))
|
||||
await this.push(new ModelSavedEvent<this>(this))
|
||||
return this
|
||||
}
|
||||
|
||||
@ -745,7 +754,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
* This returns a NEW instance of the SAME record by matching on
|
||||
* the primary key. It does NOT change the current instance of the record.
|
||||
*/
|
||||
public async fresh(): Promise<Model<T> | undefined> {
|
||||
public async fresh(): Promise<this | undefined> {
|
||||
return this.query()
|
||||
.where(this.qualifyKey(), '=', this.key())
|
||||
.limit(1)
|
||||
@ -789,7 +798,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
*
|
||||
* @param model
|
||||
*/
|
||||
public async populate(model: T): Promise<T> {
|
||||
public async populate(model: this): Promise<this> {
|
||||
const row = this.toQueryRow()
|
||||
delete row[this.keyName()]
|
||||
await model.assumeFromSource(row)
|
||||
@ -803,7 +812,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
*
|
||||
* @param other
|
||||
*/
|
||||
public is(other: Model<any>): boolean {
|
||||
public is(other: Model): boolean {
|
||||
return this.key() === other.key() && this.qualifyKey() === other.qualifyKey()
|
||||
}
|
||||
|
||||
@ -811,7 +820,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
* Inverse of `is()`.
|
||||
* @param other
|
||||
*/
|
||||
public isNot(other: Model<any>): boolean {
|
||||
public isNot(other: Model): boolean {
|
||||
return !this.is(other)
|
||||
}
|
||||
|
||||
@ -886,8 +895,8 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
* @param foreignKeyOverride
|
||||
* @param localKeyOverride
|
||||
*/
|
||||
public hasOne<T2 extends Model<T2>>(related: Instantiable<T2>, foreignKeyOverride?: keyof T & string, localKeyOverride?: keyof T2 & string): HasOne<T, T2> {
|
||||
return new HasOne<T, T2>(this as unknown as T, this.make(related), foreignKeyOverride, localKeyOverride)
|
||||
public hasOne<T2 extends Model>(related: Instantiable<T2>, foreignKeyOverride?: keyof this & string, localKeyOverride?: keyof T2 & string): HasOne<this, T2> {
|
||||
return new HasOne<this, T2>(this, this.make(related), foreignKeyOverride, localKeyOverride)
|
||||
}
|
||||
|
||||
|
||||
@ -908,8 +917,8 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
* @param foreignKeyOverride
|
||||
* @param localKeyOverride
|
||||
*/
|
||||
public hasMany<T2 extends Model<T2>>(related: Instantiable<T2>, foreignKeyOverride?: keyof T & string, localKeyOverride?: keyof T2 & string): HasMany<T, T2> {
|
||||
return new HasMany<T, T2>(this as unknown as T, this.make(related), foreignKeyOverride, localKeyOverride)
|
||||
public hasMany<T2 extends Model>(related: Instantiable<T2>, foreignKeyOverride?: keyof this & string, localKeyOverride?: keyof T2 & string): HasMany<this, T2> {
|
||||
return new HasMany<this, T2>(this, this.make(related), foreignKeyOverride, localKeyOverride)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -935,7 +944,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
* @param related
|
||||
* @param relationName
|
||||
*/
|
||||
public belongsToOne<T2 extends Model<T2>>(related: Instantiable<T>, relationName: keyof T2): HasOne<T, T2> {
|
||||
public belongsToOne<T2 extends Model>(related: Instantiable<T2>, relationName: keyof T2): HasOne<this, T2> {
|
||||
const relatedInst = this.make(related) as T2
|
||||
const relation = relatedInst.getRelation(relationName)
|
||||
|
||||
@ -946,11 +955,11 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
const localKey = relation.localKey
|
||||
const foreignKey = relation.foreignKey
|
||||
|
||||
if ( !isKeyof(localKey, this as unknown as T) || !isKeyof(foreignKey, relatedInst) ) {
|
||||
if ( !isKeyof(localKey, this) || !isKeyof(foreignKey, relatedInst) ) {
|
||||
throw new TypeError('Local or foreign keys do not exist on the base model.')
|
||||
}
|
||||
|
||||
return new HasOne<T, T2>(this as unknown as T, relatedInst, localKey, foreignKey)
|
||||
return new HasOne(this, relatedInst, localKey, foreignKey)
|
||||
}
|
||||
|
||||
|
||||
@ -977,7 +986,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
* @param related
|
||||
* @param relationName
|
||||
*/
|
||||
public belongsToMany<T2 extends Model<T2>>(related: Instantiable<T>, relationName: keyof T2): HasMany<T, T2> {
|
||||
public belongsToMany<T2 extends Model>(related: Instantiable<T2>, relationName: keyof T2): HasMany<this, T2> {
|
||||
const relatedInst = this.make(related) as T2
|
||||
const relation = relatedInst.getRelation(relationName)
|
||||
|
||||
@ -988,11 +997,11 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
const localKey = relation.localKey
|
||||
const foreignKey = relation.foreignKey
|
||||
|
||||
if ( !isKeyof(localKey, this as unknown as T) || !isKeyof(foreignKey, relatedInst) ) {
|
||||
if ( !isKeyof(localKey, this) || !isKeyof(foreignKey, relatedInst) ) {
|
||||
throw new TypeError('Local or foreign keys do not exist on the base model.')
|
||||
}
|
||||
|
||||
return new HasMany<T, T2>(this as unknown as T, relatedInst, localKey, foreignKey)
|
||||
return new HasMany(this, relatedInst, localKey, foreignKey)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1000,7 +1009,7 @@ export abstract class Model<T extends Model<T>> extends LocalBus<ModelEvent<T>>
|
||||
* @param name
|
||||
* @protected
|
||||
*/
|
||||
public getRelation<T2 extends Model<T2>>(name: keyof this): Relation<T, T2, RelationValue<T2>> {
|
||||
public getRelation<T2 extends Model>(name: keyof this): Relation<this, T2, RelationValue<T2>> {
|
||||
const relFn = this[name]
|
||||
|
||||
if ( relFn instanceof Relation ) {
|
||||
|
@ -11,7 +11,7 @@ import {Scope, ScopeClosure} from './scope/Scope'
|
||||
/**
|
||||
* Implementation of the abstract builder whose results yield instances of a given Model, `T`.
|
||||
*/
|
||||
export class ModelBuilder<T extends Model<T>> extends AbstractBuilder<T> {
|
||||
export class ModelBuilder<T extends Model> extends AbstractBuilder<T> {
|
||||
protected eagerLoadRelations: (keyof T)[] = []
|
||||
|
||||
protected appliedScopes: Collection<{ accessor: string | Instantiable<Scope>, scope: ScopeClosure }> = new Collection<{accessor: string | Instantiable<Scope>; scope: ScopeClosure}>()
|
||||
|
@ -9,7 +9,7 @@ import {collect, Collection} from '../../util'
|
||||
/**
|
||||
* Implementation of the result iterable that returns query results as instances of the defined model.
|
||||
*/
|
||||
export class ModelResultIterable<T extends Model<T>> extends AbstractResultIterable<T> {
|
||||
export class ModelResultIterable<T extends Model> extends AbstractResultIterable<T> {
|
||||
constructor(
|
||||
public readonly builder: ModelBuilder<T>,
|
||||
public readonly connection: Connection,
|
||||
|
@ -13,19 +13,19 @@ export interface ModelSerialPayload extends JSONState {
|
||||
|
||||
@ObjectSerializer()
|
||||
@Injectable()
|
||||
export class ModelSerializer extends BaseSerializer<Model<any>, ModelSerialPayload> {
|
||||
export class ModelSerializer extends BaseSerializer<Model, ModelSerialPayload> {
|
||||
@Inject()
|
||||
protected readonly canon!: Canon
|
||||
|
||||
protected async decodeSerial(serial: ModelSerialPayload): Promise<Model<any>> {
|
||||
protected async decodeSerial(serial: ModelSerialPayload): Promise<Model> {
|
||||
const ModelClass = this.canon.getFromFullyQualified(serial.canonicalResolver) as typeof Model
|
||||
if ( !ModelClass || !(ModelClass.prototype instanceof Model) || !isInstantiable<Model<any>>(ModelClass) ) {
|
||||
if ( !ModelClass || !(ModelClass.prototype instanceof Model) || !isInstantiable<Model>(ModelClass) ) {
|
||||
throw new ErrorWithContext('Cannot decode serialized model as canonical resolver is invalid', {
|
||||
serial,
|
||||
})
|
||||
}
|
||||
|
||||
let inst: Maybe<Model<any>> = this.make<Model<any>>(ModelClass)
|
||||
let inst: Maybe<Model> = this.make<Model>(ModelClass)
|
||||
if ( serial.primaryKey ) {
|
||||
inst = await ModelClass.query()
|
||||
.whereKey(serial.primaryKey)
|
||||
@ -42,7 +42,7 @@ export class ModelSerializer extends BaseSerializer<Model<any>, ModelSerialPaylo
|
||||
return inst
|
||||
}
|
||||
|
||||
protected encodeActual(actual: Model<any>): Awaitable<ModelSerialPayload> {
|
||||
protected encodeActual(actual: Model): Awaitable<ModelSerialPayload> {
|
||||
const ctor = actual.constructor as typeof Model
|
||||
const canonicalResolver = ctor.getFullyQualifiedCanonicalResolver()
|
||||
if ( !canonicalResolver ) {
|
||||
@ -62,7 +62,7 @@ export class ModelSerializer extends BaseSerializer<Model<any>, ModelSerialPaylo
|
||||
return '@extollo/lib.ModelSerializer'
|
||||
}
|
||||
|
||||
matchActual(some: Model<any>): boolean {
|
||||
matchActual(some: Model): boolean {
|
||||
return some instanceof Model
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,6 @@ import {ModelEvent} from './ModelEvent'
|
||||
/**
|
||||
* Event fired right after a model is inserted.
|
||||
*/
|
||||
export class ModelCreatedEvent<T extends Model<T>> extends ModelEvent<T> {
|
||||
export class ModelCreatedEvent<T extends Model> extends ModelEvent<T> {
|
||||
eventName = '@extollo/lib.ModelCreatedEvent'
|
||||
}
|
||||
|
@ -4,6 +4,6 @@ import {ModelEvent} from './ModelEvent'
|
||||
/**
|
||||
* Event fired right before a model is inserted.
|
||||
*/
|
||||
export class ModelCreatingEvent<T extends Model<T>> extends ModelEvent<T> {
|
||||
export class ModelCreatingEvent<T extends Model> extends ModelEvent<T> {
|
||||
eventName = '@extollo/lib.ModelCreatingEvent'
|
||||
}
|
||||
|
@ -4,6 +4,6 @@ import {ModelEvent} from './ModelEvent'
|
||||
/**
|
||||
* Event fired right after a model is deleted.
|
||||
*/
|
||||
export class ModelDeletedEvent<T extends Model<T>> extends ModelEvent<T> {
|
||||
export class ModelDeletedEvent<T extends Model> extends ModelEvent<T> {
|
||||
eventName = '@extollo/lib.ModelDeletedEvent'
|
||||
}
|
||||
|
@ -4,6 +4,6 @@ import {ModelEvent} from './ModelEvent'
|
||||
/**
|
||||
* Event fired right before a model is deleted.
|
||||
*/
|
||||
export class ModelDeletingEvent<T extends Model<T>> extends ModelEvent<T> {
|
||||
export class ModelDeletingEvent<T extends Model> extends ModelEvent<T> {
|
||||
eventName = '@extollo/lib.ModelDeletingEvent'
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import {Awaitable} from '../../../util'
|
||||
* Base class for events that concern an instance of a model.
|
||||
* @fixme support serialization
|
||||
*/
|
||||
export abstract class ModelEvent<T extends Model<T>> extends BaseEvent {
|
||||
export abstract class ModelEvent<T extends Model = Model> extends BaseEvent {
|
||||
constructor(
|
||||
public readonly instance: T,
|
||||
) {
|
||||
|
@ -4,6 +4,6 @@ import {ModelEvent} from './ModelEvent'
|
||||
/**
|
||||
* Event fired right after a model's data is loaded from the source.
|
||||
*/
|
||||
export class ModelRetrievedEvent<T extends Model<T>> extends ModelEvent<T> {
|
||||
export class ModelRetrievedEvent<T extends Model> extends ModelEvent<T> {
|
||||
eventName = '@extollo/lib.ModelRetrievedEvent'
|
||||
}
|
||||
|
@ -4,6 +4,6 @@ import {ModelEvent} from './ModelEvent'
|
||||
/**
|
||||
* Event fired right after a model is persisted to the source.
|
||||
*/
|
||||
export class ModelSavedEvent<T extends Model<T>> extends ModelEvent<T> {
|
||||
export class ModelSavedEvent<T extends Model> extends ModelEvent<T> {
|
||||
eventName = '@extollo/lib.ModelSavedEvent'
|
||||
}
|
||||
|
@ -4,6 +4,6 @@ import {ModelEvent} from './ModelEvent'
|
||||
/**
|
||||
* Event fired right before a model is persisted to the source.
|
||||
*/
|
||||
export class ModelSavingEvent<T extends Model<T>> extends ModelEvent<T> {
|
||||
export class ModelSavingEvent<T extends Model> extends ModelEvent<T> {
|
||||
eventName = '@extollo/lib.ModelSavingEvent'
|
||||
}
|
||||
|
@ -4,6 +4,6 @@ import {ModelEvent} from './ModelEvent'
|
||||
/**
|
||||
* Event fired right after a model's data is updated.
|
||||
*/
|
||||
export class ModelUpdatedEvent<T extends Model<T>> extends ModelEvent<T> {
|
||||
export class ModelUpdatedEvent<T extends Model> extends ModelEvent<T> {
|
||||
eventName = '@extollo/lib.ModelUpdatedEvent'
|
||||
}
|
||||
|
@ -4,6 +4,6 @@ import {ModelEvent} from './ModelEvent'
|
||||
/**
|
||||
* Event fired right before a model's data is updated.
|
||||
*/
|
||||
export class ModelUpdatingEvent<T extends Model<T>> extends ModelEvent<T> {
|
||||
export class ModelUpdatingEvent<T extends Model> extends ModelEvent<T> {
|
||||
eventName = '@extollo/lib.ModelUpdatingEvent'
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import {RelationNotLoadedError} from './Relation'
|
||||
/**
|
||||
* One-to-many relation implementation.
|
||||
*/
|
||||
export class HasMany<T extends Model<T>, T2 extends Model<T2>> extends HasOneOrMany<T, T2, Collection<T2>> {
|
||||
export class HasMany<T extends Model, T2 extends Model> extends HasOneOrMany<T, T2, Collection<T2>> {
|
||||
protected cachedValue?: Collection<T2>
|
||||
|
||||
protected cachedLoaded = false
|
||||
|
@ -6,7 +6,7 @@ import {Maybe} from '../../../util'
|
||||
/**
|
||||
* One-to-one relation implementation.
|
||||
*/
|
||||
export class HasOne<T extends Model<T>, T2 extends Model<T2>> extends HasOneOrMany<T, T2, Maybe<T2>> {
|
||||
export class HasOne<T extends Model, T2 extends Model> extends HasOneOrMany<T, T2, Maybe<T2>> {
|
||||
protected cachedValue?: T2
|
||||
|
||||
protected cachedLoaded = false
|
||||
|
@ -9,7 +9,7 @@ import {Collection, toString} from '../../../util'
|
||||
/**
|
||||
* Base class for 1:1 and 1:M relations.
|
||||
*/
|
||||
export abstract class HasOneOrMany<T extends Model<T>, T2 extends Model<T2>, V extends RelationValue<T2>> extends Relation<T, T2, V> {
|
||||
export abstract class HasOneOrMany<T extends Model, T2 extends Model, V extends RelationValue<T2>> extends Relation<T, T2, V> {
|
||||
protected constructor(
|
||||
parent: T,
|
||||
related: T2,
|
||||
|
@ -22,7 +22,7 @@ export class RelationNotLoadedError extends ErrorWithContext {
|
||||
/**
|
||||
* Base class for inter-model relation implementations.
|
||||
*/
|
||||
export abstract class Relation<T extends Model<T>, T2 extends Model<T2>, V extends RelationValue<T2>> extends InjectionAware {
|
||||
export abstract class Relation<T extends Model, T2 extends Model, V extends RelationValue<T2>> extends InjectionAware {
|
||||
protected constructor(
|
||||
/** The model related from. */
|
||||
protected parent: T,
|
||||
|
@ -5,7 +5,7 @@ import {Relation} from './Relation'
|
||||
/**
|
||||
* ModelBuilder instance that queries the related model in a relation.
|
||||
*/
|
||||
export class RelationBuilder<T extends Model<T>> extends ModelBuilder<T> {
|
||||
export class RelationBuilder<T extends Model> extends ModelBuilder<T> {
|
||||
constructor(
|
||||
protected relation: Relation<any, T, any>,
|
||||
) {
|
||||
|
@ -14,7 +14,7 @@ export function Related(): MethodDecorator {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
descriptor.value = function(...args) {
|
||||
const model = this as Model<any>
|
||||
const model = this as Model
|
||||
const cache = model.relationCache
|
||||
|
||||
const existing = cache.firstWhere('accessor', '=', propertyKey)
|
||||
|
@ -9,7 +9,7 @@ import {CanonicalDefinition} from '../../service/Canonical'
|
||||
* Canonical unit responsible for loading the model classes defined by the application.
|
||||
*/
|
||||
@Singleton()
|
||||
export class Models extends CanonicalStatic<Model<any>, Instantiable<Model<any>>> {
|
||||
export class Models extends CanonicalStatic<Model, Instantiable<Model>> {
|
||||
@Inject()
|
||||
protected readonly cli!: CommandLine
|
||||
|
||||
@ -24,7 +24,7 @@ export class Models extends CanonicalStatic<Model<any>, Instantiable<Model<any>>
|
||||
this.cli.registerTemplate(templateModel)
|
||||
}
|
||||
|
||||
public async initCanonicalItem(definition: CanonicalDefinition): Promise<Instantiable<Model<any>>> {
|
||||
public async initCanonicalItem(definition: CanonicalDefinition): Promise<Instantiable<Model>> {
|
||||
const item = await super.initCanonicalItem(definition)
|
||||
if ( !(item.prototype instanceof Model) ) {
|
||||
throw new TypeError(`Invalid controller definition: ${definition.originalName}. Models must extend from @extollo/orm.Model.`)
|
||||
|
@ -7,7 +7,7 @@ import {ModelBuilder} from '../model/ModelBuilder'
|
||||
/**
|
||||
* A model instance which stores records from the ORMCache driver.
|
||||
*/
|
||||
export class CacheModel extends Model<CacheModel> {
|
||||
export class CacheModel extends Model {
|
||||
protected static table = 'caches'; // FIXME allow configuring
|
||||
|
||||
protected static key = 'cache_key';
|
||||
@ -22,7 +22,7 @@ export class CacheModel extends Model<CacheModel> {
|
||||
public cacheExpires?: Date;
|
||||
|
||||
public static withCacheKey(key: string): ModelBuilder<CacheModel> {
|
||||
return this.query<CacheModel>()
|
||||
return this.query()
|
||||
.whereKey(key)
|
||||
.whereProperty('cacheExpires', '>', new Date())
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ export class ORMCache extends Cache {
|
||||
}
|
||||
|
||||
public async put(key: string, value: string, expires?: Date): Promise<void> {
|
||||
let model = await CacheModel.findByKey<CacheModel>(key)
|
||||
let model = await CacheModel.findByKey(key)
|
||||
if ( !model ) {
|
||||
model = <CacheModel> Container.getContainer().make(CacheModel)
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ export class ORMSession extends Session {
|
||||
throw new NoSessionKeyError()
|
||||
}
|
||||
|
||||
const session = <SessionModel> await SessionModel.findByKey(this.key)
|
||||
const session = await SessionModel.findByKey(this.key)
|
||||
if ( session ) {
|
||||
this.session = session
|
||||
this.data = this.session.json
|
||||
|
@ -5,7 +5,7 @@ import {FieldType} from '../types'
|
||||
/**
|
||||
* Model used to fetch & store sessions from the ORMSession driver.
|
||||
*/
|
||||
export class SessionModel extends Model<SessionModel> {
|
||||
export class SessionModel extends Model {
|
||||
protected static table = 'sessions' // FIXME allow configuring
|
||||
|
||||
protected static key = 'session_uuid'
|
||||
|
Loading…
Reference in New Issue
Block a user