Skip to content

Commit

Permalink
chore: refactor create verical router
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyxiao committed Nov 8, 2023
1 parent 8f330e2 commit 6c38c13
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 81 deletions.
48 changes: 20 additions & 28 deletions packages/cdk-core/verticals/accounting.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import type {MaybePromise} from '@usevenice/util'
import {z} from '@usevenice/util'
import {objectEntries, R, z} from '@usevenice/util'

import type {IntegrationSchemas, IntHelpers} from '../integration.types'
import type {
PaginatedOutput,
Pagination,
VerticalRouterOpts,
} from './new-mapper'
import {paginatedOutput, proxyListRemote, zPaginationParams} from './new-mapper'
import {
paginatedOutput,
proxyListRemoteRedux,
zPaginationParams,
} from './new-mapper'

export const zAccounting = {
account: z.object({
Expand Down Expand Up @@ -61,32 +65,20 @@ export interface AccountingMethods<
// Guess it means accounting router also belongs in the engine backend...

export function createAccountingRouter(opts: VerticalRouterOpts) {
const vertical = 'accounting'
// We cannot use a single trpc procedure because neither openAPI nor trpc
// supports switching output shape that depends on input
return opts.trpc.router({
listAccounts: opts.remoteProcedure
.meta({
openapi: {method: 'GET', path: '/accounting/accounts'},
response: {vertical: 'accounting', entity: 'account', type: 'list'},
})
.input(zPaginationParams.nullish())
.output(paginatedOutput(zAccounting.account))
.query(proxyListRemote),
listExpenses: opts.remoteProcedure
.meta({
openapi: {method: 'GET', path: '/accounting/expenses'},
response: {vertical: 'accounting', entity: 'expense', type: 'list'},
})
.input(zPaginationParams.nullish())
.output(paginatedOutput(zAccounting.expense))
.query(proxyListRemote),
listVendors: opts.remoteProcedure
.meta({
openapi: {method: 'GET', path: '/accounting/vendors'},
response: {vertical: 'accounting', entity: 'vendor', type: 'list'},
})
.input(zPaginationParams.nullish())
.output(paginatedOutput(zAccounting.vendor))
.query(proxyListRemote),
})

return opts.trpc.router(
R.mapToObj(objectEntries(zAccounting), ([entityName, v]) => [
`${vertical}_${entityName}_list`,
opts.remoteProcedure
.meta({openapi: {method: 'GET', path: `/${vertical}/${entityName}`}})
.input(zPaginationParams.nullish())
.output(paginatedOutput(v))
.query(async ({input, ctx}) =>
proxyListRemoteRedux({input, ctx, meta: {entityName, vertical}}),
),
]),
)
}
58 changes: 25 additions & 33 deletions packages/cdk-core/verticals/investment.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import type {MaybePromise} from '@usevenice/util'
import {z} from '@usevenice/util'
import {objectEntries, z} from '@usevenice/util'
// This is unfortunately quite duplicated...
// Guess it means accounting router also belongs in the engine backend...
import {R} from '@usevenice/util'

import type {IntegrationSchemas, IntHelpers} from '../integration.types'
import type {
PaginatedOutput,
Pagination,
VerticalRouterOpts,
} from './new-mapper'
import {paginatedOutput, proxyListRemote, zPaginationParams} from './new-mapper'
import {
paginatedOutput,
proxyListRemoteRedux,
zPaginationParams,
} from './new-mapper'

export const zInvestment = {
account: z.object({
Expand Down Expand Up @@ -50,36 +57,21 @@ export interface InvestmentMethods<
) => MaybePromise<T['_verticals']['investment'][TType] | null>
}

// This is unfortunately quite duplicated...
// Guess it means accounting router also belongs in the engine backend...

export function createInvestmentRouter(opts: VerticalRouterOpts) {
// We cannot use a single trpc procedure because neither openAPI nor trpc
// supports switching output shape that depends on input
return opts.trpc.router({
listAccounts: opts.remoteProcedure
.meta({
openapi: {method: 'GET', path: '/investment/accounts'},
response: {vertical: 'investment', entity: 'account', type: 'list'},
})
.input(zPaginationParams.nullish())
.output(paginatedOutput(zInvestment.account))
.query(proxyListRemote),
listHoldings: opts.remoteProcedure
.meta({
openapi: {method: 'GET', path: '/investment/holdings'},
response: {vertical: 'investment', entity: 'holding', type: 'list'},
})
.input(zPaginationParams.nullish())
.output(paginatedOutput(zInvestment.holding))
.query(proxyListRemote),
listTransactions: opts.remoteProcedure
.meta({
openapi: {method: 'GET', path: '/investment/transactions'},
response: {vertical: 'investment', entity: 'transaction', type: 'list'},
})
.input(zPaginationParams.nullish())
.output(paginatedOutput(zInvestment.transaction))
.query(proxyListRemote),
})
const vertical = 'investment'

return opts.trpc.router(
R.mapToObj(objectEntries(zInvestment), ([entityName, v]) => [
`${vertical}_${entityName}_list`,
opts.remoteProcedure
.meta({openapi: {method: 'GET', path: `/${vertical}/${entityName}`}})
.input(zPaginationParams.nullish())
.output(paginatedOutput(v))
.query(async ({input, ctx}) =>
proxyListRemoteRedux({input, ctx, meta: {entityName, vertical}}),
),
]),
// We cannot use a single trpc procedure because neither openAPI nor trpc
// supports switching output shape that depends on input
)
}
41 changes: 21 additions & 20 deletions packages/cdk-core/verticals/new-mapper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import type {
AnyProcedure,
Expand All @@ -18,7 +17,6 @@ import {z} from '@usevenice/util'
import type {
remoteProcedure,
RemoteProcedureContext,
RouterMeta,
trpc,
} from '../../engine-backend/router/_base'

Expand All @@ -37,19 +35,21 @@ export interface VerticalRouterOpts {
remoteProcedure: typeof remoteProcedure
}

export async function proxyListRemote(opts: {
export async function proxyListRemoteRedux({
input,
ctx,
meta: {entityName, vertical},
}: {
input: unknown
ctx: RemoteProcedureContext
meta: {vertical: string; entityName: string}
}) {
const meta = (opts as any).meta as RouterMeta

const {input, ctx} = opts
const instance = ctx.remote.provider.newInstance?.({
config: ctx.remote.config,
settings: ctx.remote.settings,
})
const implementation = (
ctx.remote.provider.verticals?.[meta.response?.vertical!] as any
ctx.remote.provider.verticals?.[vertical as never] as any
)?.list as Function
if (typeof implementation !== 'function') {
throw new TRPCError({
Expand All @@ -58,22 +58,23 @@ export async function proxyListRemote(opts: {
})
}

const res = await implementation(instance, meta.response?.entity, input)
const res: PaginatedOutput<any> = await implementation(
instance,
entityName,
input,
)

if (meta.response?.type === 'list') {
const mapper = (
ctx.remote.provider.streams?.[meta.response?.vertical] as any
)[meta.response?.entity] as (entity: unknown, settings: unknown) => any
const mapper = (ctx.remote.provider.streams?.[vertical as never] as any)[
entityName
] as (entity: unknown, settings: unknown) => any

return {
...res,
items: (res as PaginatedOutput<any>).items.map((item) => ({
...mapper(item, ctx.remote.settings),
_original: item,
})),
}
return {
...res,
items: res.items.map((item) => ({
...mapper(item, ctx.remote.settings),
_original: item,
})),
}
return res
}

export const zPaginationParams = z.object({
Expand Down

0 comments on commit 6c38c13

Please sign in to comment.