/**
 * `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 } from '../types/core-storage';
/**
 * internal type `Model`
 */
declare type Model = CoreModel<string>;
/**
 * partial set of `CoreModel`
 */
export interface Cores {
    /**
     * 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 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 from model to view
     *
     * @see Transformable.modelAsView
     */
    modelAsView(model: MyModel, hasCores?: boolean): MyView;
    /**
     * transform from body(req-body) to model
     *
     * @see Transformable.bodyToModel
     */
    bodyToModel(body: MyBody | any, isCreate?: boolean): MyModel;
}
export {};
