225 lines
5.2 KiB
TypeScript
225 lines
5.2 KiB
TypeScript
import { Filter, OnlyDefined } from '@rondo.dev/common'
|
|
import { HTTPClient } from '@rondo.dev/http-client'
|
|
import { Routes } from '@rondo.dev/http-types'
|
|
import { CRUDAction, CRUDChangeAction, CRUDCreateAction, CRUDEditAction } from './CRUDAction'
|
|
import { CRUDMethod } from './CRUDMethod'
|
|
|
|
type Action <T, ActionType extends string, Method extends CRUDMethod> =
|
|
Filter<CRUDAction<T, ActionType> , {method: Method, status: 'pending'}>
|
|
|
|
interface PostParams<Body = unknown, Params = unknown> {
|
|
body: Body
|
|
params: Params
|
|
}
|
|
|
|
interface GetParams<Query = unknown, Params = unknown> {
|
|
query: Query
|
|
params: Params
|
|
}
|
|
|
|
export interface CRUDChangeParams<T> {
|
|
id?: number
|
|
key: keyof T & string
|
|
value: string
|
|
}
|
|
|
|
export class SaveActionCreator<
|
|
T extends Routes,
|
|
Route extends keyof T & string,
|
|
ActionType extends string,
|
|
> {
|
|
|
|
constructor(
|
|
readonly http: HTTPClient<T>,
|
|
readonly route: Route,
|
|
readonly type: ActionType,
|
|
) {}
|
|
|
|
save = (params: OnlyDefined<{
|
|
body: T[Route]['post']['body']
|
|
params: T[Route]['post']['params']
|
|
}>): Action<T[Route]['post']['response'], ActionType, 'save'> => {
|
|
const p = params as PostParams
|
|
return {
|
|
payload: this.http.post(this.route, p.body, p.params),
|
|
type: this.type,
|
|
method: 'save',
|
|
status: 'pending',
|
|
}
|
|
}
|
|
}
|
|
|
|
export class FindOneActionCreator<
|
|
T extends Routes,
|
|
Route extends keyof T & string,
|
|
ActionType extends string,
|
|
> {
|
|
|
|
constructor(
|
|
readonly http: HTTPClient<T>,
|
|
readonly route: Route,
|
|
readonly type: ActionType,
|
|
) {}
|
|
|
|
findOne = (params: OnlyDefined<{
|
|
query: T[Route]['get']['query']
|
|
params: T[Route]['get']['params']
|
|
}>): Action<T[Route]['get']['response'], ActionType, 'findOne'> => {
|
|
const p = params as {query: unknown, params: unknown}
|
|
return {
|
|
payload: this.http.get(this.route, p.query, p.params),
|
|
type: this.type,
|
|
method: 'findOne',
|
|
status: 'pending',
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
export class UpdateActionCreator<
|
|
T extends Routes,
|
|
Route extends keyof T & string,
|
|
ActionType extends string
|
|
> {
|
|
|
|
constructor(
|
|
readonly http: HTTPClient<T>,
|
|
readonly route: Route,
|
|
readonly type: ActionType,
|
|
) {}
|
|
|
|
update = (params: OnlyDefined<{
|
|
body: T[Route]['put']['body']
|
|
params: T[Route]['put']['params']
|
|
}>): Action<T[Route]['put']['response'], ActionType, 'update'> => {
|
|
const p = params as PostParams
|
|
return {
|
|
payload: this.http.put(this.route, p.body, p.params),
|
|
type: this.type,
|
|
method: 'update',
|
|
status: 'pending',
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
export class RemoveActionCreator<
|
|
T extends Routes,
|
|
Route extends keyof T & string,
|
|
ActionType extends string,
|
|
> {
|
|
|
|
constructor(
|
|
readonly http: HTTPClient<T>,
|
|
readonly route: Route,
|
|
readonly type: ActionType,
|
|
) {}
|
|
|
|
remove = (params: OnlyDefined<{
|
|
body: T[Route]['delete']['body']
|
|
params: T[Route]['delete']['params']
|
|
}>): Action<T[Route]['delete']['response'], ActionType, 'remove'> => {
|
|
const p = params as PostParams
|
|
return {
|
|
payload: this.http.delete(this.route, p.body, p.params),
|
|
type: this.type,
|
|
method: 'remove',
|
|
status: 'pending',
|
|
}
|
|
}
|
|
}
|
|
|
|
export class FindManyActionCreator<
|
|
T extends Routes,
|
|
Route extends keyof T & string,
|
|
ActionType extends string,
|
|
> {
|
|
|
|
constructor(
|
|
readonly http: HTTPClient<T>,
|
|
readonly route: Route,
|
|
readonly type: ActionType,
|
|
) {}
|
|
|
|
findMany = (params: OnlyDefined<{
|
|
query: T[Route]['get']['query']
|
|
params: T[Route]['get']['params']
|
|
}>): {
|
|
payload: Promise<T[Route]['get']['response']>
|
|
type: ActionType
|
|
status: 'pending'
|
|
method: 'findMany'
|
|
} => {
|
|
const p = params as GetParams
|
|
return {
|
|
payload: this.http.get(this.route, p.query, p.params),
|
|
type: this.type,
|
|
method: 'findMany',
|
|
status: 'pending',
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
export class FormActionCreator<T, ActionType extends string> {
|
|
constructor(readonly actionType: ActionType) {}
|
|
|
|
create = (item: Partial<T>): CRUDCreateAction<T, ActionType> => {
|
|
return {
|
|
payload: item,
|
|
type: this.actionType,
|
|
method: 'create',
|
|
}
|
|
}
|
|
|
|
edit = (params: {id: number}): CRUDEditAction<ActionType> => {
|
|
return {
|
|
payload: {id: params.id},
|
|
type: this.actionType,
|
|
method: 'edit',
|
|
}
|
|
}
|
|
|
|
change = (
|
|
params: CRUDChangeParams<T>,
|
|
): CRUDChangeAction<T, ActionType> => {
|
|
return {
|
|
payload: params,
|
|
type: this.actionType,
|
|
method: 'change',
|
|
}
|
|
}
|
|
}
|
|
|
|
export function createCRUDActions<
|
|
T extends Routes,
|
|
EntityRoute extends keyof T & string,
|
|
ListRoute extends keyof T & string,
|
|
ActionType extends string,
|
|
>(
|
|
http: HTTPClient<T>,
|
|
entityRoute: EntityRoute,
|
|
listRoute: ListRoute,
|
|
actionType: ActionType,
|
|
) {
|
|
const {save} = new SaveActionCreator(http, listRoute, actionType)
|
|
const {update} = new UpdateActionCreator(http, entityRoute, actionType)
|
|
const {remove} = new RemoveActionCreator(http, entityRoute, actionType)
|
|
const {findOne} = new FindOneActionCreator(http, entityRoute, actionType)
|
|
const {findMany} = new FindManyActionCreator(http, listRoute, actionType)
|
|
|
|
const {create, edit, change} = new FormActionCreator
|
|
<T[ListRoute]['post']['body'], ActionType>(actionType)
|
|
|
|
return {
|
|
save,
|
|
update,
|
|
remove,
|
|
findOne,
|
|
findMany,
|
|
create,
|
|
edit,
|
|
change,
|
|
}
|
|
}
|