openstamanager/resources/ts/Models/Model.ts

93 lines
2.4 KiB
TypeScript

import RequestHttpClient from '@osm/Models/Http/RequestHttpClient';
import {
Model as BaseModel,
PaginationStrategy,
PluralResponse
} from 'coloquent';
import type {ValueOf} from 'type-fest';
export interface ModelAttributes {
id: number;
createdAt: Date;
updatedAt: Date;
[key: string]: unknown;
}
export interface ModelRelations {
[key: string]: unknown;
}
/**
* The base model for all models.
*/
export default abstract class Model<A extends ModelAttributes, R extends ModelRelations> extends BaseModel {
protected static paginationStrategy = PaginationStrategy.PageBased;
protected static jsonApiBaseUrl = '/api/restify';
protected static httpClient = new RequestHttpClient();
static dates = {
createdAt: 'YYYY-MM-DDTHH:mm:ss.ssssssZ',
updatedAt: 'YYYY-MM-DDTHH:mm:ss.ssssssZ'
};
protected static get jsonApiType() {
return `${this.name.toLowerCase()}s`;
}
/**
* Returns all the instances of the model. (Alias of {@link Model.get}).
*/
static all<M extends Model<any, any>>(): Promise<PluralResponse<M>> {
// @ts-expect-error
return this.get();
}
/**
* Set multiple attributes on the model.
*/
setAttributes(attributes: A | Map<keyof A, ValueOf<A>>) {
// Record to map
if (!(attributes instanceof Map)) {
// eslint-disable-next-line no-param-reassign
attributes = new Map(Object.entries(attributes) as [keyof A, ValueOf<A>][]);
}
for (const [attribute, value] of attributes) {
this.setAttribute(attribute, value);
}
}
getAttribute<AN extends keyof A = keyof A>(attributeName: AN) {
return super.getAttribute(attributeName as string) as ValueOf<A, AN>;
}
getAttributes() {
return super.getAttributes() as ModelAttributes;
}
setAttribute<AN extends keyof A = keyof A>(attributeName: AN, value: ValueOf<A, AN>) {
// @ts-expect-error — This is needed to parse the dates correctly.
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
this.attributes.set(attributeName as string, value);
}
getRelation<RN extends keyof R = keyof R>(relationName: RN) {
return super.getRelation(relationName as string) as ValueOf<R, RN>;
}
/**
* Get model ID.
*/
getId() {
return this.getApiId();
}
/**
* Check if the model is new (not already saved).
*/
isNew() {
return this.getId() === undefined;
}
}