Make query optional
This commit is contained in:
parent
0a9648c392
commit
b8ff27128b
@ -58,8 +58,8 @@ describe('CRUD', () => {
|
|||||||
const http = new HTTPClientMock<ITestAPI>()
|
const http = new HTTPClientMock<ITestAPI>()
|
||||||
const actions = createCRUDActions(
|
const actions = createCRUDActions(
|
||||||
http,
|
http,
|
||||||
'/one/:oneId/two',
|
|
||||||
'/one/:oneId/two/:twoId',
|
'/one/:oneId/two/:twoId',
|
||||||
|
'/one/:oneId/two',
|
||||||
'TEST',
|
'TEST',
|
||||||
)
|
)
|
||||||
const crudReducer = new CRUDReducer<ITwo, 'TEST'>('TEST')
|
const crudReducer = new CRUDReducer<ITwo, 'TEST'>('TEST')
|
||||||
@ -249,7 +249,6 @@ describe('CRUD', () => {
|
|||||||
|
|
||||||
it('updates state', async () => {
|
it('updates state', async () => {
|
||||||
const action = dispatch(testCase.method, actions[method]({
|
const action = dispatch(testCase.method, actions[method]({
|
||||||
query: undefined,
|
|
||||||
params: testCase.params,
|
params: testCase.params,
|
||||||
body: testCase.body,
|
body: testCase.body,
|
||||||
}))
|
}))
|
||||||
@ -300,7 +299,6 @@ describe('CRUD', () => {
|
|||||||
expect(store.getState().Crud.ids).toEqual([entity.id])
|
expect(store.getState().Crud.ids).toEqual([entity.id])
|
||||||
const action2 = store.dispatch(actions.remove({
|
const action2 = store.dispatch(actions.remove({
|
||||||
params: removeTestCase.params,
|
params: removeTestCase.params,
|
||||||
body: removeTestCase.body,
|
|
||||||
}))
|
}))
|
||||||
await action2.payload
|
await action2.payload
|
||||||
expect(store.getState().Crud.ids).toEqual([])
|
expect(store.getState().Crud.ids).toEqual([])
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import {ICRUDAction} from './ICRUDAction'
|
import {ICRUDAction} from './ICRUDAction'
|
||||||
import {ICRUDMethod} from './ICRUDMethod'
|
import {ICRUDMethod} from './ICRUDMethod'
|
||||||
import {IHTTPClient, ITypedRequestParams} from '../http'
|
import {IHTTPClient, ITypedRequestParams} from '../http'
|
||||||
import {IRoutes} from '@rondo/common'
|
import {IRoutes, Filter, OnlyDefined} from '@rondo/common'
|
||||||
|
|
||||||
export type Optional<T> = T extends {} ? T : undefined
|
export type Optional<T> = T extends {} ? T : undefined
|
||||||
|
|
||||||
type Filter<T, U> = T extends U ? T : never
|
|
||||||
|
|
||||||
type Action<T, ActionType extends string, Method extends ICRUDMethod> =
|
type Action<T, ActionType extends string, Method extends ICRUDMethod> =
|
||||||
Filter<ICRUDAction<T, ActionType>, {method: Method, status: 'pending'}>
|
Filter<ICRUDAction<T, ActionType>, {method: Method, status: 'pending'}>
|
||||||
|
|
||||||
@ -22,12 +20,13 @@ export class SaveActionCreator<
|
|||||||
readonly type: ActionType,
|
readonly type: ActionType,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
save = (params: {
|
save = (params: OnlyDefined<{
|
||||||
body: T[Route]['post']['body'],
|
body: T[Route]['post']['body'],
|
||||||
params: T[Route]['post']['params'],
|
params: T[Route]['post']['params'],
|
||||||
}): Action<T[Route]['post']['response'], ActionType, 'save'> => {
|
}>): Action<T[Route]['post']['response'], ActionType, 'save'> => {
|
||||||
|
const p = params as any
|
||||||
return {
|
return {
|
||||||
payload: this.http.post(this.route, params.body, params.params),
|
payload: this.http.post(this.route, p.body, p.params),
|
||||||
type: this.type,
|
type: this.type,
|
||||||
method: 'save',
|
method: 'save',
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
@ -47,12 +46,13 @@ export class FindOneActionCreator<
|
|||||||
readonly type: ActionType,
|
readonly type: ActionType,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
findOne = (params: {
|
findOne = (params: OnlyDefined<{
|
||||||
query: Optional<T[Route]['get']['query']>,
|
query: Optional<T[Route]['get']['query']>,
|
||||||
params: T[Route]['get']['params'],
|
params: T[Route]['get']['params'],
|
||||||
}): Action<T[Route]['get']['response'], ActionType, 'findOne'> => {
|
}>): Action<T[Route]['get']['response'], ActionType, 'findOne'> => {
|
||||||
|
const p = params as any
|
||||||
return {
|
return {
|
||||||
payload: this.http.get(this.route, params.query, params.params),
|
payload: this.http.get(this.route, p.query, p.params),
|
||||||
type: this.type,
|
type: this.type,
|
||||||
method: 'findOne',
|
method: 'findOne',
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
@ -73,12 +73,13 @@ export class UpdateActionCreator<
|
|||||||
readonly type: ActionType,
|
readonly type: ActionType,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
update = (params: {
|
update = (params: OnlyDefined<{
|
||||||
body: T[Route]['put']['body'],
|
body: T[Route]['put']['body'],
|
||||||
params: T[Route]['put']['params'],
|
params: T[Route]['put']['params'],
|
||||||
}): Action<T[Route]['put']['response'], ActionType, 'update'> => {
|
}>): Action<T[Route]['put']['response'], ActionType, 'update'> => {
|
||||||
|
const p = params as any
|
||||||
return {
|
return {
|
||||||
payload: this.http.put(this.route, params.body, params.params),
|
payload: this.http.put(this.route, p.body, p.params),
|
||||||
type: this.type,
|
type: this.type,
|
||||||
method: 'update',
|
method: 'update',
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
@ -99,12 +100,13 @@ export class RemoveActionCreator<
|
|||||||
readonly type: ActionType,
|
readonly type: ActionType,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
remove = (params: {
|
remove = (params: OnlyDefined<{
|
||||||
body: T[Route]['delete']['body'],
|
body: Optional<T[Route]['delete']['body']>,
|
||||||
params: T[Route]['delete']['params'],
|
params: T[Route]['delete']['params'],
|
||||||
}): Action<T[Route]['delete']['response'], ActionType, 'remove'> => {
|
}>): Action<T[Route]['delete']['response'], ActionType, 'remove'> => {
|
||||||
|
const p = params as any
|
||||||
return {
|
return {
|
||||||
payload: this.http.delete(this.route, params.body, params.params),
|
payload: this.http.delete(this.route, p.body, p.params),
|
||||||
type: this.type,
|
type: this.type,
|
||||||
method: 'remove',
|
method: 'remove',
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
@ -124,12 +126,18 @@ export class FindManyActionCreator<
|
|||||||
readonly type: ActionType,
|
readonly type: ActionType,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
findMany = (params: {
|
findMany = (params: OnlyDefined<{
|
||||||
query: Optional<T[Route]['get']['query']>,
|
query: Optional<T[Route]['get']['query']>,
|
||||||
params: T[Route]['get']['params'],
|
params: T[Route]['get']['params'],
|
||||||
}): Action<T[Route]['get']['response'], ActionType, 'findMany'> => {
|
}>): {
|
||||||
|
payload: Promise<T[Route]['get']['response']>
|
||||||
|
type: ActionType
|
||||||
|
status: 'pending',
|
||||||
|
method: 'findMany',
|
||||||
|
} => {
|
||||||
|
const p = params as any
|
||||||
return {
|
return {
|
||||||
payload: this.http.get(this.route, params.query, params.params),
|
payload: this.http.get(this.route, p.query, p.params),
|
||||||
type: this.type,
|
type: this.type,
|
||||||
method: 'findMany',
|
method: 'findMany',
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
@ -149,11 +157,11 @@ export function createCRUDActions<
|
|||||||
listRoute: ListRoute,
|
listRoute: ListRoute,
|
||||||
actionType: ActionType,
|
actionType: ActionType,
|
||||||
) {
|
) {
|
||||||
const {save} = new SaveActionCreator(http, entityRoute, actionType)
|
const {save} = new SaveActionCreator(http, listRoute, actionType)
|
||||||
const {update} = new UpdateActionCreator(http, listRoute, actionType)
|
const {update} = new UpdateActionCreator(http, entityRoute, actionType)
|
||||||
const {remove} = new RemoveActionCreator(http, listRoute, actionType)
|
const {remove} = new RemoveActionCreator(http, entityRoute, actionType)
|
||||||
const {findOne} = new FindOneActionCreator(http, listRoute, actionType)
|
const {findOne} = new FindOneActionCreator(http, entityRoute, actionType)
|
||||||
const {findMany} = new FindManyActionCreator(http, entityRoute, actionType)
|
const {findMany} = new FindManyActionCreator(http, listRoute, actionType)
|
||||||
|
|
||||||
return {save, update, remove, findOne, findMany}
|
return {save, update, remove, findOne, findMany}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
import {IAction, IResolvedAction} from '../actions'
|
import {IAction, IResolvedAction} from '../actions'
|
||||||
import {ICRUDAction} from './ICRUDAction'
|
import {ICRUDAction} from './ICRUDAction'
|
||||||
import {ICRUDMethod} from './ICRUDMethod'
|
import {ICRUDMethod} from './ICRUDMethod'
|
||||||
import {indexBy, without} from '@rondo/common'
|
import {indexBy, without, Filter} from '@rondo/common'
|
||||||
|
|
||||||
type Filter<T, U> = T extends U ? T : never
|
|
||||||
|
|
||||||
export interface ICRUDEntity {
|
export interface ICRUDEntity {
|
||||||
readonly id: number
|
readonly id: number
|
||||||
|
|||||||
31
packages/client/src/crud/jerko.ts
Normal file
31
packages/client/src/crud/jerko.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
export type NonUndefinedPropertyNames<T> = {
|
||||||
|
[K in keyof T]: T[K] extends undefined ? never: K
|
||||||
|
}[keyof T]
|
||||||
|
|
||||||
|
export type OnlyRequired<T> = Pick<T, NonUndefinedPropertyNames<T>>
|
||||||
|
|
||||||
|
type Args1 = OnlyRequired<{
|
||||||
|
query: {a: number, b: string}
|
||||||
|
params: {c: number}
|
||||||
|
}>
|
||||||
|
|
||||||
|
type Args2 = OnlyRequired<{
|
||||||
|
query: {a: number, b: string}
|
||||||
|
params: undefined
|
||||||
|
}>
|
||||||
|
|
||||||
|
type Args3 = OnlyRequired<{
|
||||||
|
query: undefined
|
||||||
|
params: undefined
|
||||||
|
}>
|
||||||
|
|
||||||
|
const a: Args1 = {
|
||||||
|
query: {a: 1, b: 'two'},
|
||||||
|
params: {c: 3},
|
||||||
|
}
|
||||||
|
|
||||||
|
const b: Args2 = {
|
||||||
|
query: {a: 1, b: 'two'},
|
||||||
|
}
|
||||||
|
|
||||||
|
const c: Args3 = {}
|
||||||
Loading…
x
Reference in New Issue
Block a user