{error}
diff --git a/packages/frontend/lib/types.ts b/packages/frontend/lib/types.ts
index 2870e3bc9d1..ef351cbb721 100644
--- a/packages/frontend/lib/types.ts
+++ b/packages/frontend/lib/types.ts
@@ -6,7 +6,8 @@ export type AuthErrorType =
| 'missingCredentials'
| 'windowClosed'
| 'request_error'
- | 'missing_ws_client_id';
+ | 'missing_ws_client_id'
+ | 'connection_test_failed';
export interface AuthResult {
providerConfigKey: string;
diff --git a/packages/server/lib/controllers/config/getListIntegrations.integration.test.ts b/packages/server/lib/controllers/config/getListIntegrations.integration.test.ts
index 56386f8bfb4..6544762acf7 100644
--- a/packages/server/lib/controllers/config/getListIntegrations.integration.test.ts
+++ b/packages/server/lib/controllers/config/getListIntegrations.integration.test.ts
@@ -67,6 +67,7 @@ describe(`GET ${endpoint}`, () => {
{
provider: 'github',
unique_key: 'github',
+ display_name: 'GitHub',
logo: 'http://localhost:3003/images/template-logos/github.svg',
created_at: expect.toBeIsoDate(),
updated_at: expect.toBeIsoDate()
diff --git a/packages/server/lib/controllers/config/getListIntegrations.ts b/packages/server/lib/controllers/config/getListIntegrations.ts
index a9f121d0014..baf739c9e0e 100644
--- a/packages/server/lib/controllers/config/getListIntegrations.ts
+++ b/packages/server/lib/controllers/config/getListIntegrations.ts
@@ -1,7 +1,7 @@
import { asyncWrapper } from '../../utils/asyncWrapper.js';
import { requireEmptyQuery, zodErrorToHTTP } from '@nangohq/utils';
import type { GetPublicListIntegrationsLegacy } from '@nangohq/types';
-import { configService } from '@nangohq/shared';
+import { configService, getProviders } from '@nangohq/shared';
import { integrationToPublicApi } from '../../formatters/integration.js';
export const getPublicListIntegrationsLegacy = asyncWrapper
(async (req, res) => {
@@ -13,8 +13,15 @@ export const getPublicListIntegrationsLegacy = asyncWrapper {
- return integrationToPublicApi(config);
+ return integrationToPublicApi({ integration: config, provider: providers[config.provider]! });
});
res.status(200).send({ configs: results });
diff --git a/packages/server/lib/controllers/integrations/getListIntegrations.integration.test.ts b/packages/server/lib/controllers/integrations/getListIntegrations.integration.test.ts
index 92fc882e292..a248fb086f7 100644
--- a/packages/server/lib/controllers/integrations/getListIntegrations.integration.test.ts
+++ b/packages/server/lib/controllers/integrations/getListIntegrations.integration.test.ts
@@ -67,6 +67,7 @@ describe(`GET ${endpoint}`, () => {
{
provider: 'github',
unique_key: 'github',
+ display_name: 'GitHub',
logo: 'http://localhost:3003/images/template-logos/github.svg',
created_at: expect.toBeIsoDate(),
updated_at: expect.toBeIsoDate()
diff --git a/packages/server/lib/controllers/integrations/getListIntegrations.ts b/packages/server/lib/controllers/integrations/getListIntegrations.ts
index 7c1077a2374..f13fa7fe5a6 100644
--- a/packages/server/lib/controllers/integrations/getListIntegrations.ts
+++ b/packages/server/lib/controllers/integrations/getListIntegrations.ts
@@ -1,7 +1,7 @@
import { asyncWrapper } from '../../utils/asyncWrapper.js';
import { requireEmptyQuery, zodErrorToHTTP } from '@nangohq/utils';
import type { GetPublicListIntegrations } from '@nangohq/types';
-import { configService } from '@nangohq/shared';
+import { configService, getProviders } from '@nangohq/shared';
import { integrationToPublicApi } from '../../formatters/integration.js';
export const getPublicListIntegrations = asyncWrapper(async (req, res) => {
@@ -14,9 +14,15 @@ export const getPublicListIntegrations = asyncWrapper
const { environment } = res.locals;
const configs = await configService.listProviderConfigs(environment.id);
+ const providers = getProviders();
+ if (!providers) {
+ res.status(500).send({ error: { code: 'server_error', message: `failed to load providers` } });
+ return;
+ }
+
res.status(200).send({
data: configs.map((config) => {
- return integrationToPublicApi(config);
+ return integrationToPublicApi({ integration: config, provider: providers[config.provider]! });
})
});
});
diff --git a/packages/server/lib/controllers/integrations/uniqueKey/getIntegration.integration.test.ts b/packages/server/lib/controllers/integrations/uniqueKey/getIntegration.integration.test.ts
index 9e6f4aec190..da84ec29f1a 100644
--- a/packages/server/lib/controllers/integrations/uniqueKey/getIntegration.integration.test.ts
+++ b/packages/server/lib/controllers/integrations/uniqueKey/getIntegration.integration.test.ts
@@ -66,6 +66,7 @@ describe(`GET ${endpoint}`, () => {
data: {
provider: 'github',
unique_key: 'github',
+ display_name: 'GitHub',
logo: 'http://localhost:3003/images/template-logos/github.svg',
created_at: expect.toBeIsoDate(),
updated_at: expect.toBeIsoDate()
diff --git a/packages/server/lib/controllers/integrations/uniqueKey/getIntegration.ts b/packages/server/lib/controllers/integrations/uniqueKey/getIntegration.ts
index bbf1e39acc6..30047ad6369 100644
--- a/packages/server/lib/controllers/integrations/uniqueKey/getIntegration.ts
+++ b/packages/server/lib/controllers/integrations/uniqueKey/getIntegration.ts
@@ -59,6 +59,6 @@ export const getPublicIntegration = asyncWrapper(async (re
}
res.status(200).send({
- data: integrationToPublicApi(integration, include)
+ data: integrationToPublicApi({ integration, include, provider })
});
});
diff --git a/packages/server/lib/formatters/integration.ts b/packages/server/lib/formatters/integration.ts
index 8eb685173ed..e06487b7286 100644
--- a/packages/server/lib/formatters/integration.ts
+++ b/packages/server/lib/formatters/integration.ts
@@ -1,4 +1,4 @@
-import type { ApiIntegration, ApiPublicIntegration, ApiPublicIntegrationInclude, IntegrationConfig } from '@nangohq/types';
+import type { ApiIntegration, ApiPublicIntegration, ApiPublicIntegrationInclude, IntegrationConfig, Provider } from '@nangohq/types';
import { basePublicUrl } from '@nangohq/utils';
export function integrationToApi(data: IntegrationConfig): ApiIntegration {
@@ -9,13 +9,22 @@ export function integrationToApi(data: IntegrationConfig): ApiIntegration {
};
}
-export function integrationToPublicApi(data: IntegrationConfig, include?: ApiPublicIntegrationInclude): ApiPublicIntegration {
+export function integrationToPublicApi({
+ integration,
+ include,
+ provider
+}: {
+ integration: IntegrationConfig;
+ provider: Provider;
+ include?: ApiPublicIntegrationInclude;
+}): ApiPublicIntegration {
return {
- unique_key: data.unique_key,
- provider: data.provider,
- logo: `${basePublicUrl}/images/template-logos/${data.provider}.svg`,
+ unique_key: integration.unique_key,
+ provider: integration.provider,
+ display_name: provider.display_name,
+ logo: `${basePublicUrl}/images/template-logos/${integration.provider}.svg`,
...include,
- created_at: data.created_at.toISOString(),
- updated_at: data.updated_at.toISOString()
+ created_at: integration.created_at.toISOString(),
+ updated_at: integration.updated_at.toISOString()
};
}
diff --git a/packages/shared/flows.yaml b/packages/shared/flows.yaml
index 5a1524d9ef9..bbff3af00c9 100644
--- a/packages/shared/flows.yaml
+++ b/packages/shared/flows.yaml
@@ -23,25 +23,25 @@ integrations:
Creates an ephemeral transaction in Anrok.
input: Transaction
output: TransactionActionResponse
- endpoint: POST /ephmeral-transactions
+ endpoint: POST /ephmeral-transaction
create-or-update-transaction:
description: |
Creates or updates a transaction in Anrok.
input: Transaction[]
output: TransactionActionResponse
- endpoint: POST /transactions
+ endpoint: POST /transaction
void-transaction:
description: |
Voids a transaction in Anrok.
input: TransactionToDelete[]
output: TransactionDeletionActionResponse
- endpoint: POST /transactions/void
+ endpoint: POST /transaction/voide
negate-transaction:
description: |
Creates a negation in Anrok.
input: TransactionToNegate[]
output: TransactionNegationActionResponse
- endpoint: POST /transactions/negate
+ endpoint: POST /transaction/negate
models:
AnrokAddress:
line1: string
@@ -142,42 +142,42 @@ integrations:
runs: every hour
description: Retrieve all tasks that exist in the workspace
output: Task
- endpoint: GET /tasks
+ endpoint: GET /ticketing/tasks
sync_type: incremental
users:
runs: every hour
description: Retrieve all users that exist in the workspace
output: User
- endpoint: GET /users
+ endpoint: GET /ticketing/users
sync_type: incremental
workspaces:
runs: every hour
description: Retrieve all workspaces for a user
output: AsanaWorkspace
- endpoint: GET /workspaces
+ endpoint: GET /ticketing/workspaces
projects:
runs: every hour
description: Retrieves all projects for a user
output: AsanaProject
- endpoint: GET /projects
+ endpoint: GET /ticketing/projects
actions:
fetch-workspaces:
description: >-
Fetch the workspaces with a limit (default 10) of a user to allow them
to selection of projects to sync
- endpoint: GET /workspaces/limit
+ endpoint: GET /ticketing/workspaces/limit
output: BaseAsanaModel[]
input: Limit
fetch-projects:
description: >-
Fetch the projects with a limit (default 10) given a workspace of a
user to allow selection when choosing the tasks to sync.
- endpoint: GET /projects/limit
+ endpoint: GET /ticketing/projects/limit
output: BaseAsanaModel[]
input: AsanaProjectInput
create-task:
input: CreateAsanaTask
- endpoint: POST /tasks
+ endpoint: POST /ticketing/task
output: Task
description: >
Create a task using Asana specific fields and return a unified model
@@ -186,11 +186,11 @@ integrations:
update-task:
description: Update a task and be able to assign the task to a specific user
input: AsanaUpdateTask
- endpoint: PATCH /tasks
+ endpoint: PATCH /ticketing/task
output: Task
delete-task:
input: Id
- endpoint: DELETE /tasks
+ endpoint: DELETE /ticketing/task
output: boolean
models:
Id:
@@ -311,7 +311,7 @@ integrations:
Fetches a list of all candidates from your ashby account
scopes: candidatelastsyncToken
sync_type: incremental
- endpoint: GET /candidates
+ endpoint: GET /ashby/candidates
jobs:
runs: every hour
output: AshbyJob
@@ -319,20 +319,20 @@ integrations:
Fetches a list of all jobs from your ashby account
scopes: jobslastsyncToken
sync_type: incremental
- endpoint: GET /jobs
+ endpoint: GET /ashby/jobs
actions:
create-application:
output: AshbyCreateApplicationResponse
input: AshbyCreateCandidateInput
description: |
Action to consider a candidate for a job
- endpoint: POST /applications
+ endpoint: POST /ashby/create-application
create-note:
output: AshbyCreateNoteResponse
input: AshbyCreateNoteInput
description: |
Action to create a note on a candidate.
- endpoint: POST /notes
+ endpoint: POST /ashby/create-note
models:
AshbyCandidate:
id: string
@@ -485,22 +485,22 @@ integrations:
Fetches a list of current employees from bamboohr
output: BamboohrEmployee
sync_type: incremental
- endpoint: GET /employees
+ endpoint: GET /bamboohr/employees
actions:
create-employee:
description: |
Action to create a new employee
output: BamboohrCreateEmployeeResponse
input: BamboohrCreateEmployee
- endpoint: POST /employees
+ endpoint: POST /bamboohr/create-employee
version: 1.0.0
update-employee:
- endpoint: PUT /employees
+ endpoint: PUT /bamboohr/employee
input: BamboohrUpdateEmployee
output: BamboohrResponseStatus
description: Update an existing employee in the system
fetch-fields:
- endpoint: GET /fields
+ endpoint: GET /bamboohr/fields
output: BamboohrField[]
description: Introspection to retrieve available fields
models:
@@ -1118,7 +1118,7 @@ integrations:
Fetches a list of calls from your account. For the first sync, it will
go back to the past one year
sync_type: incremental
- endpoint: GET /calls
+ endpoint: GET /clari-copilot/call
models:
ClariCopilotCall:
id: string
@@ -1177,7 +1177,7 @@ integrations:
Fetches a list of spaces from confluence
sync_type: full
scopes: read:space:confluence
- endpoint: GET /spaces
+ endpoint: GET /confluence/spaces
pages:
runs: every 4 hours
output: ConfluencePage
@@ -1185,7 +1185,7 @@ integrations:
Fetches a list of pages from confluence
sync_type: full
scopes: read:page:confluence
- endpoint: GET /pages
+ endpoint: GET /confluence/pages
models:
ConfluenceSpace:
id: string
@@ -1222,7 +1222,7 @@ integrations:
active-users:
description: |
Fetches a list of active users from Discourse.
- endpoint: /users
+ endpoint: /discourse/active-users
sync_type: full
runs: every 1 hour
output: User
@@ -3433,7 +3433,7 @@ integrations:
output: Customer
sync_type: incremental
scopes: com.intuit.quickbooks.accounting
- endpoint: GET /quickbooks/customers
+ endpoint: GET /customers
accounts:
description: >
Fetches all accounts in QuickBooks. Handles both active and archived
@@ -3442,7 +3442,7 @@ integrations:
output: Account
sync_type: incremental
scopes: com.intuit.quickbooks.accounting
- endpoint: GET /quickbooks/accounts
+ endpoint: GET /accounts
payments:
description: >
Fetches all payments in QuickBooks. Handles both active and voided
@@ -3451,7 +3451,7 @@ integrations:
output: Payment
sync_type: incremental
scopes: com.intuit.quickbooks.accounting
- endpoint: GET /quickbooks/payments
+ endpoint: GET /payments
items:
description: >
Fetches all items in QuickBooks. Handles both active and archived
@@ -3460,7 +3460,7 @@ integrations:
output: Item
sync_type: incremental
scopes: com.intuit.quickbooks.accounting
- endpoint: GET /quickbooks/items
+ endpoint: GET /items
invoices:
description: >
Fetches all invoices in QuickBooks. Handles both active and voided
@@ -3469,7 +3469,7 @@ integrations:
output: Invoice
sync_type: incremental
scopes: com.intuit.quickbooks.accounting
- endpoint: GET /quickbooks/invoices
+ endpoint: GET /invoices
actions:
create-customer:
description: |
@@ -3477,77 +3477,77 @@ integrations:
input: CreateCustomer
scopes: com.intuit.quickbooks.accounting
output: Customer
- endpoint: POST /quickbooks/customer
+ endpoint: POST /customers
update-customer:
description: |
Update a single customer in QuickBooks.
input: UpdateCustomer
scopes: com.intuit.quickbooks.accounting
output: Customer
- endpoint: PUT /quickbooks/customer
+ endpoint: PUT /customers
create-item:
description: |
Creates a single item in QuickBooks.
input: CreateItem
scopes: com.intuit.quickbooks.accounting
output: Item
- endpoint: POST /quickbooks/item
+ endpoint: POST /items
update-item:
description: |
Update a single item in QuickBooks.
input: UpdateItem
scopes: com.intuit.quickbooks.accounting
output: Item
- endpoint: PUT /quickbooks/item
+ endpoint: PUT /items
create-account:
description: |
Creates a single account in QuickBooks.
input: CreateAccount
scopes: com.intuit.quickbooks.accounting
output: Account
- endpoint: POST /quickbooks/account
+ endpoint: POST /accounts
update-account:
description: |
Updates a single account in QuickBooks.
input: UpdateAccount
scopes: com.intuit.quickbooks.accounting
output: Account
- endpoint: PUT /quickbooks/account
+ endpoint: PUT /accounts
create-invoice:
description: |
Creates a single invoice in QuickBooks.
input: CreateInvoice
scopes: com.intuit.quickbooks.accounting
output: Invoice
- endpoint: POST /quickbooks/invoice
+ endpoint: POST /invoices
update-invoice:
description: |
Updates a single invoice in QuickBooks.
input: UpdateInvoice
scopes: com.intuit.quickbooks.accounting
output: Invoice
- endpoint: PUT /quickbooks/invoice
+ endpoint: PUT /invoices
create-credit-memo:
description: |
Creates a single credit memo in QuickBooks.
input: CreateCreditMemo
scopes: com.intuit.quickbooks.accounting
output: CreditMemo
- endpoint: POST /quickbooks/credit-memo
+ endpoint: POST /credit-memos
update-credit-memo:
description: |
Updates a single credit memo in QuickBooks.
input: UpdateCreditMemo
scopes: com.intuit.quickbooks.accounting
output: CreditMemo
- endpoint: PUT /quickbooks/credit-memo
+ endpoint: PUT /credit-memos
create-payment:
description: |
Creates a single payment in QuickBooks.
input: CreatePayment
scopes: com.intuit.quickbooks.accounting
output: Payment
- endpoint: POST /quickbooks/payment
+ endpoint: POST /payments
models:
Updates:
id: string
@@ -3800,7 +3800,6 @@ integrations:
description: |
Fetches a list of articles from salesforce
output: SalesforceArticle
- auto_start: false
sync_type: incremental
endpoint: GET /salesforce/articles
tickets:
@@ -4715,7 +4714,7 @@ integrations:
runs: every hour
output: Contact
sync_type: incremental
- endpoint: GET /xero/contacts
+ endpoint: GET /contacts
accounts:
description: >
Fetches all accounts in Xero (chart of accounts). Incremental sync,
@@ -4724,7 +4723,7 @@ integrations:
scopes: accounting.settings
output: Account
sync_type: incremental
- endpoint: GET /xero/accounts
+ endpoint: GET /accounts
items:
description: >
Fetches all items in Xero. Incremental sync, does not detect deletes,
@@ -4735,7 +4734,7 @@ integrations:
scopes: accounting.settings
output: Item
sync_type: incremental
- endpoint: GET /xero/items
+ endpoint: GET /items
invoices:
description: |
Fetches all invoices in Xero. Incremental sync.
@@ -4743,7 +4742,7 @@ integrations:
scopes: accounting.transactions
output: Invoice
sync_type: incremental
- endpoint: GET /xero/invoices
+ endpoint: GET /invoices
payments:
description: |
Fetches all payments in Xero. Incremental sync.
@@ -4751,7 +4750,7 @@ integrations:
scopes: accounting.transactions
output: Payment
sync_type: incremental
- endpoint: GET /xero/payments
+ endpoint: GET /payments
actions:
create-contact:
description: |
@@ -4760,7 +4759,7 @@ integrations:
input: CreateContact[]
scopes: accounting.contacts
output: ContactActionResponse
- endpoint: POST /xero/contacts
+ endpoint: POST /contacts
update-contact:
description: >
Updates one or multiple contacts in Xero. Only fields that are passed
@@ -4769,7 +4768,7 @@ integrations:
input: Contact[]
scopes: accounting.contacts
output: ContactActionResponse
- endpoint: PUT /xero/contacts
+ endpoint: PUT /contacts
create-invoice:
description: |
Creates one or more invoices in Xero.
@@ -4777,7 +4776,7 @@ integrations:
input: CreateInvoice[]
scopes: accounting.transactions
output: InvoiceActionResponse
- endpoint: POST /xero/invoices
+ endpoint: POST /invoices
version: 1.0.0
update-invoice:
description: |
@@ -4788,7 +4787,7 @@ integrations:
input: UpdateInvoice[]
scopes: accounting.transactions
output: InvoiceActionResponse
- endpoint: PUT /xero/invoices
+ endpoint: PUT /invoices
version: 1.0.0
create-credit-note:
description: |
@@ -4797,14 +4796,14 @@ integrations:
input: CreditNote[]
scopes: accounting.transactions
output: CreditNoteActionResponse
- endpoint: POST /xero/creditnotes
+ endpoint: POST /creditnotes
update-credit-note:
description: |
Updates one or more credit notes in Xero.
input: CreditNote[]
scopes: accounting.transactions
output: CreditNoteActionResponse
- endpoint: PUT /xero/creditnotes
+ endpoint: PUT /creditnotes
create-payment:
description: |
Creates one or more payments in Xero.
@@ -4812,7 +4811,7 @@ integrations:
scopes: accounting.transactions
input: CreatePayment[]
output: PaymentActionResponse
- endpoint: POST /xero/payments
+ endpoint: POST /payments
create-item:
description: |
Creates one or more items in Xero.
@@ -4820,14 +4819,14 @@ integrations:
scopes: accounting.settings
input: Item[]
output: ItemActionResponse
- endpoint: POST /xero/items
+ endpoint: POST /items
update-item:
description: |
Updates one or more items in Xero.
scopes: accounting.settings
input: Item[]
output: ItemActionResponse
- endpoint: PUT /xero/items
+ endpoint: PUT /items
models:
ActionErrorResponse:
message: string
diff --git a/packages/types/lib/integration/api.ts b/packages/types/lib/integration/api.ts
index 8ad257e1cf8..86134f5ab4e 100644
--- a/packages/types/lib/integration/api.ts
+++ b/packages/types/lib/integration/api.ts
@@ -10,6 +10,7 @@ import type { SyncType } from '../scripts/syncs/api';
export type ApiPublicIntegration = Merge, ApiTimestamps> & {
logo: string;
+ display_name: string;
} & ApiPublicIntegrationInclude;
export interface ApiPublicIntegrationInclude {
webhook_url?: string | null;