Fix linting errors in packages/jsonrpc

This commit is contained in:
Jerko Steiner 2019-09-15 17:14:31 +07:00
parent 8853c71a0d
commit 50d36f268f
21 changed files with 184 additions and 177 deletions

View File

@ -11,6 +11,10 @@ rules:
- warn
- code: 80
ignorePattern: '^import .* from '
comma-dangle:
- warn
- always-multiline
# semi:
# - warn
# - never

View File

@ -0,0 +1,8 @@
extends:
- ../../.eslintrc.yaml
rules:
# due to the nature of this project, writing code becomes much easier
# when any can be used in some places
'@typescript-eslint/no-explicit-any': off
prefer-rest-params: off
prefer-spread: off

View File

@ -8,30 +8,30 @@ import {json} from 'body-parser'
describe('util', () => {
interface IS1 {
interface S1 {
add(a: number, b: number): number
}
interface IS2 {
interface S2 {
mul(a: number, b: number): number
concat(...str: string[]): string
}
interface IContext {
interface Context {
userId: number
}
class Service1 implements WithContext<IS1, IContext> {
add(cx: IContext, a: number, b: number) {
class Service1 implements WithContext<S1, Context> {
add(cx: Context, a: number, b: number) {
return a + b + cx.userId
}
}
class Service2 implements WithContext<IS2, IContext> {
mul(cx: IContext, a: number, b: number) {
class Service2 implements WithContext<S2, Context> {
mul(cx: Context, a: number, b: number) {
return a * b + cx.userId
}
concat(cx: IContext, ...str: string[]) {
concat(cx: Context, ...str: string[]) {
return str.join('') + cx.userId
}
}
@ -98,7 +98,7 @@ describe('util', () => {
services,
)
const app = createApp(router)
const client = createClient<IS1>(app, '/rpc/s1')
const client = createClient<S1>(app, '/rpc/s1')
const result: number = await client.add(1, 3)
expect(result).toBe(14)
})

View File

@ -1,4 +1,5 @@
import {IJSONRPCReturnType} from './express'
/* eslint @typescript-eslint/no-explicit-any: off */
import {RPCReturnType} from './express'
import {WithContext, RPCClient, RPCActions} from './types'
import {createActions} from './redux'
import {createLocalClient, LocalClient} from './local'
@ -39,7 +40,7 @@ export function bulkCreateActions<T extends Record<string, RPCClient<any>>>(
}
export function bulkjsonrpc<T>(
jsonrpc: IJSONRPCReturnType,
jsonrpc: RPCReturnType,
services: T,
) {
keys(services).forEach(key => {

View File

@ -2,13 +2,13 @@ import createClientMock from './createClientMock'
describe('createClientMock', () => {
interface IService {
interface Service {
add(a: number, b: number): number
concat(a: string, b: string): string
}
it('creates a mock for all methods', async () => {
const [client, mock] = createClientMock<IService>(['add', 'concat'])
const [client, mock] = createClientMock<Service>(['add', 'concat'])
mock.add.mockReturnValue(Promise.resolve(3))
mock.concat.mockImplementation((a, b) => Promise.resolve(a + b))
expect(await client.add(4, 5)).toBe(3)

View File

@ -1,6 +1,6 @@
import { FunctionPropertyNames, RPCClient } from './types'
export type TMocked<T> = {
export type RPCClientMock<T> = {
[K in keyof T]:
T[K] extends (...args: infer A) => infer R
? jest.Mock<R, A>
@ -20,7 +20,7 @@ export type TMocked<T> = {
*/
export default function createClientMock<T extends object>(
methods: Array<FunctionPropertyNames<T>>,
): [RPCClient<T>, TMocked<RPCClient<T>>] {
): [RPCClient<T>, RPCClientMock<RPCClient<T>>] {
const client = methods
.reduce((obj, prop) => {
obj[prop] = jest.fn()
@ -29,6 +29,6 @@ export default function createClientMock<T extends object>(
return [
client as RPCClient<T>,
client as TMocked<RPCClient<T>>,
client as RPCClientMock<RPCClient<T>>,
]
}

View File

@ -7,15 +7,15 @@ import {
describe('ensure', () => {
interface IContext {
interface Context {
userId: number
}
const validate: Validate<IContext> = c => c.userId > 0
const validate: Validate<Context> = c => c.userId > 0
it('decorates class methods', () => {
class Service {
@ensure<IContext>(validate)
@ensure<Context>(validate)
fetchData() {
return 1
}
@ -32,7 +32,7 @@ describe('ensure', () => {
it('works with properties/instance method definitions', () => {
class Service {
@ensure<IContext>(validate)
@ensure<Context>(validate)
fetchData = () => 1
}
const s = new Service()

View File

@ -1,3 +1,4 @@
/* eslint @typescript-eslint/no-unused-vars: 0 */
import 'reflect-metadata'
export const ensureKey = Symbol('ensure')
@ -7,10 +8,11 @@ export type Validate<Context> = (context: Context) => boolean | Promise<boolean>
export function ensure<Context>(
validate: Validate<Context>,
message: string = 'Validation failed',
message = 'Validation failed',
) {
return function ensureImpl(
target: any, key?: string, descriptor?: PropertyDescriptor) {
target: any, key?: string, descriptor?: PropertyDescriptor,
) {
switch (arguments.length) {
case 1:
return ensureClass(validate, message).apply(null, arguments as any)
@ -25,7 +27,7 @@ export function ensure<Context>(
function ensureClass<Context>(
validate: Validate<Context>,
message: string = 'Validation failed',
message = 'Validation failed',
) {
// tslint:disable-next-line
return (target: any) => {
@ -40,7 +42,7 @@ function ensureClass<Context>(
function ensureMethod<Context>(
validate: Validate<Context>,
message: string = 'Validation failed',
message = 'Validation failed',
) {
return (
target: any,

View File

@ -1,44 +1,44 @@
export interface IError {
export interface ErrorWithCode {
code: number
message: string
}
export interface IErrorWithData<T> extends IError {
export interface ErrorWithData<T> extends ErrorWithCode {
data: T
}
export interface IErrorResponse<T> {
export interface ErrorResponse<T> {
jsonrpc: '2.0'
id: string | number | null
result: null
error: IErrorWithData<T>
error: ErrorWithData<T>
}
export interface IJSONRPCError<T> extends Error {
export interface RPCError<T> extends Error {
code: number
statusCode: number
response: IErrorResponse<T>
response: ErrorResponse<T>
}
export function isJSONRPCError(err: any): err is IJSONRPCError<unknown> {
return err.name === 'IJSONRPCError' &&
export function isRPCError(err: any): err is RPCError<unknown> {
return err.name === 'RPCError' &&
typeof err.message === 'string' &&
err.hasOwnProperty('code') &&
err.hasOwnProperty('response')
Object.prototype.hasOwnProperty.call(err, 'code') &&
Object.prototype.hasOwnProperty.call(err, 'response')
}
export function createError<T = null>(
error: IError,
error: ErrorWithCode,
info: {
id: number | string | null
data: T
statusCode: number
},
): IJSONRPCError<T> {
): RPCError<T> {
const err = new Error(error.message) as IJSONRPCError<T>
const err = new Error(error.message) as RPCError<T>
err.name = 'IJSONRPCError'
err.name = 'RPCError'
err.code = error.code
err.statusCode = info.statusCode
err.response = {

View File

@ -1,7 +1,7 @@
import bodyParser from 'body-parser'
import express from 'express'
import request from 'supertest'
import {IRequest} from './jsonrpc'
import {Request} from './jsonrpc'
import {createClient} from './supertest'
import {ensure} from './ensure'
import {jsonrpc} from './express'
@ -10,11 +10,11 @@ import {WithContext} from './types'
describe('jsonrpc', () => {
interface IContext {
interface Context {
userId: number
}
interface IService {
interface Service {
add(a: number, b: number): number
delay(): Promise<void>
syncError(message: string): void
@ -25,11 +25,11 @@ describe('jsonrpc', () => {
addWithContext2(a: number, b: number): Promise<number>
}
const ensureLoggedIn = ensure<IContext>(c => !!c.userId)
const ensureLoggedIn = ensure<Context>(c => !!c.userId)
class Service implements WithContext<IService, IContext> {
class MyService implements WithContext<Service, Context> {
constructor(readonly time: number) {}
add(context: IContext, a: number, b: number) {
add(context: Context, a: number, b: number) {
return a + b
}
multiply(...numbers: number[]) {
@ -40,13 +40,13 @@ describe('jsonrpc', () => {
setTimeout(resolve, this.time)
})
}
syncError(context: IContext, message: string) {
syncError(context: Context, message: string) {
throw new Error(message)
}
async asyncError(context: IContext, message: string) {
async asyncError(context: Context, message: string) {
throw new Error(message)
}
async httpError(context: IContext, statusCode: number, message: string) {
async httpError(context: Context, statusCode: number, message: string) {
const err: any = new Error(message)
err.statusCode = statusCode
err.errors = [{
@ -54,14 +54,14 @@ describe('jsonrpc', () => {
}]
throw err
}
addWithContext = (ctx: IContext, a: number, b: number) => {
addWithContext = (ctx: Context, a: number, b: number) => {
return a + b + ctx.userId
}
_private = () => {
return 1
}
@ensureLoggedIn
addWithContext2(ctx: IContext, a: number, b: number) {
addWithContext2(ctx: Context, a: number, b: number) {
return Promise.resolve(a + b + ctx!.userId)
}
}
@ -72,8 +72,8 @@ describe('jsonrpc', () => {
const app = express()
app.use(bodyParser.json())
app.use('/',
jsonrpc(req => ({userId}), noopLogger)
.addService('/myService', new Service(5), [
jsonrpc(() => ({userId}), noopLogger)
.addService('/myService', new MyService(5), [
'add',
'delay',
'syncError',
@ -87,7 +87,7 @@ describe('jsonrpc', () => {
return app
}
const client = createClient<IService>(createApp(), '/myService')
const client = createClient<Service>(createApp(), '/myService')
async function getError(promise: Promise<unknown>) {
let error
@ -260,7 +260,7 @@ describe('jsonrpc', () => {
describe('hook', () => {
let requests: IRequest[] = []
let requests: Request[] = []
let results: any[] = []
function create() {
requests = []
@ -268,12 +268,12 @@ describe('jsonrpc', () => {
userId = 1000
const app = express()
const myService = new Service(5)
const myService = new MyService(5)
// console.log('service', myService, Object.
app.use(bodyParser.json())
app.use('/',
jsonrpc(
req => Promise.resolve({userId}),
() => Promise.resolve({userId}),
noopLogger,
async (details, makeRequest) => {
requests.push(details.request)

View File

@ -1,35 +1,29 @@
import express, {ErrorRequestHandler} from 'express'
import {FunctionPropertyNames} from './types'
import {IDEMPOTENT_METHOD_REGEX} from './idempotent'
import {IErrorResponse} from './error'
import {ILogger} from '@rondo.dev/logger'
import {ISuccessResponse} from './jsonrpc'
import {NextFunction, Request, Response, Router} from 'express'
import {createError, isJSONRPCError, IJSONRPCError, IError} from './error'
import {
createRpcService, ERROR_SERVER, ERROR_INVALID_PARAMS, ERROR_METHOD_NOT_FOUND,
IRequest,
} from './jsonrpc'
import { Logger } from '@rondo.dev/logger'
import express, { ErrorRequestHandler, Request, Response, Router } from 'express'
import { createError, ErrorResponse, isRPCError } from './error'
import { IDEMPOTENT_METHOD_REGEX } from './idempotent'
import { createRpcService, ERROR_METHOD_NOT_FOUND, ERROR_SERVER, IRequest, SuccessResponse } from './jsonrpc'
import { FunctionPropertyNames } from './types'
export type TGetContext<Context> = (req: Request) => Promise<Context> | Context
export interface IJSONRPCReturnType {
export interface RPCReturnType {
addService<T, F extends FunctionPropertyNames<T>>(
path: string,
service: T,
methods?: F[],
): IJSONRPCReturnType,
): RPCReturnType
router(): Router
}
export interface IInvocationDetails<A extends IRequest, Context> {
export interface InvocationDetails<A extends IRequest, Context> {
context: Context
path: string
request: A
}
async function defaultHook<A extends IRequest, R, Context>(
details: IInvocationDetails<A, Context>,
details: InvocationDetails<A, Context>,
invoke: () => Promise<R>,
): Promise<R> {
const result = await invoke()
@ -38,17 +32,18 @@ async function defaultHook<A extends IRequest, R, Context>(
export function jsonrpc<Context>(
getContext: TGetContext<Context>,
logger: ILogger,
logger: Logger,
hook: <A extends IRequest, R>(
details: IInvocationDetails<A, Context>,
details: InvocationDetails<A, Context>,
invoke: (request?: A) => Promise<R>) => Promise<R> = defaultHook,
idempotentMethodRegex = IDEMPOTENT_METHOD_REGEX,
): IJSONRPCReturnType {
): RPCReturnType {
/* eslint @typescript-eslint/no-unused-vars: 0 */
const handleError: ErrorRequestHandler = (err, req, res, next) => {
logger.error('JSON-RPC Error: %s', err.stack)
if (isJSONRPCError(err)) {
if (isRPCError(err)) {
res.status(err.statusCode)
res.json(err.response)
return
@ -56,7 +51,7 @@ export function jsonrpc<Context>(
const id = getRequestId(req)
const statusCode: number = err.statusCode || 500
const errorResponse: IErrorResponse<unknown> = {
const errorResponse: ErrorResponse<unknown> = {
jsonrpc: '2.0',
id,
result: null,
@ -85,7 +80,7 @@ export function jsonrpc<Context>(
const rpcService = createRpcService(service, methods)
function handleResponse(
response: ISuccessResponse<unknown> | null,
response: SuccessResponse<unknown> | null,
res: Response,
) {
if (response === null) {

View File

@ -1,7 +1,7 @@
export type TId = number | string
import {ArgumentTypes, FunctionPropertyNames, RetType} from './types'
import {isPromise} from './isPromise'
import {createError, IErrorResponse, IErrorWithData} from './error'
import {createError, ErrorResponse} from './error'
import {getValidatorsForMethod, getValidatorsForInstance} from './ensure'
import {Validate} from './ensure'
@ -35,8 +35,8 @@ export const ERROR_SERVER = {
message: 'Server error',
}
export function pick<T, K extends FunctionPropertyNames<T>>(t: T, keys: K[])
: Pick<T, K> {
export function pick<T, K extends FunctionPropertyNames<T>>(
t: T, keys: K[]): Pick<T, K> {
return keys.reduce((obj, key) => {
// tslint:disable-next-line
const fn = t[key] as unknown as Function
@ -48,8 +48,8 @@ export function pick<T, K extends FunctionPropertyNames<T>>(t: T, keys: K[])
export function getAllMethods<T>(obj: T): Array<FunctionPropertyNames<T>> {
const props = new Set<string>()
do {
const l = Object.getOwnPropertyNames(obj)
.filter((p, i, arr) => {
Object.getOwnPropertyNames(obj)
.filter(p => {
return typeof (obj as any)[p] === 'function' &&
p.startsWith('_') === false &&
p !== 'constructor'
@ -61,24 +61,25 @@ export function getAllMethods<T>(obj: T): Array<FunctionPropertyNames<T>> {
return Array.from(props) as unknown as Array<FunctionPropertyNames<T>>
}
export interface IRequest<M extends string = any, A = any[]> {
export interface Request<M extends string = any, A = any[]> {
jsonrpc: '2.0'
id: TId | null
method: M
params: A
}
export interface ISuccessResponse<T> {
export interface SuccessResponse<T> {
jsonrpc: '2.0'
id: TId
result: T
error: null
}
export type IResponse<T = any> = ISuccessResponse<T> | IErrorResponse<T>
export type Response<T = any> = SuccessResponse<T> | ErrorResponse<T>
export function createSuccessResponse<T>(id: number | string, result: T)
: ISuccessResponse<T> {
export function createSuccessResponse<T>(
id: number | string, result: T
): SuccessResponse<T> {
return {
jsonrpc: '2.0',
id,
@ -125,9 +126,9 @@ export const createRpcService = <T, M extends FunctionPropertyNames<T>>(
pick(service, getAllMethods(service))
return {
async invoke<Context>(
req: IRequest<M, ArgumentTypes<T[M]>>,
req: Request<M, ArgumentTypes<T[M]>>,
context: Context,
): Promise<ISuccessResponse<RetType<T[M]>> | null> {
): Promise<SuccessResponse<RetType<T[M]>> | null> {
const {id, method, params} = req
if (
@ -145,7 +146,7 @@ export const createRpcService = <T, M extends FunctionPropertyNames<T>>(
const isNotification = req.id === null || req.id === undefined
if (
!rpcService.hasOwnProperty(method) ||
!Object.prototype.hasOwnProperty.call(rpcService, method) ||
typeof rpcService[method] !== 'function'
) {
throw createError(ERROR_METHOD_NOT_FOUND, {

View File

@ -1,29 +1,27 @@
import {createLocalClient} from './local'
import {keys} from 'ts-transformer-keys'
import {WithContext, WithoutContext, RPCClient} from './types'
import { createLocalClient } from './local'
import { WithContext } from './types'
describe('local', () => {
interface IService {
interface Service {
add(a: number, b: number): number
addWithContext(a: number, b: number): number
}
const IServiceKeys = keys<IService>()
interface IContext {
interface Context {
userId: 1000
}
class Service implements WithContext<IService, IContext> {
add(cx: IContext, a: number, b: number) {
class MyService implements WithContext<Service, Context> {
add(cx: Context, a: number, b: number) {
return a + b
}
addWithContext = (cx: IContext, a: number, b: number) => {
addWithContext = (cx: Context, a: number, b: number) => {
return a + b + cx.userId
}
}
const service = new Service()
const service = new MyService()
const proxy = createLocalClient(service, {userId: 1000})

View File

@ -1,7 +1,5 @@
import {RPCClient, WithContext, WithoutContext} from './types'
import {Request} from 'express'
import {TGetContext} from './express'
import {getAllMethods} from './jsonrpc'
import { getAllMethods } from './jsonrpc'
import { RPCClient, WithoutContext } from './types'
export type LocalClient<T> = RPCClient<WithoutContext<T>>

View File

@ -2,22 +2,22 @@
* @jest-environment node
*/
import { createStore } from '@rondo.dev/redux'
import bodyParser from 'body-parser'
import express from 'express'
import {AddressInfo} from 'net'
import {Server} from 'http'
import {WithContext, TPendingActions, TAllActions} from './types'
import {combineReducers} from 'redux'
import {createActions, createReducer} from './redux'
import {createRemoteClient} from './remote'
import {createStore} from '@rondo.dev/redux'
import {jsonrpc} from './express'
import {keys} from 'ts-transformer-keys'
import {noopLogger} from './test-utils'
import { Server } from 'http'
import { AddressInfo } from 'net'
import { combineReducers } from 'redux'
import { keys } from 'ts-transformer-keys'
import { jsonrpc } from './express'
import { createActions, createReducer } from './redux'
import { createRemoteClient } from './remote'
import { noopLogger } from './test-utils'
import { WithContext } from './types'
describe('createActions', () => {
interface IService {
interface Service {
add(a: number, b: number): number
addAsync(a: number, b: number): Promise<number>
addStringsAsync(a: string, b: string): Promise<string>
@ -26,25 +26,25 @@ describe('createActions', () => {
throwError(bool: boolean): boolean
}
interface IContext {
interface Context {
userId: number
}
class Service implements WithContext<IService, IContext> {
add(cx: IContext, a: number, b: number) {
class MyService implements WithContext<Service, Context> {
add(cx: Context, a: number, b: number) {
return a + b
}
addAsync(cx: IContext, a: number, b: number) {
addAsync(cx: Context, a: number, b: number) {
return new Promise<number>(resolve => resolve(a + b))
}
addStringsAsync(cx: IContext, a: string, b: string) {
addStringsAsync(cx: Context, a: string, b: string) {
return new Promise<string>(resolve => resolve(a + b))
}
addWithContext = (cx: IContext, a: number, b: number) =>
addWithContext = (cx: Context, a: number, b: number) =>
a + b + cx.userId
addAsyncWithContext = (cx: IContext, a: number, b: number) =>
addAsyncWithContext = (cx: Context, a: number, b: number) =>
new Promise<number>(resolve => resolve(a + b + cx.userId))
throwError(cx: IContext, bool: boolean) {
throwError(cx: Context, bool: boolean) {
if (bool) {
throw new Error('test')
}
@ -57,7 +57,7 @@ describe('createActions', () => {
app.use(
'/',
jsonrpc(() => ({userId: 1000}), noopLogger)
.addService('/service', new Service(), keys<IService>())
.addService('/service', new MyService(), keys<Service>())
.router(),
)
@ -78,8 +78,8 @@ describe('createActions', () => {
})
function getClient() {
const remoteClient = createRemoteClient<IService>(
baseUrl + '/service', keys<IService>())
const remoteClient = createRemoteClient<Service>(
baseUrl + '/service', keys<Service>())
const client = createActions(remoteClient, 'myService')
const defaultState = {
@ -96,16 +96,14 @@ describe('createActions', () => {
case 'addAsync':
case 'addWithContext':
case 'addAsyncWithContext':
const r1: number = action.payload
return {
...state,
add: r1,
add: action.payload,
}
case 'addStringsAsync':
const r2: string = action.payload
return {
...state,
addStringsAsync: r2,
addStringsAsync: action.payload,
}
default:
return state
@ -139,7 +137,7 @@ describe('createActions', () => {
add: action.payload,
}
},
throwError(state, action) {
throwError(state) {
return state
},
})

View File

@ -1,10 +1,10 @@
import {
IRPCActions,
RPCClient,
RPCActions,
RPCClient,
TResolvedActions,
TAllActions,
RPCReduxHandlers,
RPCActionsRecord,
} from './types'
export function createActions<T, ActionType extends string>(
@ -27,18 +27,19 @@ export function createActions<T, ActionType extends string>(
return service as RPCActions<T, ActionType>
}
export interface IState {
export interface TestState {
loading: number
error: string
}
export function createReducer<ActionType extends string, State extends IState>(
export function createReducer<
ActionType extends string, State extends TestState>(
actionType: ActionType,
defaultState: State,
) {
const self = {
withHandler<R extends IRPCActions<ActionType>>(
withHandler<R extends RPCActionsRecord<ActionType>>(
handleAction: (state: State, action: TResolvedActions<R>) => State,
): (state: State | undefined, action: TAllActions<R>) => State {
return (state: State = defaultState, action: TAllActions<R>): State => {
@ -66,7 +67,7 @@ export function createReducer<ActionType extends string, State extends IState>(
}, action)
}
},
withMapping<R extends IRPCActions<ActionType>>(
withMapping<R extends RPCActionsRecord<ActionType>>(
handlers: RPCReduxHandlers<R, State>,
) {
return self.withHandler<R>((state, action) => {

View File

@ -14,24 +14,25 @@ import {WithContext} from './types'
describe('remote', () => {
interface IService {
interface Service {
add(a: number, b: number): number
fetchItem(obj1: {a: number}, obj2: {b: number})
: Promise<{a: number, b: number}>
fetchItem(
obj1: {a: number}, obj2: {b: number}): Promise<{a: number, b: number}>
}
const IServiceKeys = keys<IService>()
const IServiceKeys = keys<Service>()
class Service implements WithContext<IService, {}> {
class MyService implements WithContext<Service, {}> {
add(ctx: {}, a: number, b: number) {
return a + b
}
async fetchItem(ctx: {}, obj1: {a: number}, obj2: {b: number})
: Promise<{a: number, b: number}> {
async fetchItem(
ctx: {}, obj1: {a: number}, obj2: {b: number}
): Promise<{a: number, b: number}> {
return Promise.resolve({...obj1, ...obj2})
}
}
const service = new Service()
const service = new MyService()
function createApp() {
const a = express()
@ -65,7 +66,7 @@ describe('remote', () => {
describe('idempotent method invocation (GET)', () => {
it('creates a proxy for remote service', async () => {
const rpc = createRemoteClient<IService>(
const rpc = createRemoteClient<Service>(
baseUrl + '/myService', IServiceKeys)
const result = await rpc.fetchItem({a: 10}, {b: 20})
expect(result).toEqual({a: 10, b: 20})
@ -74,7 +75,7 @@ describe('remote', () => {
describe('method invocation (POST)', () => {
it('creates a proxy for remote service', async () => {
const rpc = createRemoteClient<IService>(
const rpc = createRemoteClient<Service>(
baseUrl + '/myService', IServiceKeys)
const result = await rpc.add(3, 7)
expect(result).toBe(3 + 7)

View File

@ -21,7 +21,7 @@ export function createRemoteClient<T>(
method: string,
params: any[],
) {
const reqMethod = IDEMPOTENT_METHOD_REGEX.test(method) ? 'GET' : 'POST'
const reqMethod = idempotentMethodRegex.test(method) ? 'GET' : 'POST'
const payloadKey = reqMethod === 'POST' ? 'data' : 'params'
const response = await axios({

View File

@ -1,8 +1,8 @@
import {ILogger} from '@rondo.dev/logger'
import {Logger} from '@rondo.dev/logger'
const noop = () => undefined
export const noopLogger: ILogger = {
export const noopLogger: Logger = {
error: noop,
warn: noop,
info: noop,

View File

@ -1,4 +1,4 @@
import {IPendingAction, IResolvedAction, IRejectedAction} from '@rondo.dev/redux'
import {PendingAction, ResolvedAction, RejectedAction} from '@rondo.dev/redux'
export type ArgumentTypes<T> =
T extends (...args: infer U) => infer R ? U : never
@ -38,64 +38,64 @@ export type RPCClient<T> = {
[K in keyof T]: PromisifyReturnType<T[K]>
}
export interface IRPCActions<ActionType extends string> {
[key: string]: (...a: any[]) => IRPCPendingAction<any, ActionType, typeof key>
export interface RPCActionsRecord<ActionType extends string> {
[key: string]: (...a: any[]) => RPCPendingAction<any, ActionType, typeof key>
}
export type RPCActions<T, ActionType extends string> = {
[K in keyof T]: (...a: ArgumentTypes<T[K]>) =>
IRPCPendingAction<UnwrapPromise<RetType<T[K]>>, ActionType, K>
RPCPendingAction<UnwrapPromise<RetType<T[K]>>, ActionType, K>
}
export type RPCReduxHandlers<T, State> = {
[K in keyof T]: (
state: State,
action: TResolved<TPending<RetType<T[K]>>>,
action: GetResolvedAction<GetPendingAction<RetType<T[K]>>>,
) => Partial<State>
}
export interface IRPCPendingAction<
export interface RPCPendingAction<
T, ActionType extends string, Method extends string | number | symbol
> extends IPendingAction<T, ActionType> {
> extends PendingAction<T, ActionType> {
method: Method
}
export interface IRPCResolvedAction<
export interface RPCResolvedAction<
T, ActionType extends string, Method extends string | symbol | number
> extends IResolvedAction<T, ActionType> {
> extends ResolvedAction<T, ActionType> {
method: Method
}
export interface IRPCRejectedAction<
export interface RPCRejectedAction<
ActionType extends string, Method extends string | symbol | number
> extends IRejectedAction<ActionType> {
> extends RejectedAction<ActionType> {
method: Method
}
export type TRPCAction<
T, ActionType extends string, Method extends string | number | symbol
> =
IRPCPendingAction<T, ActionType, Method>
| IRPCResolvedAction<T, ActionType, Method>
| IRPCRejectedAction<ActionType, Method>
RPCPendingAction<T, ActionType, Method>
| RPCResolvedAction<T, ActionType, Method>
| RPCRejectedAction<ActionType, Method>
export type TResolved<A> =
A extends IRPCPendingAction<infer T, infer ActionType, infer Method>
? IRPCResolvedAction<T, ActionType, Method>
export type GetResolvedAction<A> =
A extends RPCPendingAction<infer T, infer ActionType, infer Method>
? RPCResolvedAction<T, ActionType, Method>
: never
export type TRejected<A> =
A extends IRPCPendingAction<infer T, infer ActionType, infer Method>
? IRPCRejectedAction<ActionType, Method>
export type GetRejectedAction<A> =
A extends RPCPendingAction<infer T, infer ActionType, infer Method>
? RPCRejectedAction<ActionType, Method>
: never
export type TPending<A> =
A extends IRPCPendingAction<infer T, infer ActionType, infer Method>
? IRPCPendingAction<T, ActionType, Method>
export type GetPendingAction<A> =
A extends RPCPendingAction<infer T, infer ActionType, infer Method>
? RPCPendingAction<T, ActionType, Method>
: never
type Values<T> = T[keyof T]
export type TPendingActions<T> = TPending<RetType<Values<T>>>
export type TResolvedActions<T> = TResolved<TPendingActions<T>>
export type TPendingActions<T> = GetPendingAction<RetType<Values<T>>>
export type TResolvedActions<T> = GetResolvedAction<TPendingActions<T>>
export type TAllActions<T> = TPendingActions<T>
| TResolvedActions<T> | TRejected<TPendingActions<T>>
| TResolvedActions<T> | GetRejectedAction<TPendingActions<T>>

View File

@ -1,4 +1,4 @@
import {PendingAction} from './IPendingAction'
import {PendingAction} from './PendingAction'
export function createPendingAction<T, ActionType extends string>(
payload: Promise<T>,