From 2ea65dd8e4179725b86e9b1318354d7feb6c13a3 Mon Sep 17 00:00:00 2001 From: Mostafa Rashed <17770919+mrashed-dev@users.noreply.github.com> Date: Mon, 14 Aug 2023 14:06:43 -0400 Subject: [PATCH] Resource documentation for SDK reference (#476) This PR has documentation adds for all the resources. Also changes the following: - Refactor Auth to reflect the recent changes to the endpoints - Refactor Errors to support API + OAuth errors as well as timeout errors - Move availability into the calendar resource --- src/apiClient.ts | 21 ++-- src/config.ts | 4 + src/models/auth.ts | 41 +------ src/models/error.ts | 103 +++++++++++----- src/models/events.ts | 15 +-- src/models/providers.ts | 1 + src/models/response.ts | 12 -- src/nylas.ts | 9 +- src/resources/applications.ts | 15 +++ src/resources/auth.ts | 217 ++++++++++++---------------------- src/resources/availability.ts | 24 ---- src/resources/calendars.ts | 98 +++++++++++++-- src/resources/events.ts | 60 +++++++++- src/resources/grants.ts | 38 ++++++ src/resources/providers.ts | 58 --------- src/resources/redirectUris.ts | 93 +++++++++++++-- src/resources/resource.ts | 9 ++ src/resources/webhooks.ts | 22 ++-- 18 files changed, 472 insertions(+), 368 deletions(-) delete mode 100644 src/resources/availability.ts delete mode 100644 src/resources/providers.ts diff --git a/src/apiClient.ts b/src/apiClient.ts index e596925e..61a1af95 100644 --- a/src/apiClient.ts +++ b/src/apiClient.ts @@ -2,12 +2,12 @@ import fetch, { Request, Response } from 'node-fetch'; import { NylasConfig, OverridableNylasConfig } from './config'; import { NylasApiError, - NylasAuthError, - NylasTokenValidationError, + NylasOAuthError, + NylasSdkTimeoutError, } from './models/error'; import { objKeysToCamelCase, objKeysToSnakeCase } from './utils'; +import PACKAGE_JSON from '../package.json'; -const PACKAGE_JSON = require('../package.json'); const SDK_VERSION = PACKAGE_JSON.version; export interface RequestOptionsParams { @@ -128,7 +128,10 @@ export default class APIClient { async request(options: RequestOptionsParams): Promise { const req = this.newRequest(options); const controller: AbortController = new AbortController(); - const timeout = setTimeout(() => controller.abort(), this.timeout); + const timeout = setTimeout(() => { + controller.abort(); + throw new NylasSdkTimeoutError(req.url, this.timeout); + }, this.timeout); const response = await fetch(req, { signal: controller.signal }); clearTimeout(timeout); @@ -143,20 +146,16 @@ export default class APIClient { options.path.includes('connect/token') || options.path.includes('connect/revoke'); - const tokenErrorResponse = options.path.includes('connect/tokeninfo'); - const text = await response.text(); let error: Error; try { const parsedError = JSON.parse(text); const camelCaseError = objKeysToCamelCase(parsedError); - if (authErrorResponse && !tokenErrorResponse) { - error = new NylasAuthError(camelCaseError); - } else if (tokenErrorResponse) { - error = new NylasTokenValidationError(camelCaseError); + if (authErrorResponse) { + error = new NylasOAuthError(camelCaseError, response.status); } else { - error = new NylasApiError(camelCaseError); + error = new NylasApiError(camelCaseError, response.status); } } catch (e) { throw new Error( diff --git a/src/config.ts b/src/config.ts index da17c8ce..e2f5bba7 100644 --- a/src/config.ts +++ b/src/config.ts @@ -6,6 +6,10 @@ export type NylasConfig = { export type OverridableNylasConfig = Partial; +/** + * An object that can be used to override the default Nylas API client configuration on a per-request basis. + * @property overrides Overrides to the default Nylas API client configuration + */ export interface Overrides { overrides?: OverridableNylasConfig; } diff --git a/src/models/auth.ts b/src/models/auth.ts index 7bbb1825..91825d12 100644 --- a/src/models/auth.ts +++ b/src/models/auth.ts @@ -2,6 +2,7 @@ type AccessType = 'online' | 'offline'; type Provider = 'google' | 'imap' | 'microsoft' | 'yahoo'; export type URLForAuthenticationConfig = { + clientId: string; redirectUri: string; provider?: Provider; accessType?: AccessType; @@ -17,25 +18,6 @@ export type URLForAdminConsentConfig = URLForAuthenticationConfig & { credentialId: string; }; -export interface OpenID { - iss: string; // Issuer - aud: string; // Application Slug - sub?: string; // ID - email?: string; - emailVerified?: boolean; - atHash?: string; - iat: number; // Issued At - exp: number; // Expites At - // Profile - name?: string; - givenName?: string; - familyName?: string; - nickName?: string; - pictureUrl?: string; - gender?: string; - locale?: string; -} - export interface CodeExchangeRequest { redirectUri: string; code: string; @@ -45,25 +27,8 @@ export interface CodeExchangeRequest { export interface TokenExchangeRequest { redirectUri: string; refreshToken: string; -} - -export type ServerSideHostedAuthRequest = { - redirectUri: string; - provider?: Provider; - state?: string; - loginHint?: string; - cookieNonce?: string; - grantId?: string; - scope?: string[]; - expiresIn?: number; - settings?: Record; -}; - -export interface ServerSideHostedAuthResponse { - url: string; - id: string; - expiresAt: number; - request: ServerSideHostedAuthRequest; + clientId: string; + clientSecret: string; } export interface PKCEAuthURL { diff --git a/src/models/error.ts b/src/models/error.ts index eb84c778..7dc8a78d 100644 --- a/src/models/error.ts +++ b/src/models/error.ts @@ -1,50 +1,93 @@ -import { - NylasApiErrorResponse, - AuthErrorResponse, - TokenValidationErrorResponse, -} from './response'; +import { NylasApiErrorResponse, AuthErrorResponse } from './response'; /** - * Extended Error class for errors returned from the Nylas API - * - * Properties: + * Base class for all Nylas API errors. */ -export class NylasApiError extends Error { +export abstract class AbstractNylasApiError extends Error { + /** + * The unique identifier of the request. + */ + requestId?: string; + /** + * The HTTP status code of the error response. + */ + statusCode?: number; +} + +/** + * Base class for all Nylas SDK errors. + */ +export abstract class AbstractNylasSdkError extends Error {} + +/** + * Class representation of a general Nylas API error. + */ +export class NylasApiError extends AbstractNylasApiError { + /** + * Error type. + */ type: string; - requestId: string; + /** + * Provider Error. + */ providerError: any; - constructor(apiError: NylasApiErrorResponse) { + constructor(apiError: NylasApiErrorResponse, statusCode?: number) { super(apiError.error.message); this.type = apiError.error.type; this.requestId = apiError.requestId; this.providerError = apiError.error.providerError; + this.statusCode = statusCode; } } -export class NylasAuthError extends Error { - type: string; - requestId: string; - providerError: any; +/** + * Class representing an OAuth error returned by the Nylas API. + */ +export class NylasOAuthError extends AbstractNylasApiError { + /** + * Error type. + */ + error: string; + /** + * Error code used for referencing the docs, logs, and data stream. + */ + errorCode: number; + /** + * Human readable error description. + */ + errorDescription: string; + /** + * URL to the related documentation and troubleshooting regarding this error. + */ + errorUri: string; - constructor(apiError: AuthErrorResponse) { + constructor(apiError: AuthErrorResponse, statusCode?: number) { super(apiError.errorDescription); - this.type = apiError.error; - this.requestId = apiError.requestId; - this.providerError = apiError.errorDescription; + this.error = apiError.error; + this.errorCode = apiError.errorCode; + this.errorDescription = apiError.errorDescription; + this.errorUri = apiError.errorUri; + this.statusCode = statusCode; } } -export class NylasTokenValidationError extends Error { - type: string; - requestId: string; - providerError: any; - constructor(apiError: TokenValidationErrorResponse) { - super(apiError.error.message); - this.type = apiError.error.type; - this.requestId = apiError.error.requestId; - this.providerError = apiError.error.message; +/** + * Error thrown when the Nylas SDK times out before receiving a response from the server + */ +export class NylasSdkTimeoutError extends AbstractNylasSdkError { + /** + * The URL that timed out + */ + url: string; + /** + * The timeout value set in the Nylas SDK, in seconds + */ + timeout: number; + + constructor(url: string, timeout: number) { + super('Nylas SDK timed out before receiving a response from the server.'); + this.url = url; + this.timeout = timeout; } } - -// TODO: sdk error models? diff --git a/src/models/events.ts b/src/models/events.ts index 40a11172..704a961f 100644 --- a/src/models/events.ts +++ b/src/models/events.ts @@ -15,8 +15,6 @@ export interface Event { conferencing: Conferencing; description?: string; location?: string; - messageId?: string; - owner?: string; icalUid?: string; title?: string; htmlLink?: string; @@ -24,7 +22,7 @@ export interface Event { metadata?: Record; creator?: EmailName; organizer: EmailName; - recurrence?: Recurrence; + recurrence?: string[]; reminders?: Reminder[]; status?: Status; visibility?: Visibility; @@ -41,7 +39,7 @@ export interface CreateEventRequest { reminderMethod?: string; metadata?: Record; participants?: Participant[]; - recurrence?: Recurrence; + recurrence?: string[]; calendarId?: string; readOnly?: boolean; roundRobinOrder?: string[]; @@ -118,8 +116,8 @@ export interface Time { export interface Timespan { startTime: number; endTime: number; - startTimezone: string; - endTimezone: string; + startTimezone?: string; + endTimezone?: string; } export interface Date { @@ -139,11 +137,6 @@ export interface Participant { phoneNumber?: string; } -export interface Recurrence { - rrule: string[]; - timezone: string; -} - export interface Reminder { reminderMinutes: string; reminderMethod: ReminderMethod; diff --git a/src/models/providers.ts b/src/models/providers.ts index 01fbf702..1fceb480 100644 --- a/src/models/providers.ts +++ b/src/models/providers.ts @@ -5,6 +5,7 @@ export interface ProviderDetectParams { export interface ProviderDetectResponse { emailAddress: string; + detected: boolean; provider?: string; type?: string; } diff --git a/src/models/response.ts b/src/models/response.ts index 481bdef0..4c3af79d 100644 --- a/src/models/response.ts +++ b/src/models/response.ts @@ -25,24 +25,12 @@ export interface NylasDeleteResponse { } export interface AuthErrorResponse { - requestId: string; error: string; errorCode: number; errorDescription: string; errorUri: string; } -export interface TokenValidationErrorResponse { - success: boolean; - error: { - httpCode: number; - eventCode: number; - type: string; - message: string; - requestId: string; - }; -} - export type ListResponseInnerType = T extends NylasListResponse ? R : never; diff --git a/src/nylas.ts b/src/nylas.ts index f350d5e1..db8858ae 100644 --- a/src/nylas.ts +++ b/src/nylas.ts @@ -4,12 +4,11 @@ import { Calendars } from './resources/calendars'; import { Events } from './resources/events'; import { Auth } from './resources/auth'; import { Webhooks } from './resources/webhooks'; -import { Availability } from './resources/availability'; import { Applications } from './resources/applications'; class Nylas { public applications: Applications; - public availability: Availability; + public auth: Auth; public calendars: Calendars; public events: Events; public webhooks: Webhooks; @@ -24,17 +23,13 @@ class Nylas { }); this.applications = new Applications(this.apiClient); - this.availability = new Availability(this.apiClient); + this.auth = new Auth(this.apiClient); this.calendars = new Calendars(this.apiClient); this.events = new Events(this.apiClient); this.webhooks = new Webhooks(this.apiClient); return this; } - - public auth(clientId: string, clientSecret: string): Auth { - return new Auth(this.apiClient, clientId, clientSecret); - } } export = Nylas; diff --git a/src/resources/applications.ts b/src/resources/applications.ts index da617702..713b0b85 100644 --- a/src/resources/applications.ts +++ b/src/resources/applications.ts @@ -5,14 +5,29 @@ import { ApplicationDetails } from '../models/applicationDetails'; import { NylasResponse } from '../models/response'; import { Overrides } from '../config'; +/** + * Nylas Applications API + * + * This endpoint allows for getting application details as well as redirect URI operations. + */ export class Applications extends Resource { + /** + * Access the collection of redirect URI related API endpoints. + */ public redirectUris: RedirectUris; + /** + * @param apiClient client The configured Nylas API client + */ constructor(apiClient: APIClient) { super(apiClient); this.redirectUris = new RedirectUris(apiClient); } + /** + * Get application details + * @returns The application details + */ public getDetails({ overrides }: Overrides = {}): Promise< NylasResponse > { diff --git a/src/resources/auth.ts b/src/resources/auth.ts index 207732b5..0e5a2546 100644 --- a/src/resources/auth.ts +++ b/src/resources/auth.ts @@ -3,58 +3,63 @@ import sha256 from 'sha256'; import APIClient from '../apiClient'; import { Resource } from './resource'; import { Grants } from './grants'; -import { Providers } from './providers'; import { URLForAdminConsentConfig, URLForAuthenticationConfig, CodeExchangeRequest, - ServerSideHostedAuthResponse, - ServerSideHostedAuthRequest, - OpenID, PKCEAuthURL, TokenExchangeRequest, CodeExchangeResponse, } from '../models/auth'; -import { NylasResponse } from '../models/response'; +/** + * A collection of authentication related API endpoints + * + * These endpoints allow for various functionality related to authentication. + * Also contains the Grants API and collection of provider API endpoints. + */ export class Auth extends Resource { + /** + * Access the Grants API + */ public grants: Grants; - public providers: Providers; apiClient: APIClient; - clientId: string; - clientSecret: string; - constructor(apiClient: APIClient, clientId: string, clientSecret: string) { + /** + * @param apiClient The configured Nylas API client + */ + constructor(apiClient: APIClient) { super(apiClient); this.apiClient = apiClient; - this.clientId = clientId; - this.clientSecret = clientSecret; - this.grants = new Grants(apiClient); - this.providers = new Providers(apiClient, clientId, clientSecret); + } + + /** + * Build the URL for authenticating users to your application with OAuth 2.0 + * @param config The configuration for building the URL + * @return The URL for hosted authentication + */ + public urlForOAuth2(config: URLForAuthenticationConfig): string { + return this.urlAuthBuilder(config).toString(); } /** * Exchange an authorization code for an access token - * @param payload The request parameters for the code exchange + * @param request The request parameters for the code exchange * @return Information about the Nylas application */ public exchangeCodeForToken( - payload: CodeExchangeRequest - ): Promise> { - this.checkAuthCredentials(); + request: CodeExchangeRequest + ): Promise { const body: Record = { - code: payload.code, - redirectUri: payload.redirectUri, - clientId: this.clientId, - clientSecret: this.clientSecret, + ...request, grantType: 'authorization_code', }; - if (payload.codeVerifier) { - body.codeVerifier = payload.codeVerifier; + if (request.codeVerifier) { + body.codeVerifier = request.codeVerifier; } - return this.apiClient.request>({ + return this.apiClient.request({ method: 'POST', path: `/v3/connect/token`, body, @@ -62,78 +67,78 @@ export class Auth extends Resource { } /** - * Exchange a refresh token for an access token (and if rotation enabled refresh token as well) - * @param payload The request parameters for the token exchange - * @return Information about the Nylas application + * Refresh an access token + * @param request The refresh token request + * @return The response containing the new access token */ public refreshAccessToken( - payload: TokenExchangeRequest - ): Promise> { - this.checkAuthCredentials(); - - return this.apiClient.request>({ + request: TokenExchangeRequest + ): Promise { + return this.apiClient.request({ method: 'POST', path: `/v3/connect/token`, body: { - refreshToken: payload.refreshToken, - redirectUri: payload.redirectUri, - clientId: this.clientId, - clientSecret: this.clientSecret, + ...request, grantType: 'refresh_token', }, }); } /** - * Validate and retrieve information about an ID token - * @param token The ID token - * @return Information about the ID token + * Build the URL for authenticating users to your application with OAuth 2.0 and PKCE + * IMPORTANT: YOU WILL NEED TO STORE THE 'secret' returned to use it inside the CodeExchange flow + * @param config The configuration for building the URL + * @return The URL for hosted authentication */ - public validateIDToken(token: string): Promise> { - return this.validateToken({ idToken: token }); + public urlForOAuth2PKCE(config: URLForAuthenticationConfig): PKCEAuthURL { + const url = this.urlAuthBuilder(config); + + // Add code challenge to URL generation + url.searchParams.set('code_challenge_method', 's256'); + const secret = uuid(); + const secretHash = this.hashPKCESecret(secret); + url.searchParams.set('code_challenge', secret); + // Return the url with secret & hashed secret + return { secret, secretHash, url: url.toString() }; } /** - * Validate and retrieve information about an access token - * @param token The access token - * @return Information about the access token + * Build the URL for admin consent authentication for Microsoft + * @param config The configuration for building the URL + * @return The URL for admin consent authentication */ - public validateAccessToken(token: string): Promise> { - return this.validateToken({ - accessToken: token, - }); - } - - private validateToken( - queryParams: Record - ): Promise> { - this.checkAuthCredentials(); - - return this.apiClient.request>({ - method: 'GET', - path: `/v3/connect/tokeninfo`, - queryParams, - }); + public urlForAdminConsent(config: URLForAdminConsentConfig): string { + const configWithProvider = { ...config, provider: 'microsoft' }; + const url = this.urlAuthBuilder(configWithProvider); + url.searchParams.set('response_type', 'adminconsent'); + url.searchParams.set('credential_id', config.credentialId); + return url.toString(); } /** - * Build the URL for authenticating users to your application via Hosted Authentication - * @param config Configuration for the authentication process - * @return The URL for hosted authentication + * Revoke a token (and the grant attached to the token) + * @param token The token to revoke + * @return True if the token was revoked successfully */ - public urlForAuthentication(config: URLForAuthenticationConfig): string { - return this.urlAuthBuilder(config).toString(); + public async revoke(token: string): Promise { + await this.apiClient.request({ + method: 'POST', + path: `/v3/connect/revoke`, + queryParams: { + token, + }, + }); + + return true; } private urlAuthBuilder(config: Record): URL { - this.checkAuthCredentials(); - const url = new URL(`${this.apiClient.serverUrl}/v3/connect/auth`); - url.searchParams.set('client_id', this.clientId as string); + url.searchParams.set('client_id', config.clientId); url.searchParams.set('redirect_uri', config.redirectUri); url.searchParams.set( 'access_type', - config.accessType ? config.accessType : 'online' //TODO::More secure + config.accessType ? config.accessType : 'online' ); url.searchParams.set('response_type', 'code'); if (config.provider) { @@ -164,81 +169,7 @@ export class Auth extends Resource { return url; } - /** - * Build the URL for authenticating users to your application via Hosted Authentication with PKCE - * IMPORTANT: YOU WILL NEED TO STORE THE 'secret' returned to use it inside the CodeExchange flow - * @param config Configuration for the authentication process - * @return The URL for hosted authentication - */ - public urlForAuthenticationPKCE( - config: URLForAuthenticationConfig - ): PKCEAuthURL { - const url = this.urlAuthBuilder(config); - - // Add code challenge to URL generation - url.searchParams.set('code_challenge_method', 's256'); - const secret = uuid(); - const secretHash = this.hashPKCESecret(secret); - url.searchParams.set('code_challenge', secret); - // Return the url with secret & hashed secret - return { secret, secretHash, url: url.toString() }; - } - private hashPKCESecret(secret: string): string { return Buffer.from(sha256(secret)).toString('base64'); } - - /** - * Build the URL for admin consent authentication for Microsoft - * @param config Configuration for the authentication process - * @return The URL for hosted authentication - */ - public urlForAdminConsent(config: URLForAdminConsentConfig): string { - const configWithProvider = { ...config, provider: 'microsoft' }; - const url = this.urlAuthBuilder(configWithProvider); - url.searchParams.set('response_type', 'adminconsent'); - url.searchParams.set('credential_id', config.credentialId); - return url.toString(); - } - - private checkAuthCredentials(): void { - if (!this.clientId || !this.clientSecret) { - throw new Error('ClientID & ClientSecret are required for using auth'); - } - } - - /** - * Create a new authorization request and get a new unique login url. - * Used only for hosted authentication. - * This is the initial step requested from the server side to issue a new login url. - * @param payload params to initiate hosted auth request - * @return True if the request was successful - */ - public async serverSideHostedAuth( - payload: ServerSideHostedAuthRequest - ): Promise> { - return await this.apiClient.request< - NylasResponse - >({ - method: 'POST', - path: `/v3/connect/auth`, - body: payload, - }); - } - - /** - * Revoke a single access token - * @param accessToken The access token to revoke - * @return True if the access token was revoked - */ - public async revoke(accessToken: string): Promise { - await this.apiClient.request({ - method: 'POST', - path: `/v3/connect/revoke`, - queryParams: { - token: accessToken, - }, - }); - return true; - } } diff --git a/src/resources/availability.ts b/src/resources/availability.ts deleted file mode 100644 index a41ab6ff..00000000 --- a/src/resources/availability.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Overrides } from '../config'; -import { Resource } from './resource'; -import { - GetAvailabilityRequest, - GetAvailabilityResponse, -} from '../models/availability'; - -interface GetAvailabilityParams { - requestBody: GetAvailabilityRequest; -} - -export class Availability extends Resource { - public getAvailability({ - requestBody, - overrides, - }: GetAvailabilityParams & Overrides): Promise { - return this.apiClient.request({ - method: 'POST', - path: `/v3/calendars/availability`, - body: requestBody, - overrides, - }); - } -} diff --git a/src/resources/calendars.ts b/src/resources/calendars.ts index 9d293f69..81e51a7a 100644 --- a/src/resources/calendars.ts +++ b/src/resources/calendars.ts @@ -11,38 +11,88 @@ import { NylasListResponse, } from '../models/response'; import { Resource, AsyncListResponse } from './resource'; +import { + GetAvailabilityRequest, + GetAvailabilityResponse, +} from '../models/availability'; +/** + * The parameters for the {@link Calendars.find} method + * @property calendarId The id of the Calendar to retrieve. Use "primary" to refer to the primary calendar associated with grant. + * @property identifier The identifier of the grant to act upon + */ interface FindCalendarParams { - calendarId: string; identifier: string; + calendarId: string; } + +/** + * The parameters for the {@link Calendars.list} method + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ interface ListCalendersParams { identifier: string; + queryParams?: ListCalendersQueryParams; } +/** + * The parameters for the {@link Calendars.create} method + * @property identifier The identifier of the grant to act upon + * @property requestBody The request body to create a calendar + */ interface CreateCalendarParams { identifier: string; requestBody: CreateCalenderRequestBody; } +/** + * The parameters for the {@link Calendars.update} method + * @property identifier The identifier of the grant to act upon + * @property calendarId The id of the Calendar to retrieve. Use "primary" to refer to the primary calendar associated with grant. + */ interface UpdateCalendarParams { - calendarId: string; identifier: string; + calendarId: string; requestBody: UpdateCalenderRequestBody; } +/** + * The parameters for the {@link Calendars.destroy} method + * @property identifier The identifier of the grant to act upon + * @property calendarId The id of the Calendar to retrieve. Use "primary" to refer to the primary calendar associated with grant. + */ interface DestroyCalendarParams { identifier: string; calendarId: string; } -type CalendarListParams = ListCalendersParams & Overrides; +/** + * The parameters for the {@link Calendars.getAvailability} method + * @property requestBody The availability request + */ +interface GetAvailabilityParams { + requestBody: GetAvailabilityRequest; +} +/** + * Nylas Calendar API + * + * The Nylas calendar API allows you to create new calendars or manage existing ones. + * A calendar can be accessed by one, or several people, and can contain events. + */ export class Calendars extends Resource { - public list( - { overrides, identifier }: CalendarListParams, - queryParams?: ListCalendersQueryParams - ): AsyncListResponse> { + /** + * Return all Calendars + * @return A list of calendars + */ + public list({ + identifier, + queryParams, + overrides, + }: ListCalendersParams & + ListCalendersQueryParams & + Overrides): AsyncListResponse> { return super._list>({ queryParams, overrides, @@ -50,9 +100,13 @@ export class Calendars extends Resource { }); } + /** + * Return a Calendar + * @return The calendar + */ public find({ - calendarId, identifier, + calendarId, overrides, }: FindCalendarParams & Overrides): Promise> { return super._find({ @@ -61,6 +115,10 @@ export class Calendars extends Resource { }); } + /** + * Create a Calendar + * @return The created calendar + */ public create({ identifier, requestBody, @@ -73,6 +131,10 @@ export class Calendars extends Resource { }); } + /** + * Update a Calendar + * @return The updated Calendar + */ public update({ calendarId, identifier, @@ -86,6 +148,10 @@ export class Calendars extends Resource { }); } + /** + * Delete a Calendar + * @return The deleted Calendar + */ public destroy({ identifier, calendarId, @@ -96,4 +162,20 @@ export class Calendars extends Resource { overrides, }); } + + /** + * Get Availability for a given account / accounts + * @return The availability response + */ + public getAvailability({ + requestBody, + overrides, + }: GetAvailabilityParams & Overrides): Promise { + return this.apiClient.request({ + method: 'POST', + path: `/v3/calendars/availability`, + body: requestBody, + overrides, + }); + } } diff --git a/src/resources/events.ts b/src/resources/events.ts index 2c574d55..6ff076a4 100644 --- a/src/resources/events.ts +++ b/src/resources/events.ts @@ -16,35 +16,71 @@ import { } from '../models/response'; import { AsyncListResponse, Resource } from './resource'; +/** + * @property eventId The id of the Event to retrieve. + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ interface FindEventParams { + identifier: string; eventId: string; queryParams: FindEventQueryParams; - identifier: string; } + +/** + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ interface ListEventParams { identifier: string; queryParams: ListEventQueryParams; } +/** + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + * @property requestBody The values to create the Event with + */ interface CreateEventParams { identifier: string; - queryParams: CreateEventQueryParams; requestBody: CreateEventRequest; + queryParams: CreateEventQueryParams; } +/** + * @property identifier The identifier of the grant to act upon + * @property eventId The id of the Event to retrieve. + * @property requestBody The values to update the Event with + * @property queryParams The query parameters to include in the request + */ interface UpdateEventParams { - eventId: string; identifier: string; - queryParams: UpdateEventQueryParams; + eventId: string; requestBody: UpdateEventRequest; + queryParams: UpdateEventQueryParams; } +/** + * @property identifier The identifier of the grant to act upon + * @property eventId The id of the Event to retrieve. + * @property queryParams The query parameters to include in the request + */ interface DestroyEventParams { identifier: string; eventId: string; queryParams: DestroyEventQueryParams; } + +/** + * Nylas Events API + * + * The Nylas Events API allows you to create, update, and delete events on user calendars. + */ export class Events extends Resource { + /** + * Return all Events + * @return The list of Events + */ public list({ identifier, queryParams, @@ -57,6 +93,10 @@ export class Events extends Resource { }); } + /** + * Return an Event + * @return The Event + */ public find({ identifier, eventId, @@ -70,6 +110,10 @@ export class Events extends Resource { }); } + /** + * Create an Event + * @return The created Event + */ public create({ identifier, requestBody, @@ -84,6 +128,10 @@ export class Events extends Resource { }); } + /** + * Update an Event + * @return The updated Event + */ public update({ identifier, eventId, @@ -99,6 +147,10 @@ export class Events extends Resource { }); } + /** + * Delete an Event + * @return The deletion response + */ public destroy({ identifier, eventId, diff --git a/src/resources/grants.ts b/src/resources/grants.ts index a887f83a..e5f026e1 100644 --- a/src/resources/grants.ts +++ b/src/resources/grants.ts @@ -12,24 +12,46 @@ import { UpdateGrantRequest, } from '../models/grants'; +/** + * @property grantId The id of the Grant to retrieve. + */ interface FindGrantParams { grantId: string; } +/** + * @property requestBody The values to create the Grant with. + */ interface CreateGrantParams { requestBody: CreateGrantRequest; } +/** + * @property grantId The id of the Grant to update. + * @property requestBody The values to update the Grant with. + */ interface UpdateGrantParams { grantId: string; requestBody: UpdateGrantRequest; } +/** + * @property grantId The id of the Grant to delete. + */ interface DestroyGrantParams { grantId: string; } +/** + * Nylas Grants API + * + * The Nylas Grants API allows for the management of grants. + */ export class Grants extends Resource { + /** + * Return all Grants + * @return The list of Grants + */ public async list( { overrides }: Overrides = {}, queryParams?: ListGrantsQueryParams @@ -41,6 +63,10 @@ export class Grants extends Resource { }); } + /** + * Return a Grant + * @return The Grant + */ public find({ grantId, overrides, @@ -51,6 +77,10 @@ export class Grants extends Resource { }); } + /** + * Create a Grant + * @return The created Grant + */ public create({ requestBody, overrides, @@ -62,6 +92,10 @@ export class Grants extends Resource { }); } + /** + * Update a Grant + * @return The updated Grant + */ public update({ grantId, requestBody, @@ -74,6 +108,10 @@ export class Grants extends Resource { }); } + /** + * Delete a Grant + * @return The deletion response + */ public destroy({ grantId, overrides, diff --git a/src/resources/providers.ts b/src/resources/providers.ts deleted file mode 100644 index a79c52ae..00000000 --- a/src/resources/providers.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Resource } from './resource'; -import { NylasListResponse, NylasResponse } from '../models/response'; -import { - Provider, - ProviderDetectParams, - ProviderDetectResponse, -} from '../models/providers'; -import APIClient from '../apiClient'; - -export class Providers extends Resource { - clientId: string; - clientSecret: string; - - constructor(apiClient: APIClient, clientId: string, clientSecret: string) { - super(apiClient); - this.clientId = clientId; - this.clientSecret = clientSecret; - } - - private checkAuthCredentials(): void { - if (!this.clientId) { - throw new Error('ClientID is required for using providers'); - } - } - - /** - * Lists created providers(integrations) - * @return List of created providers with type & settings if supported - */ - public async list(): Promise> { - this.checkAuthCredentials(); - return await this.apiClient.request>({ - method: 'GET', - path: `/v3/connect/providers/find`, - queryParams: { - clientId: this.clientId, - }, - }); - } - - /** - * Detects provider for passed email (if allProviderTypes set to true tries to detect provider based on all supported providers) - * @return Information about the passed provider email - */ - public async detect( - params: ProviderDetectParams - ): Promise> { - this.checkAuthCredentials(); - return await this.apiClient.request>({ - method: 'POST', - path: `/v3/providers/detect`, - queryParams: { - clientId: this.clientId, - ...params, - }, - }); - } -} diff --git a/src/resources/redirectUris.ts b/src/resources/redirectUris.ts index 143148fa..8d3c982f 100644 --- a/src/resources/redirectUris.ts +++ b/src/resources/redirectUris.ts @@ -11,7 +11,46 @@ import { } from '../models/redirectUri'; import { Overrides } from '../config'; +/** + * @property redirectUriId The id of the Redirect URI to retrieve. + */ +interface FindRedirectUrisParams { + redirectUriId: string; +} + +/** + * @property requestBody The values to create the Redirect URI with. + */ +interface CreateRedirectUrisParams { + requestBody: CreateRedirectUriRequest; +} + +/** + * @property redirectUriId The id of the Redirect URI to update. + * @property requestBody The values to update the Redirect URI with. + */ +interface UpdateRedirectUrisParams { + redirectUriId: string; + requestBody: UpdateRedirectUriRequest; +} + +/** + * @property redirectUriId The id of the Redirect URI to delete. + */ +interface DestroyRedirectUrisParams { + redirectUriId: string; +} + +/** + * A collection of redirect URI related API endpoints. + * + * These endpoints allows for the management of redirect URIs. + */ export class RedirectUris extends Resource { + /** + * Return all Redirect URIs + * @return The list of Redirect URIs + */ public list({ overrides }: Overrides = {}): AsyncListResponse< NylasListResponse > { @@ -21,35 +60,67 @@ export class RedirectUris extends Resource { }); } - public find(redirectUriId: string): Promise> { + /** + * Return a Redirect URI + * @return The Redirect URI + */ + public find({ + redirectUriId, + overrides, + }: FindRedirectUrisParams & Overrides): Promise> { return super._find({ + overrides, path: `/v3/applications/redirect-uris/${redirectUriId}`, }); } - public create( - requestBody: CreateRedirectUriRequest - ): Promise> { + /** + * Create a Redirect URI + * @return The created Redirect URI + */ + public create({ + requestBody, + overrides, + }: CreateRedirectUrisParams & Overrides): Promise< + NylasResponse + > { return super._create({ + overrides, path: '/v3/applications/redirect-uris', requestBody, }); } - public update( - redirectUriId: string, - requestBody: UpdateRedirectUriRequest - ): Promise> { + /** + * Update a Redirect URI + * @return The updated Redirect URI + */ + public update({ + redirectUriId, + requestBody, + overrides, + }: UpdateRedirectUrisParams & Overrides): Promise< + NylasResponse + > { return super._update({ + overrides, path: `/v3/applications/redirect-uris/${redirectUriId}`, requestBody, }); } - public destroy( - redirectUriId: string - ): Promise> { + /** + * Delete a Redirect URI + * @return The deleted Redirect URI + */ + public destroy({ + redirectUriId, + overrides, + }: DestroyRedirectUrisParams & Overrides): Promise< + NylasResponse + > { return super._destroy({ + overrides, path: `/v1/redirect_uris/${redirectUriId}`, }); } diff --git a/src/resources/resource.ts b/src/resources/resource.ts index cabed285..19516add 100644 --- a/src/resources/resource.ts +++ b/src/resources/resource.ts @@ -34,9 +34,18 @@ interface DestroyParams { } type List = NylasListResponse>; + +/** + * Base class for Nylas API resources + * + * @ignore No public constructor or functions + */ export class Resource { protected apiClient: APIClient; + /** + * @param apiClient client The configured Nylas API client + */ constructor(apiClient: APIClient) { this.apiClient = apiClient; } diff --git a/src/resources/webhooks.ts b/src/resources/webhooks.ts index 6cc48eef..e4ffcb0d 100644 --- a/src/resources/webhooks.ts +++ b/src/resources/webhooks.ts @@ -10,15 +10,25 @@ import { WebhookWithSecret, } from '../models/webhooks'; +/** + * @property requestBody The webhook destination details + */ interface CreateWebhookParams { requestBody: CreateWebhookRequest; } +/** + * @property webhookId The ID of the webhook destination to update + * @property requestBody The updated webview destination details + */ interface UpdateWebhookParams { webhookId: string; requestBody: UpdateWebhookRequestBody; } +/** + * @property webhookId The ID of the webhook destination to delete + */ interface DestroyWebhookParams { webhookId: string; } @@ -26,7 +36,6 @@ interface DestroyWebhookParams { export class Webhooks extends Resource { /** * List all webhook destinations for the application - * @param overrides Overrides for the request * @returns The list of webhook destinations */ public list({ overrides }: Overrides = {}): AsyncListResponse< @@ -40,8 +49,6 @@ export class Webhooks extends Resource { /** * Create a webhook destination - * @param requestBody The webhook destination details - * @param overrides Overrides for the request * @returns The created webhook destination */ public create({ @@ -59,9 +66,6 @@ export class Webhooks extends Resource { /** * Update a webhook destination - * @param webhookId The ID of the webhook destination to update - * @param requestBody The updated webview destination details - * @param overrides Overrides for the request * @returns The updated webhook destination */ public update({ @@ -78,8 +82,7 @@ export class Webhooks extends Resource { /** * Delete a webhook destination - * @param webhookId The ID of the webhook destination to delete - * @param overrides Overrides for the request + * @returns The deletion response */ public destroy({ webhookId, @@ -93,8 +96,6 @@ export class Webhooks extends Resource { /** * Update the webhook secret value for a destination - * @param webhookId The ID of the webhook destination to update - * @param overrides Overrides for the request * @returns The updated webhook destination */ public rotateSecret({ @@ -110,7 +111,6 @@ export class Webhooks extends Resource { /** * Get the current list of IP addresses that Nylas sends webhooks from - * @param overrides Overrides for the request * @returns The list of IP addresses that Nylas sends webhooks from */ public ipAddresses({ overrides }: Overrides = {}): Promise<