From 0599319f9a2cd3d03750e94a5a2b3853b11d7286 Mon Sep 17 00:00:00 2001 From: Rojan Rajbhandari Date: Thu, 19 Feb 2026 15:13:35 +0545 Subject: [PATCH 1/7] chore(OUT-3169): add patch for assembly node-sdk to prevent sending tokenId in auth header --- lib-patches/assembly-js-node-sdk.js | 133 ++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 lib-patches/assembly-js-node-sdk.js diff --git a/lib-patches/assembly-js-node-sdk.js b/lib-patches/assembly-js-node-sdk.js new file mode 100644 index 0000000..7cefcf4 --- /dev/null +++ b/lib-patches/assembly-js-node-sdk.js @@ -0,0 +1,133 @@ +import { DefaultService as Assembly, OpenAPI } from '../codegen/api' +export { OpenAPI } +import { request as __request } from '../codegen/api/core/request' +import { decryptAES128BitToken, generate128BitKey } from '../utils/crypto' +// SDK version for tracking compatibility +// TODO: Restore dynamic version reading after fixing build +let SDK_VERSION = '3.19.1' +const sdk = Assembly +// Helper functions to check env vars at runtime (supports both new and old names) +function getIsDebug() { + var _a + return !!((_a = process.env.ASSEMBLY_DEBUG) !== null && _a !== void 0 + ? _a + : process.env.COPILOT_DEBUG) +} +function getEnvMode() { + var _a + return (_a = process.env.ASSEMBLY_ENV) !== null && _a !== void 0 + ? _a + : process.env.COPILOT_ENV +} +// Exported for testing purposes only +export function processToken(token) { + try { + const json = JSON.parse(token) + // workspaceId is the only required field + if (!('workspaceId' in json)) { + throw new Error('Missing required field in token payload: workspaceId') + } + // Note: We intentionally do NOT validate that all keys are from a known list. + // This allows the backend to add new fields (like tokenId, expiresAt) without + // breaking older SDK versions. Unknown fields are simply ignored. + const areAllValuesValid = Object.values(json).every( + (val) => typeof val === 'string', + ) + if (!areAllValuesValid) { + throw new Error('Invalid values in token payload.') + } + const result = { + companyId: json.companyId, + clientId: json.clientId, + internalUserId: json.internalUserId, + workspaceId: json.workspaceId, + notificationId: json.notificationId, + baseUrl: json.baseUrl, + tokenId: json.tokenId, + } + return result + } catch (e) { + if (getIsDebug()) { + console.error(e) + } + return null + } +} +// Primary function (new name) +export function assemblyApi({ apiKey, token: tokenString }) { + const isDebug = getIsDebug() + const envMode = getEnvMode() + let key = ['local', '__SECRET_STAGING__'].includes( + envMode !== null && envMode !== void 0 ? envMode : '', + ) + ? apiKey + : undefined + if (isDebug) { + console.log('Debugging the assemblyApi init script.') + console.log({ env: envMode }) + } + if (tokenString) { + if (isDebug) { + console.log({ tokenString, apiKey }) + } + try { + const decipherKey = generate128BitKey(apiKey) + const decryptedPayload = decryptAES128BitToken(decipherKey, tokenString) + if (isDebug) { + console.log('Decrypted Payload:', decryptedPayload) + } + const payload = processToken(decryptedPayload) + if (!payload) { + throw new Error('Invalid token payload.') + } + if (isDebug) { + console.log('Payload:', payload) + } + if (payload.baseUrl) { + OpenAPI.BASE = payload.baseUrl + } + sdk.getTokenPayload = () => new Promise((resolve) => resolve(payload)) + // Build the key: workspaceId/apiKey or workspaceId/apiKey/tokenId if tokenId is present + key = payload.tokenId + ? `${payload.workspaceId}/${apiKey}/${payload.tokenId}` + : `${payload.workspaceId}/${apiKey}` + } catch (error) { + console.error(error) + } + } + if (!key) { + console.warn( + 'We were unable to authorize the SDK. If you are working in a local development environment, set the ASSEMBLY_ENV environment variable to "local" (COPILOT_ENV also works).', + ) + throw new Error('Unable to authorize Assembly SDK.') + } + if (isDebug) { + console.log(`Authorizing with key: ${key}`) + } + + // TEMPORARY FIX: suppress sending tokenId to auth header if ASSEMBLY_SUPPRESS_TOKEN_ID is set + const suppressTokenId = !!process.env.ASSEMBLY_SUPPRESS_TOKEN_ID + if (suppressTokenId) { + const keySections = key.split('/') + key = `${keySections[0]}/${keySections[1]}` + SDK_VERSION = undefined // looks like this is being used to enable/disable expiry. Drop this just in case. + } + + OpenAPI.HEADERS = { + 'X-API-Key': key, + 'X-Assembly-SDK-Version': SDK_VERSION, + } + sdk.sendWebhook = (event, payload) => { + return __request(OpenAPI, { + method: 'POST', + url: '/v1/webhooks/{event}', + path: { event }, + body: payload, + mediaType: 'application/json', + }) + } + return sdk +} +/** @deprecated Use `assemblyApi` instead. Will be removed in v5.0.0. */ +export const copilotApi = assemblyApi +//# sourceMappingURL=init.js.map From c9aaee274fed2216af69cb1ab92539f523de0136 Mon Sep 17 00:00:00 2001 From: Rojan Rajbhandari Date: Thu, 19 Feb 2026 15:13:56 +0545 Subject: [PATCH 2/7] chore(OUT-3169): bump assembly sdk --- src/utils/copilotAPI.ts | 60 ++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/src/utils/copilotAPI.ts b/src/utils/copilotAPI.ts index d2b1078..a6ab93a 100644 --- a/src/utils/copilotAPI.ts +++ b/src/utils/copilotAPI.ts @@ -44,18 +44,18 @@ import { WorkspaceResponseSchema, } from '@/type/common' import Bottleneck from 'bottleneck' -import type { CopilotAPI as SDK } from 'copilot-node-sdk' -import { copilotApi } from 'copilot-node-sdk' +import type { AssemblyAPI as SDK } from '@assembly-js/node-sdk' +import { assemblyApi } from '@assembly-js/node-sdk' import { z } from 'zod' import { API_DOMAIN } from '@/constant/domains' import httpStatus from 'http-status' import { MAX_INVOICE_LIST_LIMIT } from '@/app/api/core/constants/limit' export class CopilotAPI { - copilot: SDK + apiClient: SDK constructor(private token: string) { - this.copilot = copilotApi({ apiKey, token }) + this.apiClient = assemblyApi({ apiKey, token }) } private async manualFetch( @@ -88,7 +88,7 @@ export class CopilotAPI { // Get Token Payload from copilot request token async _getTokenPayload(): Promise { - const getTokenPayload = this.copilot.getTokenPayload + const getTokenPayload = this.apiClient.getTokenPayload if (!getTokenPayload) { console.error( `CopilotAPI#getTokenPayload | Could not parse token payload for token ${this.token}`, @@ -106,8 +106,8 @@ export class CopilotAPI { if (!tokenPayload || !id) return null const retrieveCurrentUserInfo = tokenPayload.internalUserId - ? this.copilot.retrieveInternalUser - : this.copilot.retrieveClient + ? this.apiClient.retrieveInternalUser + : this.apiClient.retrieveClient const currentUserInfo = await retrieveCurrentUserInfo({ id }) return MeResponseSchema.parse(currentUserInfo) @@ -115,7 +115,9 @@ export class CopilotAPI { async _getWorkspace(): Promise { console.info('CopilotAPI#getWorkspace | token =', this.token) - return WorkspaceResponseSchema.parse(await this.copilot.retrieveWorkspace()) + return WorkspaceResponseSchema.parse( + await this.apiClient.retrieveWorkspace(), + ) } async _getClientTokenPayload(): Promise { @@ -140,7 +142,7 @@ export class CopilotAPI { ): Promise { console.info('CopilotAPI#createClient | token =', this.token) return ClientResponseSchema.parse( - await this.copilot.createClient({ sendInvite, requestBody }), + await this.apiClient.createClient({ sendInvite, requestBody }), ) } @@ -152,7 +154,7 @@ export class CopilotAPI { try { console.info('CopilotAPI#getClient | token =', this.token) return ClientResponseSchema.parse( - await this.copilot.retrieveClient({ id }), + await this.apiClient.retrieveClient({ id }), ) } catch (error: unknown) { if ( @@ -182,7 +184,7 @@ export class CopilotAPI { async _getClients(args: CopilotListArgs & { companyId?: string } = {}) { try { console.info('CopilotAPI#getClients | token =', this.token) - return ClientsResponseSchema.parse(await this.copilot.listClients(args)) + return ClientsResponseSchema.parse(await this.apiClient.listClients(args)) } catch (error: unknown) { if ( typeof error === 'object' && @@ -210,19 +212,19 @@ export class CopilotAPI { ): Promise { console.info('CopilotAPI#updateClient | token =', this.token) return ClientResponseSchema.parse( - await this.copilot.updateClient({ id, requestBody }), + await this.apiClient.updateClient({ id, requestBody }), ) } async _deleteClient(id: string) { console.info('CopilotAPI#deleteClient | token =', this.token) - return await this.copilot.deleteClient({ id }) + return await this.apiClient.deleteClient({ id }) } async _createCompany(requestBody: CompanyCreateRequest) { console.info('CopilotAPI#createCompany | token =', this.token) return CompanyResponseSchema.parse( - await this.copilot.createCompany({ requestBody }), + await this.apiClient.createCompany({ requestBody }), ) } @@ -234,7 +236,7 @@ export class CopilotAPI { try { console.info('CopilotAPI#getCompany | token =', this.token) return CompanyResponseSchema.parse( - await this.copilot.retrieveCompany({ id }), + await this.apiClient.retrieveCompany({ id }), ) } catch (error: unknown) { if ( @@ -259,7 +261,9 @@ export class CopilotAPI { async _getCompanies(args: CopilotListArgs = {}): Promise { console.info('CopilotAPI#getCompanies | token =', this.token) - return CompaniesResponseSchema.parse(await this.copilot.listCompanies(args)) + return CompaniesResponseSchema.parse( + await this.apiClient.listCompanies(args), + ) } async _getCompanyClients(companyId: string): Promise { @@ -270,7 +274,7 @@ export class CopilotAPI { async _getCustomFields(): Promise { console.info('CopilotAPI#getCustomFields | token =', this.token) return CustomFieldResponseSchema.parse( - await this.copilot.listCustomFields({}), + await this.apiClient.listCustomFields({}), ) } @@ -279,14 +283,14 @@ export class CopilotAPI { ): Promise { console.info('CopilotAPI#getInternalUsers | token =', this.token) return InternalUsersResponseSchema.parse( - await this.copilot.listInternalUsers(args), + await this.apiClient.listInternalUsers(args), ) } async _getInternalUser(id: string): Promise { console.info('CopilotAPI#getInternalUser | token =', this.token) return InternalUsersSchema.parse( - await this.copilot.retrieveInternalUser({ id }), + await this.apiClient.retrieveInternalUser({ id }), ) } @@ -296,7 +300,7 @@ export class CopilotAPI { console.info('CopilotAPI#createNotification | token =', this.token) console.info('CopilotAPI#createNotification | requestBody =', requestBody) return NotificationCreatedResponseSchema.parse( - await this.copilot.createNotification({ + await this.apiClient.createNotification({ requestBody, }), ) @@ -304,7 +308,7 @@ export class CopilotAPI { async _markNotificationAsRead(id: string): Promise { console.info('CopilotAPI#markNotificationAsRead | token =', this.token) - await this.copilot.markNotificationRead({ id }) + await this.apiClient.markNotificationRead({ id }) } async _bulkMarkNotificationsAsRead(notificationIds: string[]): Promise { @@ -332,7 +336,7 @@ export class CopilotAPI { async _deleteNotification(id: string): Promise { console.info('CopilotAPI#deleteNotification | token =', this.token) - await this.copilot.deleteNotification({ id }) + await this.apiClient.deleteNotification({ id }) } async _bulkDeleteNotifications(notificationIds: string[]): Promise { @@ -381,7 +385,7 @@ export class CopilotAPI { async _getProduct(id: string): Promise { console.info('CopilotAPI#getProduct | token =', this.token) return ProductResponseSchema.parse( - await this.copilot.retrieveProduct({ id }), + await this.apiClient.retrieveProduct({ id }), ) } @@ -392,13 +396,13 @@ export class CopilotAPI { ): Promise { console.info('CopilotAPI#getProducts | token =', this.token) return ProductsResponseSchema.parse( - await this.copilot.listProducts({ name, nextToken, limit }), + await this.apiClient.listProducts({ name, nextToken, limit }), ) } async _getPrice(id: string): Promise { console.info('CopilotAPI#getPrice | token =', this.token) - return PriceResponseSchema.parse(await this.copilot.retrievePrice({ id })) + return PriceResponseSchema.parse(await this.apiClient.retrievePrice({ id })) } async _getPrices( @@ -408,14 +412,14 @@ export class CopilotAPI { ): Promise { console.info('CopilotAPI#getPrices | token =', this.token) return PricesResponseSchema.parse( - await this.copilot.listPrices({ productId, nextToken, limit }), + await this.apiClient.listPrices({ productId, nextToken, limit }), ) } async _getInvoice(id: string): Promise { console.info('CopilotAPI#getInvoice | token =', this.token) return InvoiceResponseSchema.parse( - await this.copilot.retrieveInvoice({ id }), + await this.apiClient.retrieveInvoice({ id }), ) } @@ -438,7 +442,7 @@ export class CopilotAPI { async _getPayments(invoiceId: string): Promise { console.info('CopilotAPI#getPayments | token =', this.token) return PaymentsResponseSchema.parse( - await this.copilot.listPayments({ invoiceId }), + await this.apiClient.listPayments({ invoiceId }), ) } From c58b5641bfbce0fa84092866b5f2be7e0b46f94c Mon Sep 17 00:00:00 2001 From: Rojan Rajbhandari Date: Thu, 19 Feb 2026 15:14:37 +0545 Subject: [PATCH 3/7] feat(OUT-3169): add proper build script --- build.sh | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 build.sh diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..733169b --- /dev/null +++ b/build.sh @@ -0,0 +1,5 @@ +# TEMPORARY FIX: suppress sending tokenId to auth header +yarn patch-assembly-node-sdk + +yarn drizzle-kit migrate +next build \ No newline at end of file From 8c19a819271934b6bb718d17e6e48eccf2c94393 Mon Sep 17 00:00:00 2001 From: Rojan Rajbhandari Date: Thu, 19 Feb 2026 15:14:19 +0545 Subject: [PATCH 4/7] chore(OUT-3169): add script runner for patching node sdk --- package.json | 7 ++++--- yarn.lock | 43 ++++++++++++------------------------------- 2 files changed, 16 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index 087a574..2eea42f 100644 --- a/package.json +++ b/package.json @@ -16,15 +16,16 @@ "lint-staged": "npx lint-staged", "prepare": "husky", "supabase:dev": "supabase start --ignore-health-check", - "cmd:rename-qb-accounts": "tsx src/cmd/renameQbAccount/index.ts" + "cmd:rename-qb-accounts": "tsx src/cmd/renameQbAccount/index.ts", + "patch-assembly-node-sdk": "cp ./lib-patches/assembly-js-node-sdk.js ./node_modules/@assembly-js/node-sdk/dist/api/init.js" }, "dependencies": { + "@assembly-js/node-sdk": "^3.19.1", "@sentry/nextjs": "^9.13.0", "@supabase/supabase-js": "^2.49.4", "@trigger.dev/sdk": "4.3.0", "bottleneck": "^2.19.5", "copilot-design-system": "^2.0.10", - "copilot-node-sdk": "^3.16.0", "dayjs": "^1.11.13", "deep-equal": "^2.2.3", "drizzle-orm": "^0.42.0", @@ -88,4 +89,4 @@ "yarn prettier:fix" ] } -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index a4aa734..95919aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29,6 +29,16 @@ __metadata: languageName: node linkType: hard +"@assembly-js/node-sdk@npm:^3.19.1": + version: 3.19.1 + resolution: "@assembly-js/node-sdk@npm:3.19.1" + dependencies: + isomorphic-fetch: "npm:^3.0.0" + next: "npm:^14.0.2" + checksum: 10c0/8385b54c6426f7867db8c308c96f5e535aeab59ff1150fc96809d080a1004792920d0390e8a7d26775e5480a8a10f2b7f7db1d29c1e42267a9a03e12e8418785 + languageName: node + linkType: hard + "@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.27.1": version: 7.27.1 resolution: "@babel/code-frame@npm:7.27.1" @@ -5200,35 +5210,6 @@ __metadata: languageName: node linkType: hard -"copilot-node-sdk@npm:^3.16.0": - version: 3.17.1 - resolution: "copilot-node-sdk@npm:3.17.1" - dependencies: - isomorphic-fetch: "npm:^3.0.0" - next: "npm:^14.0.2" - checksum: 10c0/976739b359a36402e249e5d3b7182c0271eb3d0c6d8479ca81b8f733b263fe1edf14fffff82e89df8679de4ecc73c58478c4006de9ab99fd8f4e642a7c343c80 - languageName: node - linkType: hard - -"copy-anything@npm:^4": - version: 4.0.5 - resolution: "copy-anything@npm:4.0.5" - dependencies: - is-what: "npm:^5.2.0" - checksum: 10c0/d0a4a4102334399dae8504a2c2e13f45ad05746a9fd5cc0df349a554e3749a05e8a6d62b3724a8049cd59fc0bbbf4f54c4edc94a428edc76211dffe3ac0af586 - languageName: node - linkType: hard - -"cors@npm:~2.8.5": - version: 2.8.5 - resolution: "cors@npm:2.8.5" - dependencies: - object-assign: "npm:^4" - vary: "npm:^1" - checksum: 10c0/373702b7999409922da80de4a61938aabba6929aea5b6fd9096fefb9e8342f626c0ebd7507b0e8b0b311380744cc985f27edebc0a26e0ddb784b54e1085de761 - languageName: node - linkType: hard - "cosmiconfig@npm:^7.0.0": version: 7.1.0 resolution: "cosmiconfig@npm:7.1.0" @@ -5313,6 +5294,7 @@ __metadata: version: 0.0.0-use.local resolution: "custom-app-base@workspace:." dependencies: + "@assembly-js/node-sdk": "npm:^3.19.1" "@eslint/eslintrc": "npm:^3.3.1" "@eslint/js": "npm:^9.24.0" "@ngrok/ngrok": "npm:^1.4.1" @@ -5330,8 +5312,7 @@ __metadata: "@types/react-linkify": "npm:^1" autoprefixer: "npm:^10.4.0" bottleneck: "npm:^2.19.5" - copilot-design-system: "npm:^2.0.10" - copilot-node-sdk: "npm:^3.16.0" + copilot-design-system: "npm:^1.2.3" dayjs: "npm:^1.11.13" deep-equal: "npm:^2.2.3" dotenv: "npm:^16.4.5" From d09a88a0d8a278dd740270e8a9eb4d8265b090c0 Mon Sep 17 00:00:00 2001 From: Rojan Rajbhandari Date: Thu, 19 Feb 2026 15:25:49 +0545 Subject: [PATCH 5/7] chore(OUT-3169): fix lockfile --- yarn.lock | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 95919aa..0b7c62c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5210,6 +5210,25 @@ __metadata: languageName: node linkType: hard +"copy-anything@npm:^4": + version: 4.0.5 + resolution: "copy-anything@npm:4.0.5" + dependencies: + is-what: "npm:^5.2.0" + checksum: 10c0/d0a4a4102334399dae8504a2c2e13f45ad05746a9fd5cc0df349a554e3749a05e8a6d62b3724a8049cd59fc0bbbf4f54c4edc94a428edc76211dffe3ac0af586 + languageName: node + linkType: hard + +"cors@npm:~2.8.5": + version: 2.8.6 + resolution: "cors@npm:2.8.6" + dependencies: + object-assign: "npm:^4" + vary: "npm:^1" + checksum: 10c0/ab2bc57b8af8ef8476682a59647f7c55c1a7d406b559ac06119aa1c5f70b96d35036864d197b24cf86e228e4547231088f1f94ca05061dbb14d89cc0bc9d4cab + languageName: node + linkType: hard + "cosmiconfig@npm:^7.0.0": version: 7.1.0 resolution: "cosmiconfig@npm:7.1.0" @@ -5312,7 +5331,7 @@ __metadata: "@types/react-linkify": "npm:^1" autoprefixer: "npm:^10.4.0" bottleneck: "npm:^2.19.5" - copilot-design-system: "npm:^1.2.3" + copilot-design-system: "npm:^2.0.10" dayjs: "npm:^1.11.13" deep-equal: "npm:^2.2.3" dotenv: "npm:^16.4.5" From 55685423f5c0e971522d060395b58bd725b2db5e Mon Sep 17 00:00:00 2001 From: Rojan Rajbhandari Date: Thu, 19 Feb 2026 15:32:40 +0545 Subject: [PATCH 6/7] refactor(OUT-3169): clean code --- lib-patches/assembly-js-node-sdk.js | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/lib-patches/assembly-js-node-sdk.js b/lib-patches/assembly-js-node-sdk.js index 7cefcf4..79e1650 100644 --- a/lib-patches/assembly-js-node-sdk.js +++ b/lib-patches/assembly-js-node-sdk.js @@ -8,13 +8,13 @@ let SDK_VERSION = '3.19.1' const sdk = Assembly // Helper functions to check env vars at runtime (supports both new and old names) function getIsDebug() { - var _a + let _a return !!((_a = process.env.ASSEMBLY_DEBUG) !== null && _a !== void 0 ? _a : process.env.COPILOT_DEBUG) } function getEnvMode() { - var _a + let _a return (_a = process.env.ASSEMBLY_ENV) !== null && _a !== void 0 ? _a : process.env.COPILOT_ENV @@ -101,16 +101,24 @@ export function assemblyApi({ apiKey, token: tokenString }) { ) throw new Error('Unable to authorize Assembly SDK.') } - if (isDebug) { - console.log(`Authorizing with key: ${key}`) - } // TEMPORARY FIX: suppress sending tokenId to auth header if ASSEMBLY_SUPPRESS_TOKEN_ID is set const suppressTokenId = !!process.env.ASSEMBLY_SUPPRESS_TOKEN_ID + if (suppressTokenId) { - const keySections = key.split('/') - key = `${keySections[0]}/${keySections[1]}` - SDK_VERSION = undefined // looks like this is being used to enable/disable expiry. Drop this just in case. + const [org, project] = key.split('/') + + if (!org || !project) { + throw new Error(`Invalid auth header`) + } + + key = `${org}/${project}` + // disable SDK version to prevent expiry logic from triggering (?) + SDK_VERSION = undefined + } + + if (isDebug) { + console.log(`Authorizing with key: ${key}`) } OpenAPI.HEADERS = { From fc4a267be36aded409019243f370bee563f24ea8 Mon Sep 17 00:00:00 2001 From: Rojan Rajbhandari Date: Thu, 19 Feb 2026 16:57:36 +0545 Subject: [PATCH 7/7] fix(OUT-3169): await assembly promise --- src/utils/copilotAPI.ts | 102 ++++++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 40 deletions(-) diff --git a/src/utils/copilotAPI.ts b/src/utils/copilotAPI.ts index a6ab93a..e1c8393 100644 --- a/src/utils/copilotAPI.ts +++ b/src/utils/copilotAPI.ts @@ -52,10 +52,10 @@ import httpStatus from 'http-status' import { MAX_INVOICE_LIST_LIMIT } from '@/app/api/core/constants/limit' export class CopilotAPI { - apiClient: SDK + assemblyPromise: SDK constructor(private token: string) { - this.apiClient = assemblyApi({ apiKey, token }) + this.assemblyPromise = assemblyApi({ apiKey, token }) } private async manualFetch( @@ -88,7 +88,8 @@ export class CopilotAPI { // Get Token Payload from copilot request token async _getTokenPayload(): Promise { - const getTokenPayload = this.apiClient.getTokenPayload + const assembly = await this.assemblyPromise + const getTokenPayload = assembly.getTokenPayload if (!getTokenPayload) { console.error( `CopilotAPI#getTokenPayload | Could not parse token payload for token ${this.token}`, @@ -100,24 +101,25 @@ export class CopilotAPI { } async _me(): Promise { + const assembly = await this.assemblyPromise + console.info('CopilotAPI#me | token =', this.token) const tokenPayload = await this.getTokenPayload() const id = tokenPayload?.internalUserId || tokenPayload?.clientId if (!tokenPayload || !id) return null const retrieveCurrentUserInfo = tokenPayload.internalUserId - ? this.apiClient.retrieveInternalUser - : this.apiClient.retrieveClient + ? assembly.retrieveInternalUser + : assembly.retrieveClient const currentUserInfo = await retrieveCurrentUserInfo({ id }) return MeResponseSchema.parse(currentUserInfo) } async _getWorkspace(): Promise { + const assembly = await this.assemblyPromise console.info('CopilotAPI#getWorkspace | token =', this.token) - return WorkspaceResponseSchema.parse( - await this.apiClient.retrieveWorkspace(), - ) + return WorkspaceResponseSchema.parse(await assembly.retrieveWorkspace()) } async _getClientTokenPayload(): Promise { @@ -140,9 +142,11 @@ export class CopilotAPI { requestBody: ClientRequest, sendInvite: boolean = false, ): Promise { + const assembly = await this.assemblyPromise + console.info('CopilotAPI#createClient | token =', this.token) return ClientResponseSchema.parse( - await this.apiClient.createClient({ sendInvite, requestBody }), + await assembly.createClient({ sendInvite, requestBody }), ) } @@ -151,11 +155,10 @@ export class CopilotAPI { * Error handling: if copilot throws NOT FOUND error or BAD REQUEST error, return undefined. This is done as we don't want to terminate the process */ async _getClient(id: string): Promise { + const assembly = await this.assemblyPromise try { console.info('CopilotAPI#getClient | token =', this.token) - return ClientResponseSchema.parse( - await this.apiClient.retrieveClient({ id }), - ) + return ClientResponseSchema.parse(await assembly.retrieveClient({ id })) } catch (error: unknown) { if ( typeof error === 'object' && @@ -182,9 +185,10 @@ export class CopilotAPI { * Error handling: if copilot throws NOT FOUND error or BAD REQUEST error, return undefined. This is done as we don't want to terminate the process */ async _getClients(args: CopilotListArgs & { companyId?: string } = {}) { + const assembly = await this.assemblyPromise try { console.info('CopilotAPI#getClients | token =', this.token) - return ClientsResponseSchema.parse(await this.apiClient.listClients(args)) + return ClientsResponseSchema.parse(await assembly.listClients(args)) } catch (error: unknown) { if ( typeof error === 'object' && @@ -210,21 +214,25 @@ export class CopilotAPI { id: string, requestBody: ClientRequest, ): Promise { + const assembly = await this.assemblyPromise console.info('CopilotAPI#updateClient | token =', this.token) return ClientResponseSchema.parse( - await this.apiClient.updateClient({ id, requestBody }), + await assembly.updateClient({ id, requestBody }), ) } async _deleteClient(id: string) { + const assembly = await this.assemblyPromise console.info('CopilotAPI#deleteClient | token =', this.token) - return await this.apiClient.deleteClient({ id }) + return await assembly.deleteClient({ id }) } async _createCompany(requestBody: CompanyCreateRequest) { + const assembly = await this.assemblyPromise + console.info('CopilotAPI#createCompany | token =', this.token) return CompanyResponseSchema.parse( - await this.apiClient.createCompany({ requestBody }), + await assembly.createCompany({ requestBody }), ) } @@ -233,11 +241,11 @@ export class CopilotAPI { * Error handling: if copilot throws NOT FOUND error or BAD REQUEST error, return undefined. This is done as we don't want to terminate the process */ async _getCompany(id: string): Promise { + const assembly = await this.assemblyPromise + try { console.info('CopilotAPI#getCompany | token =', this.token) - return CompanyResponseSchema.parse( - await this.apiClient.retrieveCompany({ id }), - ) + return CompanyResponseSchema.parse(await assembly.retrieveCompany({ id })) } catch (error: unknown) { if ( typeof error === 'object' && @@ -260,10 +268,10 @@ export class CopilotAPI { } async _getCompanies(args: CopilotListArgs = {}): Promise { + const assembly = await this.assemblyPromise + console.info('CopilotAPI#getCompanies | token =', this.token) - return CompaniesResponseSchema.parse( - await this.apiClient.listCompanies(args), - ) + return CompaniesResponseSchema.parse(await assembly.listCompanies(args)) } async _getCompanyClients(companyId: string): Promise { @@ -272,43 +280,48 @@ export class CopilotAPI { } async _getCustomFields(): Promise { + const assembly = await this.assemblyPromise + console.info('CopilotAPI#getCustomFields | token =', this.token) - return CustomFieldResponseSchema.parse( - await this.apiClient.listCustomFields({}), - ) + return CustomFieldResponseSchema.parse(await assembly.listCustomFields({})) } async _getInternalUsers( args: CopilotListArgs = {}, ): Promise { + const assembly = await this.assemblyPromise + console.info('CopilotAPI#getInternalUsers | token =', this.token) return InternalUsersResponseSchema.parse( - await this.apiClient.listInternalUsers(args), + await assembly.listInternalUsers(args), ) } async _getInternalUser(id: string): Promise { + const assembly = await this.assemblyPromise console.info('CopilotAPI#getInternalUser | token =', this.token) return InternalUsersSchema.parse( - await this.apiClient.retrieveInternalUser({ id }), + await assembly.retrieveInternalUser({ id }), ) } async _createNotification( requestBody: NotificationRequestBody, ): Promise { + const assembly = await this.assemblyPromise console.info('CopilotAPI#createNotification | token =', this.token) console.info('CopilotAPI#createNotification | requestBody =', requestBody) return NotificationCreatedResponseSchema.parse( - await this.apiClient.createNotification({ + await assembly.createNotification({ requestBody, }), ) } async _markNotificationAsRead(id: string): Promise { + const assembly = await this.assemblyPromise console.info('CopilotAPI#markNotificationAsRead | token =', this.token) - await this.apiClient.markNotificationRead({ id }) + await assembly.markNotificationRead({ id }) } async _bulkMarkNotificationsAsRead(notificationIds: string[]): Promise { @@ -335,8 +348,10 @@ export class CopilotAPI { } async _deleteNotification(id: string): Promise { + const assembly = await this.assemblyPromise + console.info('CopilotAPI#deleteNotification | token =', this.token) - await this.apiClient.deleteNotification({ id }) + await assembly.deleteNotification({ id }) } async _bulkDeleteNotifications(notificationIds: string[]): Promise { @@ -383,10 +398,10 @@ export class CopilotAPI { } async _getProduct(id: string): Promise { + const assembly = await this.assemblyPromise + console.info('CopilotAPI#getProduct | token =', this.token) - return ProductResponseSchema.parse( - await this.apiClient.retrieveProduct({ id }), - ) + return ProductResponseSchema.parse(await assembly.retrieveProduct({ id })) } async _getProducts( @@ -394,15 +409,18 @@ export class CopilotAPI { nextToken?: string, limit?: number, ): Promise { + const assembly = await this.assemblyPromise + console.info('CopilotAPI#getProducts | token =', this.token) return ProductsResponseSchema.parse( - await this.apiClient.listProducts({ name, nextToken, limit }), + await assembly.listProducts({ name, nextToken, limit }), ) } async _getPrice(id: string): Promise { + const assembly = await this.assemblyPromise console.info('CopilotAPI#getPrice | token =', this.token) - return PriceResponseSchema.parse(await this.apiClient.retrievePrice({ id })) + return PriceResponseSchema.parse(await assembly.retrievePrice({ id })) } async _getPrices( @@ -410,17 +428,19 @@ export class CopilotAPI { nextToken?: string, limit?: string, ): Promise { + const assembly = await this.assemblyPromise + console.info('CopilotAPI#getPrices | token =', this.token) return PricesResponseSchema.parse( - await this.apiClient.listPrices({ productId, nextToken, limit }), + await assembly.listPrices({ productId, nextToken, limit }), ) } async _getInvoice(id: string): Promise { + const assembly = await this.assemblyPromise + console.info('CopilotAPI#getInvoice | token =', this.token) - return InvoiceResponseSchema.parse( - await this.apiClient.retrieveInvoice({ id }), - ) + return InvoiceResponseSchema.parse(await assembly.retrieveInvoice({ id })) } async _getInvoices( @@ -440,9 +460,11 @@ export class CopilotAPI { } async _getPayments(invoiceId: string): Promise { + const assembly = await this.assemblyPromise + console.info('CopilotAPI#getPayments | token =', this.token) return PaymentsResponseSchema.parse( - await this.apiClient.listPayments({ invoiceId }), + await assembly.listPayments({ invoiceId }), ) }