diff --git a/CHANGELOG.md b/CHANGELOG.md index c89be9a4..1a0fdb6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ### 7.0.0-beta.3 / TBD * Added support for the free-busy endpoint +* Added support for native/custom authentication +* Added support for Connectors & Credentials APIs * Fix `getAvailability` response type * Fix path for destroying a redirect URI * Fix model for updating an Event diff --git a/src/models/auth.ts b/src/models/auth.ts index 2c0794cb..c944bb65 100644 --- a/src/models/auth.ts +++ b/src/models/auth.ts @@ -6,7 +6,7 @@ type AccessType = 'online' | 'offline'; /** * Type for the different OAuth providers Nylas supports. */ -export type Provider = 'google' | 'imap' | 'microsoft'; +export type Provider = 'google' | 'imap' | 'microsoft' | 'virtual-calendar'; /** * Configuration for generating a URL for OAuth 2.0 authentication. diff --git a/src/models/connectors.ts b/src/models/connectors.ts new file mode 100644 index 00000000..ea91e129 --- /dev/null +++ b/src/models/connectors.ts @@ -0,0 +1,143 @@ +import { Provider } from './auth.js'; +import { ListQueryParams } from './listQueryParams.js'; + +/** + * Interface representing the Nylas connector response. + */ +export interface Connector { + /** + * Custom name of the connector + */ + name: string; + /** + * The provider type + */ + provider: Provider; + /** + * Optional settings from provider + */ + settings?: Record; + /** + * Default scopes for the connector + */ + scope?: string[]; +} + +/** + * Interface representing a Google connector creation request. + */ +export interface GoogleCreateConnectorSettings { + /** + * The Google Client ID + */ + clientId: string; + /** + * The Google Client Secret + */ + clientSecret: string; + /** + * The Google Pub/Sub topic name + */ + topicName?: string; +} + +/** + * Interface representing a Microsoft connector creation request. + */ +export interface MicrosoftCreateConnectorSettings { + /** + * The Microsoft Client ID + */ + clientId: string; + /** + * The Microsoft Client Secret + */ + clientSecret: string; + /** + * The Microsoft tenant ID + */ + tenant?: string; +} + +/** + * Interface representing the base Nylas connector creation request. + */ +interface BaseCreateConnectionRequest { + /** + * Custom name of the connector + */ + name: string; + /** + * The provider type + */ + provider: Provider; +} + +/** + * Interface representing the base Nylas connector creation request. + */ +export interface GoogleCreateConnectorRequest + extends BaseCreateConnectionRequest { + /** + * The Google OAuth provider credentials and settings + */ + settings: GoogleCreateConnectorSettings; + /** + * The Google OAuth scopes + */ + scope?: string[]; +} + +export interface MicrosoftCreateConnectorRequest + extends BaseCreateConnectionRequest { + /** + * The Microsoft OAuth provider credentials and settings + */ + settings: MicrosoftCreateConnectorSettings; + /** + * The Microsoft OAuth scopes + */ + scope?: string[]; +} + +/** + * Interface representing the base Nylas connector creation request. + */ +export type ImapCreateConnectorRequest = BaseCreateConnectionRequest; + +/** + * Interface representing the base Nylas connector creation request. + */ +export type VirtualCalendarsCreateConnectorRequest = BaseCreateConnectionRequest; + +/** + * The type of the Nylas connector creation request. + */ +export type CreateConnectorRequest = + | GoogleCreateConnectorRequest + | MicrosoftCreateConnectorRequest + | ImapCreateConnectorRequest + | VirtualCalendarsCreateConnectorRequest; + +/** + * Interface representing the base Nylas connector creation request. + */ +export interface UpdateConnectorRequest { + /** + * Custom name of the connector + */ + name?: string; + /** + * The OAuth provider credentials and settings + */ + settings?: Record; + /** + * The OAuth scopes + */ + scope?: string[]; +} + +/** + * Interface of the query parameters for listing connectors. + */ +export type ListConnectorsQueryParams = ListQueryParams; diff --git a/src/models/credentials.ts b/src/models/credentials.ts new file mode 100644 index 00000000..ce2e60e3 --- /dev/null +++ b/src/models/credentials.ts @@ -0,0 +1,168 @@ +/** + * Interface representing a Nylas Credential object. + */ +export interface Credential { + /** + * Globally unique object identifier + */ + id: string; + /** + * Name of the credential + */ + name: string; + /** + * The type of credential + */ + credentialType?: CredentialType; + /** + * Hashed value of the credential that you created + */ + hashedData?: string; + /** + * Timestamp of when the credential was created + */ + createdAt?: number; + /** + * Timestamp of when the credential was updated + */ + updatedAt?: number; +} + +/** + * Interface representing additional data needed to create a credential for Microsoft Admin Consent + */ +export interface MicrosoftAdminConsentSettings { + clientId: string; + clientSecret: string; + [key: string]: string; +} + +/** + * Interface representing additional data needed to create a credential for Google Service Account + */ +export interface GoogleServiceAccountCredential { + privateKeyId: string; + privateKey: string; + clientEmail: string; + [key: string]: string; +} + +/** + * Interface representing additional data needed to create a credential for a Connector Override + */ +export type ConnectorOverrideCredential = Record; + +/** + * Type representing the data needed to create a credential + */ +export type CredentialData = + | MicrosoftAdminConsentSettings + | GoogleServiceAccountCredential + | ConnectorOverrideCredential; + +/** + * Interface representing a request to create a Microsoft Admin Consent credential + */ +export interface CreateMicrosoftCredentialRequest { + /** + * Unique name of this credential + */ + name: string; + /** + * Type of credential for the admin consent flow + */ + credentialType: CredentialType.ADMINCONSENT; + /** + * Data that specifies some special data required for this credential + */ + credentialData: MicrosoftAdminConsentSettings; +} + +/** + * Interface representing a request to create a Google Service Account credential + */ +export interface CreateGoogleCredentialRequest { + /** + * Unique name of this credential + */ + name: string; + /** + * Type of credential for the app permission flow + */ + credentialType: CredentialType.SERVICEACCOUNT; + /** + * Data that specifies some special data required for this credential + */ + credentialData: GoogleServiceAccountCredential; +} + +/** + * Interface representing a request to create a Connector Override credential + */ +export interface CreateOverrideCredentialRequest { + /** + * Unique name of this credential + */ + name: string; + /** + * Type of credential to force the override of a connector's client values + */ + credentialType: CredentialType.CONNECTOR; + /** + * Data that specifies some special data required for this credential + */ + credentialData: ConnectorOverrideCredential; +} + +/** + * Interface representing a request to create a credential + */ +export type CreateCredentialRequest = + | CreateMicrosoftCredentialRequest + | CreateGoogleCredentialRequest + | CreateOverrideCredentialRequest; + +/** + * Interface representing a request to update a credential + */ +export interface UpdateCredentialRequest { + /** + * Unique name of this credential + */ + name?: string; + /** + * Data that specifies some special data required for this credential + */ + credentialData?: CredentialData; +} + +/** + * Enum representing the type of credential + */ +export enum CredentialType { + ADMINCONSENT = 'adminconsent', + SERVICEACCOUNT = 'serviceaccount', + CONNECTOR = 'connector', +} + +/** + * Interface representing the query parameters for listing credentials. + */ +export interface ListCredentialsQueryParams { + /** + * Limit the number of results + */ + limit?: number; + /** + * Offset the results by this number + */ + offset?: number; + /** + * Sort the results by field name + */ + sortBy?: 'createdAt' | 'updatedAt'; + /** + * Order the results by ascending or descending + */ + orderBy?: 'desc' | 'asc'; +} diff --git a/src/nylas.ts b/src/nylas.ts index 983f45d5..7e88d752 100644 --- a/src/nylas.ts +++ b/src/nylas.ts @@ -8,6 +8,7 @@ import { Applications } from './resources/applications.js'; import { Messages } from './resources/messages.js'; import { Drafts } from './resources/drafts.js'; import { Threads } from './resources/threads.js'; +import { Connectors } from './resources/connectors.js'; /** * The entry point to the Node SDK @@ -28,6 +29,10 @@ export default class Nylas { * Access the Calendars API */ public calendars: Calendars; + /** + * Access the Connectors API + */ + public connectors: Connectors; /** * Access the Drafts API */ @@ -68,6 +73,7 @@ export default class Nylas { this.applications = new Applications(this.apiClient); this.auth = new Auth(this.apiClient); this.calendars = new Calendars(this.apiClient); + this.connectors = new Connectors(this.apiClient); this.drafts = new Drafts(this.apiClient); this.events = new Events(this.apiClient); this.messages = new Messages(this.apiClient); diff --git a/src/resources/connectors.ts b/src/resources/connectors.ts new file mode 100644 index 00000000..c4e679b7 --- /dev/null +++ b/src/resources/connectors.ts @@ -0,0 +1,149 @@ +import { AsyncListResponse, Resource } from './resource.js'; +import { + Connector, + CreateConnectorRequest, + ListConnectorsQueryParams, + UpdateConnectorRequest, +} from '../models/connectors.js'; +import { Overrides } from '../config.js'; +import { + NylasDeleteResponse, + NylasListResponse, + NylasResponse, +} from '../models/response.js'; +import { Provider } from '../models/auth.js'; +import { Credentials } from './credentials.js'; +import APIClient from '../apiClient.js'; + +/** + * The parameters for the {@link Connectors.find} method + * @property provider The provider associated to the connector to retrieve. + */ +interface FindConnectorParams { + provider: Provider; +} + +/** + * The parameters for the {@link Connectors.list} method + * @property queryParams The query parameters to include in the request + */ +interface ListConnectorsParams { + queryParams?: ListConnectorsQueryParams; +} + +/** + * The parameters for the {@link Connectors.create} method + * @property requestBody The request body to create a connector + */ +interface CreateConnectorParams { + requestBody: CreateConnectorRequest; +} + +/** + * The parameters for the {@link Connectors.update} method + * @property provider The provider associated to the connector to update. + * @property requestBody The request body to create a connector + */ +interface UpdateConnectorParams { + provider: Provider; + requestBody: UpdateConnectorRequest; +} + +/** + * The parameters for the {@link Connectors.destroy} method + * @property provider The provider associated to the connector to update. + */ +interface DestroyConnectorParams { + provider: string; +} + +export class Connectors extends Resource { + /** + * Access the Credentials API + */ + public credentials: Credentials; + + /** + * @param apiClient client The configured Nylas API client + */ + constructor(apiClient: APIClient) { + super(apiClient); + this.credentials = new Credentials(apiClient); + } + + /** + * Return all connectors + * @return A list of connectors + */ + public list({ + queryParams, + overrides, + }: ListConnectorsParams & + ListConnectorsQueryParams & + Overrides): AsyncListResponse> { + return super._list>({ + queryParams, + overrides, + path: `/v3/connectors`, + }); + } + + /** + * Return a connector + * @return The connector + */ + public find({ + provider, + overrides, + }: FindConnectorParams & Overrides): Promise> { + return super._find({ + path: `/v3/connectors/${provider}`, + overrides, + }); + } + + /** + * Create a connector + * @return The created connector + */ + public create({ + requestBody, + overrides, + }: CreateConnectorParams & Overrides): Promise> { + return super._create({ + path: `/v3/connectors`, + requestBody, + overrides, + }); + } + + /** + * Update a connector + * @return The updated connector + */ + public update({ + provider, + requestBody, + overrides, + }: UpdateConnectorParams & Overrides): Promise> { + return super._update({ + path: `/v3/connectors/${provider}`, + requestBody, + overrides, + }); + } + + /** + * Delete a connector + * @return The deleted connector + */ + public destroy({ + provider, + overrides, + }: DestroyConnectorParams & Overrides): Promise { + return super._destroy({ + path: `/v3/connectors/${provider}`, + overrides, + }); + } +} diff --git a/src/resources/credentials.ts b/src/resources/credentials.ts new file mode 100644 index 00000000..9debc7fb --- /dev/null +++ b/src/resources/credentials.ts @@ -0,0 +1,149 @@ +import { AsyncListResponse, Resource } from './resource.js'; +import { + Credential, + CreateCredentialRequest, + ListCredentialsQueryParams, + UpdateCredentialRequest, +} from '../models/credentials.js'; +import { Overrides } from '../config.js'; +import { + NylasDeleteResponse, + NylasListResponse, + NylasResponse, +} from '../models/response.js'; +import { Provider } from '../models/auth.js'; + +/** + * The parameters for the {@link Credentials.find} method + * @property provider The provider associated to the credential to retrieve. + * @property credentialsId The id of the credentials to retrieve. + */ +interface FindCredentialParams { + provider: Provider; + credentialsId: string; +} + +/** + * The parameters for the {@link Credentials.list} method + * @property provider The provider associated to the credential to list from. + * @property queryParams The query parameters to include in the request + */ +interface ListCredentialsParams { + provider: Provider; + queryParams?: ListCredentialsQueryParams; +} + +/** + * The parameters for the {@link Credentials.create} method + * @property provider The provider associated to the credential being created. + * @property requestBody The request body to create a credential + */ +interface CreateCredentialParams { + provider: Provider; + requestBody: CreateCredentialRequest; +} + +/** + * The parameters for the {@link Credentials.update} method + * @property provider The provider associated to the credential to update from. + * @property requestBody The request body to create a credential + * @property credentialsId The id of the credentials to update. + */ +interface UpdateCredentialParams { + provider: Provider; + credentialsId: string; + requestBody: UpdateCredentialRequest; +} + +/** + * The parameters for the {@link Credentials.destroy} method + * @property provider The provider associated to the credential to delete from. + * @property credentialsId The id of the credentials to delete. + */ +interface DestroyCredentialParams { + provider: string; + credentialsId: string; +} + +export class Credentials extends Resource { + /** + * Return all credentials + * @return A list of credentials + */ + public list({ + provider, + queryParams, + overrides, + }: ListCredentialsParams & + ListCredentialsQueryParams & + Overrides): AsyncListResponse> { + return super._list>({ + queryParams, + overrides, + path: `/v3/credentials/${provider}/creds`, + }); + } + + /** + * Return a credential + * @return The credential + */ + public find({ + provider, + credentialsId, + overrides, + }: FindCredentialParams & Overrides): Promise> { + return super._find({ + path: `/v3/credentials/${provider}/creds/${credentialsId}`, + overrides, + }); + } + + /** + * Create a credential + * @return The created credential + */ + public create({ + provider, + requestBody, + overrides, + }: CreateCredentialParams & Overrides): Promise> { + return super._create({ + path: `/v3/credentials/${provider}/creds`, + requestBody, + overrides, + }); + } + + /** + * Update a credential + * @return The updated credential + */ + public update({ + provider, + credentialsId, + requestBody, + overrides, + }: UpdateCredentialParams & Overrides): Promise> { + return super._update({ + path: `/v3/credentials/${provider}/creds/${credentialsId}}`, + requestBody, + overrides, + }); + } + + /** + * Delete a credential + * @return The deleted credential + */ + public destroy({ + provider, + credentialsId, + overrides, + }: DestroyCredentialParams & Overrides): Promise { + return super._destroy({ + path: `/v3/credentials/${provider}/creds/${credentialsId}}`, + overrides, + }); + } +} diff --git a/src/resources/grants.ts b/src/resources/grants.ts index 685b803a..40624354 100644 --- a/src/resources/grants.ts +++ b/src/resources/grants.ts @@ -78,7 +78,7 @@ export class Grants extends Resource { } /** - * Create a Grant + * Create a Grant via Custom Authentication * @return The created Grant */ public create({ @@ -86,7 +86,7 @@ export class Grants extends Resource { overrides, }: CreateGrantParams & Overrides): Promise> { return super._create({ - path: `/v3/grants`, + path: `/v3/connect/custom`, requestBody, overrides, }); diff --git a/tests/resources/grants.spec.ts b/tests/resources/grants.spec.ts index 4e0bfb81..7ec6d516 100644 --- a/tests/resources/grants.spec.ts +++ b/tests/resources/grants.spec.ts @@ -81,7 +81,7 @@ describe('Grants', () => { expect(apiClient.request).toHaveBeenCalledWith({ method: 'POST', - path: '/v3/grants', + path: '/v3/connect/custom', body: { provider: 'google', settings: {