From 7e3fe238ba625b100e13255476ad15996cdbc499 Mon Sep 17 00:00:00 2001 From: jatin Date: Mon, 1 Apr 2024 19:25:41 +0530 Subject: [PATCH] feat: (wip) add sync logic for accounts --- apps/cli/package.json | 1 + connectors/connector-xero/def.ts | 36 +++++++++----- connectors/connector-xero/package.json | 3 +- connectors/connector-xero/server.ts | 47 +++++++++++++++++-- packages/engine-backend/router/_base.ts | 23 +++++---- .../engine-backend/router/resourceRouter.ts | 6 ++- packages/engine-frontend/VeniceConnect.tsx | 2 +- pnpm-lock.yaml | 29 ++++++++++-- 8 files changed, 111 insertions(+), 36 deletions(-) diff --git a/apps/cli/package.json b/apps/cli/package.json index a95760a0..e603aa76 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -27,6 +27,7 @@ "@usevenice/connector-toggl": "workspace:*", "@usevenice/connector-venmo": "workspace:*", "@usevenice/connector-wise": "workspace:*", + "@usevenice/connector-xero": "workspace:*", "@usevenice/connector-yodlee": "workspace:*", "@usevenice/engine-backend": "workspace:*", "@usevenice/env": "workspace:*", diff --git a/connectors/connector-xero/def.ts b/connectors/connector-xero/def.ts index 067a5498..985899a4 100644 --- a/connectors/connector-xero/def.ts +++ b/connectors/connector-xero/def.ts @@ -1,17 +1,29 @@ -import type { - ConnectorDef, - ConnectorSchemas, - EntityPayloadWithRaw, -} from '@usevenice/cdk' -import {connHelpers} from '@usevenice/cdk' -import {z, zCast} from '@usevenice/util' +import type {components} from '@opensdks/sdk-xero/xero_accounting.oas.types' +import type {ConnectorDef, ConnectorSchemas} from '@usevenice/cdk' +import {connHelpers, oauthBaseSchema, zEntityPayload} from '@usevenice/cdk' +import {R, z} from '@usevenice/util' + +export const zConfig = oauthBaseSchema.connectorConfig + +const oReso = oauthBaseSchema.resourceSettings +export const zSettings = oReso.extend({ + oauth: oReso.shape.oauth, +}) + +export type XERO = components['schemas'] + +export const XERO_ENTITY_NAME = { + Accounts: 'Accounts', + PurchaseOrders: 'PurchaseOrders', +} export const xeroSchemas = { name: z.literal('xero'), - resourceSettings: z.object({ - access_token: z.string(), - }), - destinationInputEntity: zCast(), + connectorConfig: zConfig, + resourceSettings: zSettings, + connectOutput: oauthBaseSchema.connectOutput, + sourceOutputEntity: zEntityPayload, + sourceOutputEntities: R.mapValues(XERO_ENTITY_NAME, () => z.unknown()), } satisfies ConnectorSchemas export const helpers = connHelpers(xeroSchemas) @@ -21,7 +33,7 @@ export const xeroDef = { categories: ['accounting'], logoUrl: '/_assets/logo-xero.svg', displayName: 'Xero', - stage: 'alpha', + stage: 'beta', nangoProvider: 'xero', }, name: 'xero', diff --git a/connectors/connector-xero/package.json b/connectors/connector-xero/package.json index 9e1e7663..6b9e32f2 100644 --- a/connectors/connector-xero/package.json +++ b/connectors/connector-xero/package.json @@ -5,7 +5,8 @@ "sideEffects": [], "module": "./index.ts", "dependencies": { - "@opensdks/sdk-xero": "^0.0.2", + "@opensdks/runtime": "^0.0.16", + "@opensdks/sdk-xero": "^0.0.5", "@opensdks/util-zod": "^0.0.15", "@usevenice/cdk": "workspace:*", "@usevenice/util": "workspace:*" diff --git a/connectors/connector-xero/server.ts b/connectors/connector-xero/server.ts index 88732094..40b1e411 100644 --- a/connectors/connector-xero/server.ts +++ b/connectors/connector-xero/server.ts @@ -1,16 +1,53 @@ import {initXeroSDK} from '@opensdks/sdk-xero' import type {ConnectorServer} from '@usevenice/cdk' -import type {xeroSchemas} from './def' +import {nangoProxyLink} from '@usevenice/cdk' +import {rxjs} from '@usevenice/util' +import {type xeroSchemas} from './def' export const xeroServer = { - newInstance: ({settings}) => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + newInstance: ({settings, fetchLinks}) => { const xero = initXeroSDK({ - headers: {authorization: `Bearer ${settings.access_token}`}, + headers: { + authorization: `Bearer ${settings.oauth.credentials.access_token}`, + }, + links: (defaultLinks) => [ + (req, next) => { + if (xero.clientOptions.baseUrl) { + req.headers.set( + nangoProxyLink.kBaseUrlOverride, + xero.clientOptions.baseUrl, + ) + } + return next(req) + }, + ...fetchLinks, + ...defaultLinks, + ], }) - // TODO(@jatin): Add logic here to handle sync. return xero }, + sourceSync: ({instance: xero}) => { + // TODO(@jatin): Add logic here to handle sync. + // TODO: ensure instance has typesafety for some reason the types are not present here :/. + console.log('[xero] Starting sync', xero) + const getAll = async () => { + const result = await xero.client.GET('/Accounts', { + params: { + header: { + 'xero-tenant-id': '35325d8f-5087-4c6d-b413-c3f740c26f2e', // TODO: Remove hardcoding + }, + }, + }) + console.log('result', result) + return result.data?.Accounts + } + + getAll() + .then((res) => console.log('[data test]', res)) + .catch((err) => console.log('error', err)) + + return rxjs.empty() + }, } satisfies ConnectorServer export default xeroServer diff --git a/packages/engine-backend/router/_base.ts b/packages/engine-backend/router/_base.ts index f1d7d9db..4e508598 100644 --- a/packages/engine-backend/router/_base.ts +++ b/packages/engine-backend/router/_base.ts @@ -44,20 +44,19 @@ export const trpc = initTRPC }) export const publicProcedure = trpc.procedure -// Enable me for logs -// .use( -// ({next, ctx, input, rawInput, meta, path}) => { -// console.log('[trpc]', { -// input, -// rawInput, -// meta, -// path, -// }) -// return next({ctx}) -// }, -// ) + // Enable me for logs + .use(({next, ctx, input, rawInput, meta, path}) => { + console.log('[trpc]', { + input, + rawInput, + meta, + path, + }) + return next({ctx}) + }) export const protectedProcedure = publicProcedure.use(({next, ctx}) => { + console.log('DEBUG', ctx.viewer) if (!hasRole(ctx.viewer, ['end_user', 'user', 'org', 'system'])) { throw new TRPCError({ code: ctx.viewer.role === 'anon' ? 'UNAUTHORIZED' : 'FORBIDDEN', diff --git a/packages/engine-backend/router/resourceRouter.ts b/packages/engine-backend/router/resourceRouter.ts index 93c134ea..72849b1b 100644 --- a/packages/engine-backend/router/resourceRouter.ts +++ b/packages/engine-backend/router/resourceRouter.ts @@ -277,7 +277,11 @@ export const resourceRouter = trpc.router({ return } const reso = await ctx.asOrgIfNeeded.getResourceExpandedOrFail(resoId) - console.log('[syncResource]', reso, opts) + console.log( + '[syncResource]', + opts?.metaOnly, + reso.connectorConfig.connector.sourceSync, + ) // No need to checkResource here as sourceSync should take care of it if (opts?.metaOnly) { diff --git a/packages/engine-frontend/VeniceConnect.tsx b/packages/engine-frontend/VeniceConnect.tsx index 9a90dc25..03850009 100644 --- a/packages/engine-frontend/VeniceConnect.tsx +++ b/packages/engine-frontend/VeniceConnect.tsx @@ -156,7 +156,7 @@ export function _VeniceConnect({ }) { const nangoPublicKey = _trpcReact.getPublicEnv.useQuery().data?.NEXT_PUBLIC_NANGO_PUBLIC_KEY - + console.log('DEBUG', connectorConfigInfos, clientConnectors) const nangoFrontend = React.useMemo( () => nangoPublicKey && diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f2ff9fd4..be233ad8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -409,6 +409,9 @@ importers: '@usevenice/connector-wise': specifier: workspace:* version: link:../../connectors/connector-wise + '@usevenice/connector-xero': + specifier: workspace:* + version: link:../../connectors/connector-xero '@usevenice/connector-yodlee': specifier: workspace:* version: link:../../connectors/connector-yodlee @@ -1165,9 +1168,12 @@ importers: connectors/connector-xero: dependencies: + '@opensdks/runtime': + specifier: ^0.0.16 + version: 0.0.16 '@opensdks/sdk-xero': - specifier: ^0.0.2 - version: 0.0.2 + specifier: ^0.0.5 + version: 0.0.5 '@opensdks/util-zod': specifier: ^0.0.15 version: 0.0.15 @@ -4709,6 +4715,10 @@ packages: /@opensdks/fetch-links@0.0.17: resolution: {integrity: sha512-BUomrnpFtlu085W1wOY0k52Kf6qkJwBDifQxFoSHkfjyjS81AkpOTPsBTYS5HffAXS8rgoBBJF+7fu2NSYipFw==} + /@opensdks/fetch-links@0.0.18: + resolution: {integrity: sha512-EhBj92wLXoj3pF4ERxzoEhAlwlefIzQ31At0zaksSbA9zqMlod9DyfypQRX/6J8w4iZzraV33BtFEk7l98nsLA==} + dev: false + /@opensdks/runtime@0.0.16: resolution: {integrity: sha512-aCRhxlWr2e+hB38quP2tLkaPGZNPMV9rBE+IoTwDoHS4mql2dyn7HvxRYisoU3XmdaMCLvbf8+H/7Nrj02tMpg==} dependencies: @@ -4717,6 +4727,15 @@ packages: openapi-typescript-helpers: 0.0.4 openapi3-ts: 4.1.2 + /@opensdks/runtime@0.0.19: + resolution: {integrity: sha512-9rPrPDHS+PRVKOWXbdYEtys/4uHeVzitQgR0QVSWtMFOn6FOY8VxMGvem0TGJwHf4EPecejoWF8NuNwUATmbeA==} + dependencies: + '@opensdks/fetch-links': 0.0.18 + openapi-fetch: 0.8.1 + openapi-typescript-helpers: 0.0.4 + openapi3-ts: 4.1.2 + dev: false + /@opensdks/sdk-apollo@0.0.18: resolution: {integrity: sha512-i2rps56eTt22cM1pwbVyTVlZtpjP65T3jMJhX2rKO2CiHd7+QoI3+hT+ko6dCIsi6STPnoM+IIJhmyQZjJIktA==} dev: false @@ -4764,8 +4783,10 @@ packages: '@opensdks/runtime': 0.0.16 dev: true - /@opensdks/sdk-xero@0.0.2: - resolution: {integrity: sha512-ni6s4q658K9dWsmXwD4mnJrL9QguZwGxgtDt24Is4cjUNmiLqfxpC7PqE4ecxKn/TNv+oZiQJKm7Di29UHt3rQ==} + /@opensdks/sdk-xero@0.0.5: + resolution: {integrity: sha512-dYlYTa6awnXQ8TmdCQu36Dt+pwzD9+sQ3CAuzfknOxWnERc0mb1ark5rxDoMoqNQsddSeNKkBQE2b8DEj9oa4Q==} + dependencies: + '@opensdks/runtime': 0.0.19 dev: false /@opensdks/util-zod@0.0.15: