Add Contextual<Service, Context> type
As seen in TeamService2.ts, the Contextual type will add Context as the last argument to any method of the interface, as long as the method has 0-4 arguments. Interfaces with more than 4 arguments cannot use this type, but they could be converted to interfaces which use 1 argument (object/dictionary) only. Some long-term thinking: Maybe only methods with a single argument should be supported, similar to the way gRPC does it.
This commit is contained in:
parent
cc2f5f58e2
commit
19565563cc
@ -24,24 +24,24 @@ export interface IContext {
|
||||
userId: number
|
||||
}
|
||||
|
||||
type Contextual<T> = (context: IContext) => Promise<T>
|
||||
|
||||
export interface ITeamService {
|
||||
create(params: ITeamCreateParams): Contextual<ITeam>
|
||||
jerko(params: string): number
|
||||
|
||||
remove(params: ITeamRemoveParams): Contextual<{id: number}>
|
||||
create(params: ITeamCreateParams): Promise<ITeam>
|
||||
|
||||
update(params: ITeamUpdateParams): Contextual<ITeam>
|
||||
remove(params: ITeamRemoveParams): Promise<{id: number}>
|
||||
|
||||
addUser(params: ITeamAddUserParams): Contextual<IUserInTeam>
|
||||
update(params: ITeamUpdateParams): Promise<ITeam>
|
||||
|
||||
removeUser(params: ITeamAddUserParams): Contextual<ITeamAddUserParams>
|
||||
addUser(params: ITeamAddUserParams): Promise<IUserInTeam>
|
||||
|
||||
removeUser(params: ITeamAddUserParams): Promise<ITeamAddUserParams>
|
||||
|
||||
findOne(id: number): Promise<ITeam | undefined>
|
||||
|
||||
find(userId: number): Contextual<ITeam[]>
|
||||
find(): Promise<ITeam[]>
|
||||
|
||||
findUsers(teamId: number): Contextual<IUserInTeam[]>
|
||||
findUsers(teamId: number): Promise<IUserInTeam[]>
|
||||
|
||||
// TODO add other methods
|
||||
}
|
||||
|
||||
@ -9,6 +9,25 @@ type RetProm<T> = T extends Promise<any> ? T : Promise<T>
|
||||
type PromisifyReturnType<T> = (...a: ArgumentTypes<T>) =>
|
||||
RetProm<UnwrapHOC<RetType<T>>>
|
||||
|
||||
/**
|
||||
* Helps implement a service from a service definiton that has a context as a
|
||||
* last argument.
|
||||
*/
|
||||
export type Contextual<T, Cx> = {
|
||||
[K in keyof T]:
|
||||
T[K] extends () => infer R
|
||||
? (cx: Cx) => R :
|
||||
T[K] extends (a: infer A) => infer R
|
||||
? (a: A, cx: Cx) => R :
|
||||
T[K] extends (a: infer A, b: infer B) => infer R
|
||||
? (a: A, b: B, cx: Cx) => R :
|
||||
T[K] extends (a: infer A, b: infer B, c: infer C) => infer R
|
||||
? (a: A, b: B, c: C, cx: Cx) => R :
|
||||
T[K] extends (a: infer A, b: infer B, c: infer C, d: infer D) => infer R
|
||||
? (a: A, b: B, c: C, d: D, cx: Cx) => R :
|
||||
never
|
||||
}
|
||||
|
||||
export type FunctionPropertyNames<T> = {
|
||||
[K in keyof T]: K extends string
|
||||
? T[K] extends (...args: any[]) => any
|
||||
|
||||
@ -8,16 +8,21 @@ import {
|
||||
team as t,
|
||||
IUserInTeam,
|
||||
} from '@rondo/common'
|
||||
import {Contextual} from '@rondo/jsonrpc'
|
||||
|
||||
type IContext = t.IContext
|
||||
|
||||
export class TeamService2 implements t.ITeamService {
|
||||
export class TeamService2 implements Contextual<t.ITeamService, IContext> {
|
||||
constructor(
|
||||
protected readonly db: DB,
|
||||
protected readonly permissions: IUserPermissions,
|
||||
) {}
|
||||
|
||||
create = (params: t.ITeamCreateParams) => async (context: IContext) => {
|
||||
jerko(params: string, context?: IContext): number {
|
||||
return parseInt(params, 10)
|
||||
}
|
||||
|
||||
async create(params: t.ITeamCreateParams, context: IContext) {
|
||||
const {userId} = context
|
||||
const name = trim(params.name)
|
||||
|
||||
@ -36,12 +41,12 @@ export class TeamService2 implements t.ITeamService {
|
||||
userId,
|
||||
// ADMIN role
|
||||
roleId: 1,
|
||||
})(context)
|
||||
}, context)
|
||||
|
||||
return team
|
||||
}
|
||||
|
||||
remove = ({id}: t.ITeamRemoveParams) => async (context: IContext) => {
|
||||
async remove({id}: t.ITeamRemoveParams, context: IContext) {
|
||||
const {userId} = context
|
||||
|
||||
await this.permissions.belongsToTeam({
|
||||
@ -58,7 +63,7 @@ export class TeamService2 implements t.ITeamService {
|
||||
return {id}
|
||||
}
|
||||
|
||||
update = ({id, name}: t.ITeamUpdateParams) => async (context: IContext) => {
|
||||
async update({id, name}: t.ITeamUpdateParams, context: IContext) {
|
||||
await this.permissions.belongsToTeam({
|
||||
teamId: id,
|
||||
userId: context.userId,
|
||||
@ -74,7 +79,7 @@ export class TeamService2 implements t.ITeamService {
|
||||
return (await this.findOne(id))!
|
||||
}
|
||||
|
||||
addUser = (params: t.ITeamAddUserParams) => async (context: IContext) => {
|
||||
async addUser(params: t.ITeamAddUserParams, context: IContext) {
|
||||
const {userId, teamId, roleId} = params
|
||||
await this.db.getRepository(UserTeam)
|
||||
.save({userId, teamId, roleId})
|
||||
@ -90,7 +95,7 @@ export class TeamService2 implements t.ITeamService {
|
||||
return this.mapUserInTeam(userTeam!)
|
||||
}
|
||||
|
||||
removeUser = (params: t.ITeamAddUserParams) => async (context: IContext) => {
|
||||
async removeUser(params: t.ITeamAddUserParams, context: IContext) {
|
||||
const {teamId, userId, roleId} = params
|
||||
|
||||
await this.permissions.belongsToTeam({
|
||||
@ -109,7 +114,8 @@ export class TeamService2 implements t.ITeamService {
|
||||
return this.db.getRepository(Team).findOne(id)
|
||||
}
|
||||
|
||||
find = () => async ({userId}: IContext) => {
|
||||
async find(context: IContext) {
|
||||
const {userId} = context
|
||||
return this.db.getRepository(Team)
|
||||
.createQueryBuilder('team')
|
||||
.select('team')
|
||||
@ -118,7 +124,7 @@ export class TeamService2 implements t.ITeamService {
|
||||
.getMany()
|
||||
}
|
||||
|
||||
findUsers = (teamId: number) => async (context: IContext) => {
|
||||
async findUsers(teamId: number, context: IContext) {
|
||||
await this.permissions.belongsToTeam({
|
||||
teamId,
|
||||
userId: context.userId,
|
||||
|
||||
@ -4,8 +4,7 @@
|
||||
"outDir": "esm"
|
||||
},
|
||||
"references": [
|
||||
{
|
||||
"path": "../common/tsconfig.esm.json"
|
||||
}
|
||||
{"path": "../common/tsconfig.esm.json"},
|
||||
{"path": "../jsonrpc/tsconfig.esm.json"}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
"rootDir": "src"
|
||||
},
|
||||
"references": [
|
||||
{"path": "../common"}
|
||||
{"path": "../common"},
|
||||
{"path": "../jsonrpc"}
|
||||
]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user