lemon-model
Version:
Common shared model definitions for Lemon Micro-Service Platform
152 lines (151 loc) • 3.78 kB
TypeScript
/**
* `transformer.ts`
* - general transformer between `Model`, `View` and `Body`
*
*
* @author Steve <steve@lemoncloud.io>
* @date 2023-01-19 initial version
*
* @copyright (C) 2023 LemonCloud Co Ltd. - All Rights Reserved.
*/
import { CoreModel, CoreModifier } from '../types/core-storage';
/**
* internal type `Model`
*/
declare type Model = CoreModel<string>;
/**
* partial set of `CoreModel`
*/
export interface Cores extends Partial<CoreModifier> {
/**
* site-id of model
* - inited by `identity-token` if use session
*/
sid?: string;
/**
* user-id of model
* - inited by `identity-token` if use session
*/
uid?: string;
/**
* group-id of model
* - inited by `identity-token` if use session
*/
gid?: string;
}
/**
* common `View` types.
* - layout of response.
*/
export interface View {
/**
* (optional) model's id
*/
id?: string;
/**
* created timestamp
*/
createdAt?: number;
/**
* updated timestamp
*/
updatedAt?: number;
/**
* deleted timestamp
*/
deletedAt?: number;
/**
* (optional) internal error.
*/
error?: string;
/**
* (optional) internal cores modifier info.
* - present if `hasCores` is true in `modelAsView()`
* - or can be shown only if model has cores data.
*/
readonly $?: Cores;
}
/**
* common `Body` types.
* - layout of request's body.
*/
export interface Body {
/**
* (optional) target model's id
*/
id?: string;
}
/**
* transform model to view, or body to model.
* - required the sub-class model of `CoreModel`
*
* @see CoreModel
*/
export interface Transformable<MyModel extends Model, MyView extends View, MyBody extends Body> {
/**
* transform model to view
* - result will be response json.
*
* @param model the data model.
* @param hasCores (optional) include the properties in `CoreModel` as `$`
*/
modelAsView: (model: MyModel, hasCores?: boolean) => MyView;
/**
* transform request-body to model.
* - must check data types
*
* @param body the body posted
* @param isCreate (optional) if body is for creation.
*/
bodyToModel: (body: MyBody, isCreate?: boolean) => MyModel;
}
/**
* reverse into model from remote view & body.
*/
export interface Reversable<Model, View = Model, Body = Model> {
/**
* convert response-view to model
*/
asModel: (view: View) => Model;
/**
* convert model to request-body.
*/
asBody: (model: Model) => Body;
}
/**
* type: `AbstractTransformer`
* - common base class of `Transformable`
*/
export declare abstract class AbstractTransformer<MyModel extends Model, MyView extends View, MyBody extends Body> implements Transformable<MyModel, MyView, MyBody> {
/**
* check in date: YYYY-MM-DD
*
* @param val string
* @param field (optional) target field name to use
*/
asDate: (val: string, field?: string) => string;
/**
* extract only the defined attribute.
* ex) `{ a:1, b: undefined }` -> `{ a:1 }`
*/
onlyDefined: <T extends object>(N?: T) => T;
/**
* transform the cores data
* @param cores the cores data to transform
* @returns transformed cores data or null
*/
asCore<T extends Cores>(cores?: T | null): T | null;
/**
* transform from model to view
*
* @see Transformable.modelAsView
*/
modelAsView(model?: MyModel | null, hasCores?: boolean): MyView;
/**
* transform from body(req-body) to model
*
* @see Transformable.bodyToModel
*/
bodyToModel(body: MyBody | any, isCreate?: boolean): MyModel;
}
export {};