Skip to content

Commit

Permalink
feat(xero): listCategories, sourceSync account and category
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyxiao committed Apr 1, 2024
1 parent 5d3124f commit 9839bf3
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 13 deletions.
2 changes: 1 addition & 1 deletion connectors/connector-xero/def.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const xeroSchemas = {
sourceOutputEntities: R.mapValues(XERO_ENTITY_NAME, () => z.unknown()),
} satisfies ConnectorSchemas

export const helpers = connHelpers(xeroSchemas)
export const xeroHelpers = connHelpers(xeroSchemas)

export const xeroDef = {
metadata: {
Expand Down
6 changes: 6 additions & 0 deletions connectors/connector-xero/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import type {initXeroSDK} from '@opensdks/sdk-xero'

// codegen:start {preset: barrel, include: "./{*.{ts,tsx},*/index.{ts,tsx}}", exclude: "./**/*.{d,spec,test,fixture,gen,node}.{ts,tsx}"}
export * from './def'
export * from './server'
// codegen:end

export * from '@opensdks/sdk-xero'

export type XeroSDK = ReturnType<typeof initXeroSDK>
25 changes: 15 additions & 10 deletions connectors/connector-xero/server.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {initXeroSDK} from '@opensdks/sdk-xero'
import type {ConnectorServer} from '@usevenice/cdk'
import {nangoProxyLink} from '@usevenice/cdk'
import {rxjs} from '@usevenice/util'
import {type xeroSchemas} from './def'
import {Rx, rxjs} from '@usevenice/util'
import {xeroHelpers, type xeroSchemas} from './def'

export const xeroServer = {
// Would be good if this was async...
Expand Down Expand Up @@ -34,7 +34,7 @@ export const xeroServer = {
},
sourceSync: ({instance: xero}) => {
console.log('[xero] Starting sync')
const getAll = async () => {
async function* iterateEntities() {
// TODO: Should handle more than one tenant Id
const tenantId = await xero.identity
.GET('/Connections')
Expand All @@ -44,18 +44,23 @@ export const xeroServer = {
'Missing access to any tenants. Check xero token permission',
)
}

const result = await xero.accounting.GET('/Accounts', {
params: {header: {'xero-tenant-id': tenantId}},
})
console.log('result', result)
return result
}

getAll()
.then((res) => console.log('[data test]', res))
.catch((err) => console.log('error', err))
if (result.data.Accounts) {
yield result.data.Accounts?.map((a) =>
xeroHelpers._opData('Accounts', a.AccountID!, a),
)
}
}

return rxjs.empty() // TODO: replace with data above.
return rxjs
.from(iterateEntities())
.pipe(
Rx.mergeMap((ops) => rxjs.from([...ops, xeroHelpers._op('commit')])),
)
},
} satisfies ConnectorServer<typeof xeroSchemas, ReturnType<typeof initXeroSDK>>

Expand Down
3 changes: 2 additions & 1 deletion docs/samples/banking-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {createVeniceClient} from '@usevenice/sdk'
const venice = createVeniceClient({
apiKey: process.env['_VENICE_API_KEY'],
apiHost: process.env['_VENICE_API_HOST'],
resourceId: process.env['_QBO_RESOURCE_ID'],
// resourceId: process.env['_QBO_RESOURCE_ID'],
resourceId: process.env['_XERO_RESOURCE_ID'],
})

void venice.GET('/verticals/banking/category').then((r) => {
Expand Down
3 changes: 2 additions & 1 deletion packages/engine-backend/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
outreachAdapter,
qboAdapter,
salesloftAdapter,
xeroAdapter,
} from '@usevenice/cdk/verticals'
import {remoteProcedure, trpc} from './_base'
import {adminRouter} from './adminRouter'
Expand All @@ -26,7 +27,7 @@ import {systemRouter} from './systemRouter'
const bankingRouter = createBankingRouter({
trpc,
remoteProcedure,
adapterByName: {qbo: qboAdapter},
adapterByName: {qbo: qboAdapter, xero: xeroAdapter},
})
const accountingRouter = createAccountingRouter({
trpc,
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions verticals/vertical-banking/adapters/xero-adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type {Oas_accounting, XeroSDK} from 'connectors/connector-xero'
import type {StrictObj} from '@usevenice/vdk'
import {mapper, z, zCast} from '@usevenice/vdk'
import type {VerticalBanking} from '../banking'
import {zBanking} from '../banking'

type Xero = Oas_accounting['components']['schemas']

const mappers = {
category: mapper(
zCast<StrictObj<Xero['Account']>>(),
zBanking.category.extend({_raw: z.unknown().optional()}),
{
id: 'AccountID',
name: 'Name',
_raw: (a) => a,
},
),
}

export const xeroAdapter = {
listCategories: async ({instance}) => {
// TODO: Abstract this away please...
const tenantId = await instance.identity
.GET('/Connections')
.then((r) => r.data?.[0]?.tenantId)
if (!tenantId) {
throw new Error(
'Missing access to any tenants. Check xero token permission',
)
}

const res = await instance.accounting.GET('/Accounts', {
params: {
header: {'xero-tenant-id': tenantId},
query: {
where: 'Class=="REVENUE"||Class=="EXPENSE"',
},
},
})
return {
hasNextPage: false,
items: (res.data.Accounts ?? []).map(mappers.category),
}
},
} satisfies VerticalBanking<{instance: XeroSDK}>
45 changes: 45 additions & 0 deletions verticals/vertical-banking/banking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {AnyEntityPayload, Id, Link} from '@usevenice/cdk'
import type {PlaidSDKTypes} from '@usevenice/connector-plaid'
import type {postgresHelpers} from '@usevenice/connector-postgres'
import type {QBO} from '@usevenice/connector-qbo'
import type {Oas_accounting} from '@usevenice/connector-xero'
import type {StrictObj} from '@usevenice/types'
import type {RouterMap, RouterMeta, VerticalRouterOpts} from '@usevenice/vdk'
import {
Expand All @@ -16,6 +17,7 @@ import {
} from '@usevenice/vdk'

type Plaid = PlaidSDKTypes['oas']['components']
type Xero = Oas_accounting['components']['schemas']

export const zBanking = {
transaction: z
Expand Down Expand Up @@ -83,6 +85,39 @@ export function bankingLink(ctx: {
if (op.type !== 'data') {
return rxjs.of(op)
}

if (ctx.source.connectorConfig.connectorName === 'xero') {
if (op.data.entityName === 'Accounts') {
const entity = op.data.entity as Xero['Account']
if (entity.Class === 'REVENUE' || entity.Class === 'EXPENSE') {
const mapped = applyMapper(
mappers.xero.category,
op.data.entity as Xero['Account'],
)
return rxjs.of({
...op,
data: {
id: mapped.id,
entityName: 'banking_category',
entity: {raw: op.data.entity, unified: mapped},
} satisfies PostgresInputPayload,
})
} else {
const mapped = applyMapper(
mappers.xero.accounts,
op.data.entity as Xero['Account'],
)
return rxjs.of({
...op,
data: {
id: mapped.id,
entityName: 'banking_account',
entity: {raw: op.data.entity, unified: mapped},
} satisfies PostgresInputPayload,
})
}
}
}
if (ctx.source.connectorConfig.connectorName === 'qbo') {
if (op.data.entityName === 'purchase') {
const mapped = applyMapper(
Expand Down Expand Up @@ -203,6 +238,16 @@ export function bankingLink(ctx: {
}

const mappers = {
xero: {
accounts: mapper(zCast<StrictObj<Xero['Account']>>(), zBanking.account, {
id: 'AccountID',
name: 'Name',
}),
category: mapper(zCast<StrictObj<Xero['Account']>>(), zBanking.account, {
id: 'AccountID',
name: 'Name',
}),
},
// Should be able to have input and output entity types in here also.
qbo: {
purchase: mapper(
Expand Down
1 change: 1 addition & 0 deletions verticals/vertical-banking/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
export * from './banking'
// codegen:end
export * from './adapters/qbo-adapter'
export * from './adapters/xero-adapter'
1 change: 1 addition & 0 deletions verticals/vertical-banking/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"@usevenice/connector-plaid": "workspace:*",
"@usevenice/connector-postgres": "workspace:*",
"@usevenice/connector-qbo": "workspace:*",
"@usevenice/connector-xero": "workspace:*",
"@usevenice/types": "workspace:*"
}
}

0 comments on commit 9839bf3

Please sign in to comment.