-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(wip): dummy xero connector implementation * remove xero-sdk reference till publish * update connector image on dashboard * feat: (wip) add sync logic for accounts * upgrade sdk-xero * revert: changes that are were needed * feat: remove hard code in xero connector * feat(xero): listCategories, sourceSync account and category * feat(xero): bank transactions ync --------- Co-authored-by: Tony Xiao <[email protected]>
- Loading branch information
1 parent
3088e47
commit 6e94d3a
Showing
15 changed files
with
313 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,83 @@ | ||
import {initXeroSDK} from '@opensdks/sdk-xero' | ||
import type {ConnectorServer} from '@usevenice/cdk' | ||
import type {xeroSchemas} from './def' | ||
import {nangoProxyLink} from '@usevenice/cdk' | ||
import {Rx, rxjs} from '@usevenice/util' | ||
import {XERO_ENTITY_NAME, xeroHelpers, type xeroSchemas} from './def' | ||
|
||
export const xeroServer = { | ||
newInstance: ({settings}) => { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
// Would be good if this was async... | ||
newInstance: ({settings, fetchLinks}) => { | ||
const xero = initXeroSDK({ | ||
headers: {authorization: `Bearer ${settings.access_token}`}, | ||
headers: { | ||
authorization: `Bearer ${settings.oauth.credentials.access_token}`, | ||
}, | ||
links: (defaultLinks) => [ | ||
(req, next) => { | ||
req.headers.set( | ||
nangoProxyLink.kBaseUrlOverride, | ||
'https://api.xero.com', | ||
) | ||
// nango's proxy endpoint is pretty annoying... Will only proxy | ||
// if it is prefixed with nango-proxy. Might as well not proxy like this... | ||
const tenantId = req.headers.get('xero-tenant-id') | ||
if (tenantId) { | ||
req.headers.delete('xero-tenant-id') | ||
req.headers.set('nango-proxy-xero-tenant-id', tenantId) | ||
} | ||
return next(req) | ||
}, | ||
...fetchLinks, | ||
...defaultLinks, | ||
], | ||
}) | ||
// TODO(@jatin): Add logic here to handle sync. | ||
return xero | ||
}, | ||
} satisfies ConnectorServer<typeof xeroSchemas> | ||
sourceSync: ({instance: xero, streams}) => { | ||
console.log('[xero] Starting sync') | ||
async function* iterateEntities() { | ||
// TODO: Should handle more than one tenant Id | ||
const tenantId = await xero.identity | ||
.GET('/Connections') | ||
.then((r) => r.data?.[0]?.tenantId) | ||
if (!tenantId) { | ||
throw new Error( | ||
'Missing access to any tenants. Check xero token permission', | ||
) | ||
} | ||
for (const type of Object.values(XERO_ENTITY_NAME)) { | ||
if (!streams[type]) { | ||
continue | ||
} | ||
|
||
const singular = type as 'BankTransaction' | ||
const plural = `${singular}s` as const | ||
const kId = `${singular}ID` as const | ||
let page = 1 | ||
while (true) { | ||
const result = await xero.accounting.GET(`/${plural}`, { | ||
params: {header: {'xero-tenant-id': tenantId}, query: {page}}, | ||
}) | ||
if (result.data[plural]?.length) { | ||
yield result.data[plural]?.map((a) => | ||
xeroHelpers._opData(singular, a[kId]!, a), | ||
) | ||
// Account does not support pagination, all or nothing... | ||
if (type !== 'Account') { | ||
page++ | ||
continue | ||
} | ||
} | ||
break | ||
} | ||
} | ||
} | ||
|
||
return rxjs | ||
.from(iterateEntities()) | ||
.pipe( | ||
Rx.mergeMap((ops) => rxjs.from([...ops, xeroHelpers._op('commit')])), | ||
) | ||
}, | ||
} satisfies ConnectorServer<typeof xeroSchemas, ReturnType<typeof initXeroSDK>> | ||
|
||
export default xeroServer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}> |
Oops, something went wrong.
6e94d3a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
venice – ./
venice-git-production-venice.vercel.app
venice-venice.vercel.app
usevenice.vercel.app
app.venice.is