diff --git a/.eslintignore b/.eslintignore index e6c30dce..142200e3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,4 @@ node_modules lib -example \ No newline at end of file +example +docs diff --git a/.prettierignore b/.prettierignore index e6c30dce..2ddf2e1e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,4 @@ node_modules lib -example \ No newline at end of file +example +docs \ No newline at end of file diff --git a/README.md b/README.md index a96e29d7..9ece13b5 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ # Nylas Node.js SDK -[![Travis build status](https://travis-ci.org/nylas/nylas-nodejs.svg?branch=master)](https://travis-ci.org/nylas/nylas-nodejs) [![codecov](https://codecov.io/gh/nylas/nylas-nodejs/branch/main/graph/badge.svg?token=94IMGU4F09)](https://codecov.io/gh/nylas/nylas-nodejs) This is the GitHub repository for the Nylas Node SDK and this repo is primarily for anyone who wants to make contributions to the SDK or install it from source. If you are looking to use Node to access the Nylas Email, Calendar, or Contacts API you should refer to our official [Node SDK Quickstart Guide](https://developer.nylas.com/docs/developer-tools/sdk/node-sdk/). @@ -20,6 +19,10 @@ Here are some resources to help you get started: ## ⚙️ Install +**Note:** The Nylas Node SDK requires Node.js v16 or later. + +### Set up using npm + To run the Nylas Node SDK, you will first need to have [Node](https://nodejs.org/en/download/) and [npm](https://www.npmjs.com/get-npm) installed on your machine. Then, head to the nearest command line and run the following: @@ -27,6 +30,8 @@ Then, head to the nearest command line and run the following: Alternatively, if you prefer to use [Yarn](https://yarnpkg.com/en/), you can install the Nylas Node SDK with `yarn add nylas` +### Build from source + To install this package from source, clone this repo and run `npm install` from inside the project directory. ```bash @@ -37,27 +42,34 @@ npm install ## ⚡️ Usage +To use this SDK, you must first [get a free Nylas account](https://dashboard.nylas.com/register). + +Then, follow the Quickstart guide to [set up your first app and get your API keys](https://developer.nylas.com/docs/v3-beta/v3-quickstart/). + +For code examples that demonstrate how to use this SDK, take a look at our [Node repos in the Nylas Samples collection](https://github.com/orgs/nylas-samples/repositories?q=&type=all&language=javascript&sort=). + +### 🚀 Making Your First Request + Every resource (i.e., messages, events, contacts) is accessed via an instance of `Nylas`. Before making any requests, be sure to call `config` and initialize the `Nylas` instance with your `clientId` and `clientSecret`. Then, call `with` and pass it your `accessToken`. The `accessToken` allows `Nylas` to make requests for a given account's resources. -```javascript -const Nylas = require('nylas'); +```typescript +import Nylas from "nylas"; -Nylas.config({ - clientId: CLIENT_ID, - clientSecret: CLIENT_SECRET, +const nylas = new Nylas({ + apiKey: "NYLAS_API_KEY", }); - -const nylas = Nylas.with(ACCESS_TOKEN); ``` Then, you can use Nylas to access information about a user's account: -```javascript -nylas.threads.list({}).then(threads => { - console.log(threads.length); +```typescript +nylas.calendars.list({ identifier: "GRANT_ID" }).then(calendars => { + console.log(calendars); }); ``` -For more information about how to use the Nylas Node SDK, [take a look at our quickstart guide](https://developer.nylas.com/docs/developer-tools/sdk/node-sdk/). +## 📚 Documentation + +Nylas maintains a [reference guide for the Node SDK](https://nylas-nodejs-sdk-reference.pages.dev/) to help you get familiar with the available methods and classes. ## 💙 Contributing diff --git a/package-lock.json b/package-lock.json index e034e5c8..f321af39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "prettier": "^1.19.1", "ts-jest": "^29.1.1", "typedoc": "^0.24.8", - "typedoc-plugin-missing-exports": "^2.0.1", + "typedoc-plugin-rename-defaults": "^0.6.5", "typescript": "^4.9.5" }, "engines": { @@ -6541,13 +6541,13 @@ "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x" } }, - "node_modules/typedoc-plugin-missing-exports": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/typedoc-plugin-missing-exports/-/typedoc-plugin-missing-exports-2.0.1.tgz", - "integrity": "sha512-+A78kT78uC0Dbv2EFB9RXHO3iywJ5x89jd4z0bLL7Z8DlOSQjJxhRHf8otXsHZbgRUWAuYqYMA9LzxfuSOc87A==", + "node_modules/typedoc-plugin-rename-defaults": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/typedoc-plugin-rename-defaults/-/typedoc-plugin-rename-defaults-0.6.5.tgz", + "integrity": "sha512-DwkgwRMxgu3UrDR3VUAdnF9jYzM6p7rw6UcVIh4MD7yjEmFDR8WWyOlk6oYgELmRYHxTDx0f0GK6iSgoxSh/Qw==", "dev": true, "peerDependencies": { - "typedoc": "0.24.x" + "typedoc": "0.22.x || 0.23.x || 0.24.x" } }, "node_modules/typedoc/node_modules/brace-expansion": { @@ -11888,10 +11888,10 @@ } } }, - "typedoc-plugin-missing-exports": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/typedoc-plugin-missing-exports/-/typedoc-plugin-missing-exports-2.0.1.tgz", - "integrity": "sha512-+A78kT78uC0Dbv2EFB9RXHO3iywJ5x89jd4z0bLL7Z8DlOSQjJxhRHf8otXsHZbgRUWAuYqYMA9LzxfuSOc87A==", + "typedoc-plugin-rename-defaults": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/typedoc-plugin-rename-defaults/-/typedoc-plugin-rename-defaults-0.6.5.tgz", + "integrity": "sha512-DwkgwRMxgu3UrDR3VUAdnF9jYzM6p7rw6UcVIh4MD7yjEmFDR8WWyOlk6oYgELmRYHxTDx0f0GK6iSgoxSh/Qw==", "dev": true, "requires": {} }, diff --git a/package.json b/package.json index 1b686dd4..6fc8a43e 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "prettier": "^1.19.1", "ts-jest": "^29.1.1", "typedoc": "^0.24.8", - "typedoc-plugin-missing-exports": "^2.0.1", + "typedoc-plugin-rename-defaults": "^0.6.5", "typescript": "^4.9.5" }, "repository": { diff --git a/src/apiClient.ts b/src/apiClient.ts index 107177f5..f4b20d77 100644 --- a/src/apiClient.ts +++ b/src/apiClient.ts @@ -10,6 +10,16 @@ const PACKAGE_JSON = require('package.json').default; const SDK_VERSION = PACKAGE_JSON.version; +/** + * Options for a request to the Nylas API + * @property path The path to the API endpoint + * @property method The HTTP method to use + * @property headers Additional headers to send with the request + * @property queryParams Query parameters to send with the request + * @property body The body of the request + * @property overrides Overrides to the default Nylas API client configuration + * @ignore Not for public use + */ export interface RequestOptionsParams { path: string; method: string; @@ -19,6 +29,16 @@ export interface RequestOptionsParams { overrides?: OverridableNylasConfig; } +/** + * Options for building a request for fetch to understand + * @property path The path to the API endpoint + * @property method The HTTP method to use + * @property headers Additional headers to send with the request + * @property url The URL of the request + * @property body The body of the request + * @property overrides Overrides to the default Nylas API client configuration + * @ignore Not for public use + */ interface RequestOptions { path: string; method: string; @@ -28,14 +48,27 @@ interface RequestOptions { overrides?: Partial; } +/** + * The API client for communicating with the Nylas API + * @ignore Not for public use + */ export default class APIClient { + /** + * The API key to use for authentication + */ apiKey: string; + /** + * The URL to use for communicating with the Nylas API + */ serverUrl: string; + /** + * The timeout for requests to the Nylas API, in seconds + */ timeout: number; - constructor({ apiKey, serverUrl, timeout }: Required) { + constructor({ apiKey, apiUri, timeout }: Required) { this.apiKey = apiKey; - this.serverUrl = serverUrl; + this.serverUrl = apiUri; this.timeout = timeout * 1000; // fetch timeout uses milliseconds } @@ -44,7 +77,7 @@ export default class APIClient { path, queryParams, }: RequestOptionsParams): URL { - const url = new URL(`${overrides?.serverUrl || this.serverUrl}${path}`); + const url = new URL(`${overrides?.apiUri || this.serverUrl}${path}`); return this.setQueryStrings(url, queryParams); } diff --git a/src/config.ts b/src/config.ts index e2f5bba7..3bdbe3f6 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,9 +1,18 @@ +/** + * Configuration options for initializing the Nylas SDK. + * @property apiKey The Nylas API key to use for authentication + * @property apiUri The URL to use for communicating with the Nylas API + * @property timeout The timeout for requests to the Nylas API, in seconds + */ export type NylasConfig = { apiKey: string; - serverUrl?: string; // TODO: rename to nylasAPIUrl + apiUri?: string; timeout?: number; }; +/** + * The options that can override the default Nylas API client configuration. + */ export type OverridableNylasConfig = Partial; /** @@ -14,32 +23,30 @@ export interface Overrides { overrides?: OverridableNylasConfig; } -export enum ResponseType { - CODE = 'code', - TOKEN = 'token', -} - -export type AuthenticateUrlConfig = { - redirectURI: string; - redirectOnError?: boolean; - loginHint?: string; - state?: string; - provider?: string; - scopes?: string[]; - responseType?: ResponseType; -}; - +/** + * Enum representing the available Nylas API regions. + */ export enum Region { Us = 'us', Eu = 'eu', } +/** + * The default Nylas API region. + * @default Region.Us + */ export const DEFAULT_REGION = Region.Us; +/** + * The configuration options for each Nylas API region. + */ type RegionConfig = { nylasAPIUrl: string; }; +/** + * The available preset configuration values for each Nylas API region. + */ export const REGION_CONFIG: Record = { [Region.Us]: { nylasAPIUrl: 'https://api.us.nylas.com', @@ -49,4 +56,8 @@ export const REGION_CONFIG: Record = { }, }; +/** + * The default Nylas API URL. + * @default https://api.us.nylas.com + */ export const DEFAULT_SERVER_URL = REGION_CONFIG[DEFAULT_REGION].nylasAPIUrl; diff --git a/src/models/applicationDetails.ts b/src/models/applicationDetails.ts index f6551d93..67f152f8 100644 --- a/src/models/applicationDetails.ts +++ b/src/models/applicationDetails.ts @@ -1,29 +1,95 @@ import { RedirectUri } from './redirectUri'; +/** + * Interface for a Nylas application details object + */ export interface ApplicationDetails { + /** + * Public Application ID + */ applicationId: string; + /** + * ID of organization + */ organizationId: string; + /** + * Region identifier + */ region: 'us' | 'eu'; + /** + * Environment identifier + */ environment: 'production' | 'staging'; + /** + * Branding details for the application + */ branding: Branding; + /** + * Hosted authentication branding details + */ hostedAuthentication?: HostedAuthentication; + /** + * List of redirect URIs + */ redirectUris?: RedirectUri[]; } +/** + * Interface for branding details for the application + */ interface Branding { + /** + * Name of the application + */ name: string; + /** + * URL points to application icon + */ iconUrl?: string; + /** + * Application / publisher website URL + */ websiteUrl?: string; + /** + * Description of the appli∏cati∏on + */ description?: string; } +/** + * Interface for hosted authentication branding details + */ interface HostedAuthentication { + /** + * URL of the background image + */ backgroundImageUrl?: string; + /** + * Alignment of background image + */ alignment?: string; + /** + * Primary color + */ colorPrimary?: string; + /** + * Secondary color + */ colorSecondary?: string; + /** + * Title + */ title?: string; + /** + * Subtitle + */ subtitle?: string; + /** + * Background color + */ backgroundColor?: string; + /** + * CSS spacing attribute in px + */ spacing?: number; } diff --git a/src/models/auth.ts b/src/models/auth.ts index 91825d12..2c0794cb 100644 --- a/src/models/auth.ts +++ b/src/models/auth.ts @@ -1,48 +1,204 @@ +/** + * Type for the access type of the authentication URL. + */ type AccessType = 'online' | 'offline'; -type Provider = 'google' | 'imap' | 'microsoft' | 'yahoo'; -export type URLForAuthenticationConfig = { +/** + * Type for the different OAuth providers Nylas supports. + */ +export type Provider = 'google' | 'imap' | 'microsoft'; + +/** + * Configuration for generating a URL for OAuth 2.0 authentication. + */ +export interface URLForAuthenticationConfig { + /** + * The client ID of your application. + */ clientId: string; + /** + * Redirect URI of the integration. + */ redirectUri: string; + /** + * The integration provider type that you already had set up with Nylas for this application. + * If not set, the user is directed to the Hosted Login screen and prompted to select a provider. + */ provider?: Provider; + /** + * If the exchange token should return a refresh token too. Not suitable for client side or JavaScript apps. + */ accessType?: AccessType; + /** + * The prompt parameter is used to force the consent screen to be displayed even if the user has already given consent to your application. + */ prompt?: string; + /** + * A space-delimited list of scopes that identify the resources that your application could access on the user's behalf. + * If no scope is given, all of the default integration's scopes are used. + */ scope?: string[]; + /** + * If set to true, the scopes granted to the application will be included in the response. + */ includeGrantScopes?: boolean; - metadata?: string; + /** + * Optional state to be returned after authentication + */ state?: string; + /** + * Prefill the login name (usually email) during authorization flow. + * If a Grant for the provided email already exists, a Grant's re-auth will automatically be initiated. + */ loginHint?: string; -}; +} -export type URLForAdminConsentConfig = URLForAuthenticationConfig & { +/** + * Configuration for generating a URL for admin consent authentication for Microsoft. + */ +export interface URLForAdminConsentConfig extends URLForAuthenticationConfig { + /** + * The credential ID for the Microsoft account + */ credentialId: string; -}; +} +/** + * Interface of a Nylas code exchange request + */ export interface CodeExchangeRequest { + /** + * Should match the same redirect URI that was used for getting the code during the initial authorization request. + */ redirectUri: string; + /** + * OAuth 2.0 code fetched from the previous step. + */ code: string; - codeVerifier?: string; // Only For PKCE auth requests + /** + * Client ID of the application. + */ + clientId: string; + /** + * Client secret of the application. + */ + clientSecret: string; + /** + * The original plain text code verifier (code_challenge) used in the initial authorization request (PKCE). + */ + codeVerifier?: string; } +/** + * Interface of a Nylas token exchange request + */ export interface TokenExchangeRequest { + /** + * Should match the same redirect URI that was used for getting the code during the initial authorization request. + */ redirectUri: string; + /** + * Token to refresh/request your short-lived access token + */ refreshToken: string; + /** + * Client ID of the application. + */ clientId: string; + /** + * Client secret of the application. + */ clientSecret: string; } +/** + * Interface of the object containing the OAuth 2.0 URL as well as the hashed secret. + */ export interface PKCEAuthURL { + /** + * The URL for hosted authentication + */ url: string; + /** + * Server-side challenge used in the OAuth 2.0 flow + */ secret: string; + /** + * SHA-256 hash of the secret + */ secretHash: string; } +/** + * Interface of a Nylas code exchange response + */ export interface CodeExchangeResponse { + /** + * Supports exchanging the code for tokens, or refreshing an access token using [Auth.refreshAccessToken][com.nylas.resources.Auth.refreshAccessToken]. + */ accessToken: string; + /** + * Nylas grant ID that is now successfully created. + */ grantId: string; + /** + * The remaining lifetime of the access token in seconds. + */ expiresIn: number; + /** + * List of scopes associated with this token. + */ + scope: string; + /** + * Only returned if the code was requested using [AccessType.OFFLINE][com.nylas.models.AccessType.OFFLINE]. + */ refreshToken?: string; + /** + * A JWT that contains identity information about the user that is digitally signed by Nylas. + */ idToken?: string; + /** + * Currently always Bearer. + */ tokenType?: string; - scope: string; +} + +/** + * Interface representing the object used to set parameters for detecting a provider. + */ +export interface ProviderDetectParams { + /** + * Email address to detect the provider for. + */ + email: string; + /** + * Client ID of the Nylas application. + */ + clientId: string; + /** + * Search by all providers regardless of created integrations. If unset, defaults to false. + */ + allProviderTypes?: boolean; +} + +/** + * Interface representing the Nylas provider detect response. + */ +export interface ProviderDetectResponse { + /** + * Email provided for autodetection + */ + emailAddress: string; + /** + * Whether the provider was detected + */ + detected: boolean; + /** + * Detected provider + */ + provider?: string; + /** + * Provider type (if IMAP provider detected displays the IMAP provider) + */ + type?: string; } diff --git a/src/models/availability.ts b/src/models/availability.ts index 68355422..1253730b 100644 --- a/src/models/availability.ts +++ b/src/models/availability.ts @@ -1,51 +1,165 @@ -export type GetAvailabilityResponse = { +/** + * Interface for a Nylas get availability response + */ +export interface GetAvailabilityResponse { + /** + * This property is only populated for round-robin events. + * It will contain the order in which the accounts would be next in line to attend the proposed meeting. + */ order: string[]; + /** + * The available time slots where a new meeting can be created for the requested preferences. + */ timeSlots: TimeSlot[]; -}; +} +/** + * Interface for a Nylas get availability request + */ export interface GetAvailabilityRequest { - /** Unix timestamp for the start time to check availability for. */ + /** + * Unix timestamp for the start time to check availability for. + */ startTime: number; - /** Unix timestamp for the end time to check availability for. */ + /** + * Unix timestamp for the end time to check availability for. + */ endTime: number; - participants: Participant[]; + /** + * Participant details to check availability for. + */ + participants: AvailabilityParticipant[]; + /** + * The total number of minutes the event should last. + */ durationMinutes: number; + /** + * Nylas checks from the nearest interval of the passed [startTime]. + * For example, to schedule 30-minute meetings ([durationMinutes]) with 15 minutes between them ([intervalMinutes]). + * If you have a meeting starting at 9:59, the API returns times starting at 10:00. 10:00-10:30, 10:15-10:45. + */ intervalMinutes?: number; + /** + * When set to true, the availability time slots will start at 30 minutes past or on the hour. + * For example, a free slot starting at 16:10 is considered available only from 16:30. + */ roundTo30Minutes?: boolean; + /** + * The rules to apply when checking availability. + */ availabilityRules?: AvailabilityRules; } -export type TimeSlot = { - accounts: string[]; +/** + * Interface for a Nylas availability time slot + */ +export interface TimeSlot { + /** + * The emails of the participants who are available for the time slot. + */ + emails: string[]; + /** + * Unix timestamp for the start of the slot. + */ startTime: string; + /** + * Unix timestamp for the end of the slot. + */ endTime: string; -}; +} +/** + * Interface for the availability rules for a Nylas calendar. + */ export interface AvailabilityRules { + /** + * The method used to determine availability for a meeting. + */ availabilityMethod?: AvailabilityMethod; + /** + * The buffer to add to the start and end of a meeting. + */ buffer?: MeetingBuffer; + /** + * A default set of open hours to apply to all participants. + * You can overwrite these open hours for individual participants by specifying [AvailabilityParticipant.openHours] + * on the participant object. + */ defaultOpenHours?: OpenHours[]; + /** + * The ID on events that Nylas considers when calculating the order of round-robin participants. + * This is used for both max-fairness and max-availability methods. + */ roundRobinEventId?: string; } +/** + * Interface for the meeting buffer object within an availability request. + */ export interface MeetingBuffer { + /** + * The amount of buffer time in increments of 5 minutes to add before existing meetings. + * Defaults to 0. + */ before: number; + /** + * The amount of buffer time in increments of 5 minutes to add after existing meetings. + * Defaults to 0. + */ after: number; } +/** + * Interface of a participant's open hours. + */ export interface OpenHours { + /** + * The days of the week that the open hour settings will be applied to. + * Sunday corresponds to 0 and Saturday corresponds to 6. + */ days: number[]; + /** + * IANA time zone database formatted string (e.g. America/New_York). + * @see List of tz database time zones + */ timezone: string; + /** + * Start time in 24-hour time format. Leading 0's are left off. + */ start: string; + /** + * End time in 24-hour time format. Leading 0's are left off. + */ end: string; + /** + * A list of dates that will be excluded from the open hours. + * Dates should be formatted as YYYY-MM-DD. + */ + exdates: string[]; } -export interface Participant { +/** + * Interface of participant details to check availability for. + */ +export interface AvailabilityParticipant { + /** + * The email address of the participant. + */ email: string; + /** + * An optional list of the calendar IDs associated with each participant's email address. + * If not provided, Nylas uses the primary calendar ID. + */ calendarIds?: string[]; + /** + * Open hours for this participant. The endpoint searches for free time slots during these open hours. + */ openHours?: OpenHours[]; } +/** + * Enum representing the method used to determine availability for a meeting. + */ export enum AvailabilityMethod { MaxFairness = 'max-fairness', MaxAvailability = 'max-availability', diff --git a/src/models/calendars.ts b/src/models/calendars.ts index 9cdb367f..1058ab92 100644 --- a/src/models/calendars.ts +++ b/src/models/calendars.ts @@ -1,35 +1,125 @@ -import { ListQueryParams } from './request'; +import { ListQueryParams } from './listQueryParams'; +/** + * Interface of the query parameters for listing calendars. + */ export interface ListCalendersQueryParams extends ListQueryParams { - /** Metadata */ + /** + * The maximum number of objects to return. + * This field defaults to 50. The maximum allowed value is 200. + */ + limit?: number; + /** + * An identifier that specifies which page of data to return. + * This value should be taken from the [ListResponse.nextCursor] response field. + */ + pageToken?: string; + /** + * Pass in your metadata key and value pair to search for metadata. + */ metadataPair?: Record; } +/** + * Interface of a Nylas create calendar request + */ export interface CreateCalenderRequestBody { + /** + * Name of the Calendar. + */ name: string; - description: string; - location: string; - timezone: string; - metadata: Record; + /** + * Description of the calendar. + */ + description?: string; + /** + * Geographic location of the calendar as free-form text. + */ + location?: string; + /** + * IANA time zone database formatted string (e.g. America/New_York). + * @see List of tz database time zones + */ + timezone?: string; + /** + * A list of key-value pairs storing additional data. + */ + metadata?: Record; } +/** + * Interface of a Nylas update calendar request + */ export interface UpdateCalenderRequestBody extends CreateCalenderRequestBody { + /** + * The background color of the calendar in the hexadecimal format (e.g. #0099EE). + * Empty indicates default color. + */ hexColor?: string; + /** + * The background color of the calendar in the hexadecimal format (e.g. #0099EE). + * Empty indicates default color. (Google only) + */ hexForegroundColor?: string; } -export type Calendar = { +/** + * Interface of a Nylas calendar object + */ +export interface Calendar { + /** + * Globally unique object identifier. + */ id: string; + /** + * Grant ID of the Nylas account. + */ grantId: string; + /** + * Name of the Calendar. + */ name: string; + /** + * The type of object. + */ object: string; + /** + * IANA time zone database formatted string (e.g. America/New_York). + * @see List of tz database time zones + */ timezone: string; + /** + * If the event participants are able to edit the event. + */ readOnly: boolean; + /** + * If the calendar is owned by the user account. + */ isOwnedByUser: boolean; + /** + * Description of the calendar. + */ description?: string; + /** + * Geographic location of the calendar as free-form text. + */ location?: string; + /** + * The background color of the calendar in the hexadecimal format (e.g. #0099EE). + * Empty indicates default color. + */ hexColor?: string; + /** + * The background color of the calendar in the hexadecimal format (e.g. #0099EE). + * Empty indicates default color. (Google only) + */ hexForegroundColor?: string; + /** + * If the calendar is the primary calendar. + */ isPrimary?: boolean; + /** + * A list of key-value pairs storing additional data. + */ metadata?: Record; -}; +} diff --git a/src/models/error.ts b/src/models/error.ts index 7dc8a78d..9b6bee0e 100644 --- a/src/models/error.ts +++ b/src/models/error.ts @@ -1,5 +1,3 @@ -import { NylasApiErrorResponse, AuthErrorResponse } from './response'; - /** * Base class for all Nylas API errors. */ @@ -22,7 +20,8 @@ export abstract class AbstractNylasSdkError extends Error {} /** * Class representation of a general Nylas API error. */ -export class NylasApiError extends AbstractNylasApiError { +export class NylasApiError extends AbstractNylasApiError + implements NylasApiErrorResponseData { /** * Error type. */ @@ -44,7 +43,8 @@ export class NylasApiError extends AbstractNylasApiError { /** * Class representing an OAuth error returned by the Nylas API. */ -export class NylasOAuthError extends AbstractNylasApiError { +export class NylasOAuthError extends AbstractNylasApiError + implements NylasOAuthErrorResponse { /** * Error type. */ @@ -62,7 +62,7 @@ export class NylasOAuthError extends AbstractNylasApiError { */ errorUri: string; - constructor(apiError: AuthErrorResponse, statusCode?: number) { + constructor(apiError: NylasOAuthErrorResponse, statusCode?: number) { super(apiError.errorDescription); this.error = apiError.error; this.errorCode = apiError.errorCode; @@ -91,3 +91,43 @@ export class NylasSdkTimeoutError extends AbstractNylasSdkError { this.timeout = timeout; } } + +/** + * Interface representing the error response from the Nylas API. + */ + +export interface NylasApiErrorResponse { + requestId: string; + error: NylasApiErrorResponseData; +} + +/** + * Interface representing the error data within the response object. + */ +export interface NylasApiErrorResponseData { + type: string; + message: string; + providerError?: any; +} + +/** + * Interface representing an OAuth error returned by the Nylas API. + */ +export interface NylasOAuthErrorResponse { + /** + * 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; +} diff --git a/src/models/events.ts b/src/models/events.ts index 704a961f..5ca8449f 100644 --- a/src/models/events.ts +++ b/src/models/events.ts @@ -1,148 +1,524 @@ -import { ListQueryParams } from './request'; +import { ListQueryParams } from './listQueryParams'; import { Subset } from '../utils'; +/** + * Interface representing a Nylas Event object. + */ export interface Event { + /** + * Globally unique object identifier. + */ id: string; + /** + * Grant ID of the Nylas account. + */ grantId: string; + /** + * The type of object. + */ object: 'event'; + /** + * Calendar ID of the event. + */ calendarId: string; + /** + * This value determines whether to show this event's time block as available on shared or public calendars. + */ busy: boolean; + /** + * If the event participants are able to edit the event. + */ readOnly: boolean; + /** + * Unix timestamp when the event was created. + */ createdAt: number; + /** + * Unix timestamp when the event was last updated. + */ updatedAt: number; + /** + * List of participants invited to the event. Participants may also be rooms or resources. + */ participants: Participant[]; + /** + * Representation of time and duration for events. When object can be in one of four formats (sub-objects): + * - {@link Date} + * - {@link Datespan} + * - {@link Time} + * - {@link Timespan} + */ when: When; + /** + * Representation of conferencing details for events. Conferencing object can be in one of two formats (sub-objects): + * - {@link Autocreate} + * - {@link Details} + */ conferencing: Conferencing; + /** + * Description of the event. + */ description?: string; + /** + * Location of the event, such as a physical address or meeting room name. + */ location?: string; + /** + * Unique id for iCalendar standard, for identifying events across calendaring systems. + * Recurring events may share the same value. Can be null for events synced before the year 2020. + */ icalUid?: string; + /** + * Title of the event. + */ title?: string; + /** + * A link to this event in the provider's UI + */ htmlLink?: string; + /** + * Whether participants of the event should be hidden. + */ hideParticipants?: boolean; + /** + * List of key-value pairs storing additional data. + */ metadata?: Record; + /** + * User who created the event. + * Not supported for all providers. + */ creator?: EmailName; + /** + * Organizer of the event. + */ organizer: EmailName; + /** + * An list of RRULE and EXDATE strings. + * @see RFC-5545 + */ recurrence?: string[]; + /** + * List of reminders for the event. + */ reminders?: Reminder[]; + /** + * Status of the event. + */ status?: Status; + /** + * Visibility of the event, if the event is private or public. + */ visibility?: Visibility; } +/** + * Interface representing a request to create an event. + */ export interface CreateEventRequest { + /** + * Representation of time and duration for events. When object can be in one of four formats (sub-objects): + * - {@link Date} + * - {@link Datespan} + * - {@link Time} + * - {@link Timespan} + */ when: When; + /** + * Title of the event. + */ title?: string; + /** + * This value determines whether to show this event's time block as available on shared or public calendars. + */ busy?: boolean; + /** + * Description of the event. + */ description?: string; + /** + * Location of the event, such as a physical address or meeting room name. + */ location?: string; + /** + * Representation of conferencing details for events. Conferencing object can be in one of two formats (sub-objects): + * - {@link Autocreate} + * - {@link Details} + */ conferencing?: Conferencing; + /** + * The number of minutes before the event start time when a user wants a reminder for this event. + * Reminder minutes need to be entered in the following format: "[20]". + */ reminderMinutes?: string; + /** + * Method to remind the user about the event. (Google only). + */ reminderMethod?: string; + /** + * A list of key-value pairs storing additional data. + */ metadata?: Record; + /** + * List of participants invited to the event. Participants may also be rooms or resources. + */ participants?: Participant[]; + /** + * An list of RRULE and EXDATE strings. + * @see RFC-5545 + */ recurrence?: string[]; + /** + * Calendar ID of the event. + */ calendarId?: string; + /** + * If the event participants are able to edit the event. + */ readOnly?: boolean; - roundRobinOrder?: string[]; + /** + * Visibility of the event, if the event is private or public. + */ visibility?: 'public' | 'private'; + /** + * The maximum number of participants that may attend the event. + */ capacity?: number; + /** + * Whether participants of the event should be hidden. + */ hideParticipants?: boolean; } +/** + * Interface representing a request to update an event. + */ export type UpdateEventRequest = Subset; +/** + * Interface representing the query parameters for listing events. + */ export interface ListEventQueryParams extends ListQueryParams { + /** + * Return events that have a status of cancelled. + * If an event is recurring, then it returns no matter the value set. + * Different providers have different semantics for cancelled events. + */ showCancelled?: boolean; eventId?: string; + /** + * Specify calendar ID of the event. "primary" is a supported value indicating the user's primary calendar. + */ calendarId: string; + /** + * Return events matching the specified title. + */ title?: string; + /** + * Return events matching the specified description. + * Graph: NOT supported + */ description?: string; + /** + * Return events matching the specified location. + */ location?: string; + /** + * Return events ending before the specified unix timestamp. + * Defaults to a month from now. Not respected by metadata filtering. + */ end?: string; + /** + * Return events starting after the specified unix timestamp. + * Defaults to the current timestamp. Not respected by metadata filtering. + */ start?: string; + /** + * Pass in your metadata key and value pair to search for metadata. + */ metadataPair?: Record; + /** + * If true, the response will include an event for each occurrence of a recurring event within the requested time range. + * If false, only a single primary event will be returned for each recurring event. + * Cannot be used when filtering on metadata. + * Defaults to false. + */ expandRecurring?: boolean; + /** + * Returns events with a busy status of true. + */ busy?: boolean; - participants?: string; + /** + * Order results by the specified field. + * Currently only start is supported. + */ + orderBy?: string; + /** + * The maximum number of objects to return. + * This field defaults to 50. The maximum allowed value is 200. + */ + limit?: number; + /** + * An identifier that specifies which page of data to return. + * This value should be taken from the {@link ListResponse.nextCursor} response field. + */ + pageToken?: string; } +/** + * Interface representing of the query parameters for creating an event. + */ export interface CreateEventQueryParams { + /** + * The ID of the calendar to create the event in. + */ calendarId: string; + /** + * Email notifications containing the calendar event is sent to all event participants. + */ notifyParticipants?: boolean; } +/** + * Interface representing of the query parameters for finding an event. + */ export interface FindEventQueryParams { + /** + * Calendar ID to find the event in. "primary" is a supported value indicating the user's primary calendar. + */ calendarId: string; } +/** + * Interface representing of the query parameters for updating events. + */ export type UpdateEventQueryParams = CreateEventQueryParams; + +/** + * Interface representing of the query parameters for destroying events. + */ export type DestroyEventQueryParams = CreateEventQueryParams; +/** + * Enum representing the status of an event. + */ type Status = 'confirmed' | 'tentative' | 'cancelled'; + +/** + * Enum representing the visibility of an event. + */ type Visibility = 'public' | 'private'; + +/** + * Enum representing the supported conferencing providers. + */ type ConferencingProvider = | 'Google Meet' | 'Zoom Meeting' | 'Microsoft Teams' | 'GoToMeeting' | 'WebEx'; + +/** + * Enum representing the status of an event participant. + */ type ParticipantStatus = 'noreply' | 'yes' | 'no' | 'maybe'; + +/** + * Enum representing the different types of reminders. + */ type ReminderMethod = 'email' | 'popup' | 'sound' | 'display'; + +/** + * Type representing the different conferencing objects. + */ type Conferencing = Details | Autocreate; + +/** + * Type representing the different objects representing time and duration for events. + */ type When = Time | Timespan | Date | Datespan; +/** + * Interface of a conferencing details object + */ export interface Details { + /** + * The conferencing provider + */ provider: ConferencingProvider; + + /** + * The conferencing details + */ details: DetailsConfig; } +/** + * Interface of a the configuration for a conferencing object + */ export interface DetailsConfig { + /** + * The conferencing meeting code. Used for Zoom. + */ meetingCode?: string; + /** + * The conferencing meeting password. Used for Zoom. + */ password?: string; + /** + * The conferencing meeting url. + */ url?: string; + /** + * The conferencing meeting pin. Used for Google Meet. + */ pin?: string; + /** + * The conferencing meeting phone numbers. Used for Google Meet. + */ phone?: string[]; } +/** + * Class representation of a conferencing autocreate object + */ export interface Autocreate { + /** + * The conferencing provider + */ provider: ConferencingProvider; + /** + * Empty dict to indicate an intention to autocreate a video link. + * Additional provider settings may be included in autocreate.settings, but Nylas does not validate these. + */ autocreate: Record; } +/** + * Class representation of a specific point in time. + * A meeting at 2pm would be represented as a time subobject. + */ export interface Time { + /** + * A UNIX timestamp representing the time of occurrence. + */ time: number; + /** + * If timezone is present, then the value for time will be read with timezone. + * Timezone using IANA formatted string. (e.g. "America/New_York") + * @see List of tz database time zones + */ timezone: string; } +/** + * Class representation of a time span with start and end times. + * An hour lunch meeting would be represented as timespan subobjects. + */ export interface Timespan { + /** + * The start time of the event. + */ startTime: number; + /** + * The end time of the event. + */ endTime: number; + /** + * The timezone of the start time. + * Timezone using IANA formatted string. (e.g. "America/New_York") + * @see List of tz database time zones + */ startTimezone?: string; + /** + * The timezone of the end time. + * Timezone using IANA formatted string. (e.g. "America/New_York") + * @see List of tz database time zones + */ endTimezone?: string; } +/** + * Class representation of an entire day spans without specific times. + * Your birthday and holidays would be represented as date subobjects. + */ export interface Date { + /** + * Date of occurrence in ISO 8601 format. + * @see ISO 8601 + */ date: string; } +/** + * Class representation of a specific dates without clock-based start or end times. + * A business quarter or academic semester would be represented as datespan subobjects. + */ export interface Datespan { + /** + * The start date in ISO 8601 format. + * @see ISO 8601 + */ startDate: string; + /** + * The end date in ISO 8601 format. + * @see ISO 8601 + */ endDate: string; } +/** + * Interface representing an Event participant. + */ export interface Participant { + /** + * Participant's email address. + */ email: string; + /** + * Participant's name. + */ name?: string; + /** + * Participant's status. + */ status: ParticipantStatus; + /** + * Comment by the participant. + */ comment?: string; + /** + * Participant's phone number. + */ phoneNumber?: string; } +/** + * Interface representing the reminders field of an event. + */ export interface Reminder { + /** + * The number of minutes before the event start time when a user wants a reminder for this event. + * Reminder minutes are in the following format: "[20]". + */ reminderMinutes: string; + /** + * Method to remind the user about the event. (Google only). + */ reminderMethod: ReminderMethod; } +/** + * Interface representing an email address and optional name. + */ export interface EmailName { + /** + * Email address. + */ email: string; + /** + * Full name. + */ name?: string; } diff --git a/src/models/grants.ts b/src/models/grants.ts index 9d8f4008..1950bd6b 100644 --- a/src/models/grants.ts +++ b/src/models/grants.ts @@ -1,39 +1,138 @@ +import { Provider } from './auth'; + +/** + * Interface representing a Nylas Grant object. + */ export interface Grant { + /** + * Globally unique object identifier. + */ id: string; + /** + * OAuth provider that the user authenticated with. + */ provider: string; + /** + * Scopes specified for the grant. + */ scope: string[]; + /** + * Unix timestamp when the grant was created. + */ createdAt: number; + /** + * Status of the grant, if it is still valid or if the user needs to re-authenticate. + */ grantStatus?: string; + /** + * Email address associated with the grant. + */ email?: string; + /** + * End user's client user agent. + */ userAgent?: string; + /** + * End user's client IP address. + */ ip?: string; + /** + * Initial state that was sent as part of the OAuth request. + */ state?: string; + /** + * Unix timestamp when the grant was updated. + */ updatedAt?: number; + /** + * Provider's ID for the user this grant is associated with. + */ providerUserId?: string; + /** + * Settings required by the provider that were sent as part of the OAuth request. + */ settings?: Record; } +/** + * Interface representing a request to create a grant. + */ export interface CreateGrantRequest { - provider: 'google' | 'microsoft' | 'imap'; + /** + * OAuth provider + */ + provider: Provider; + /** + * Settings required by provider. + */ settings: Record; + /** + * Optional state value to return to developer's website after authentication flow is completed. + */ state?: string; + /** + * Optional list of scopes to request. If not specified it will use the integration default scopes. + */ scope?: string[]; } +/** + * Interface representing a request to update a grant. + */ export interface UpdateGrantRequest { + /** + * Settings required by provider. + */ settings?: Record; + /** + * List of integration scopes for the grant. + */ scope?: string[]; } +/** + * Interface representing the query parameters for listing grants. + */ export interface ListGrantsQueryParams { + /** + * The maximum number of objects to return. + * This field defaults to 10. The maximum allowed value is 200. + */ limit?: number; + /** + * Offset grant results by this number. + */ offset?: number; + /** + * Sort entries by field name + */ sortBy?: 'createdAt' | 'updatedAt'; + /** + * Specify ascending or descending order. + */ orderBy?: 'asc' | 'desc'; + /** + * Scope grants from a specific point in time by Unix timestamp. + */ since?: number; + /** + * Scope grants to a specific point in time by Unix timestamp. + */ before?: number; + /** + * Filtering your query based on grant email address (if applicable) + */ email?: string; + /** + * Filtering your query based on grant email status (if applicable) + */ grantStatus?: string; + /** + * Filtering your query based on grant IP address + */ ip?: string; - provider?: string; + /** + * Filtering your query based on OAuth provider + */ + provider?: Provider; } diff --git a/src/models/request.ts b/src/models/listQueryParams.ts similarity index 100% rename from src/models/request.ts rename to src/models/listQueryParams.ts diff --git a/src/models/providers.ts b/src/models/providers.ts deleted file mode 100644 index 1fceb480..00000000 --- a/src/models/providers.ts +++ /dev/null @@ -1,28 +0,0 @@ -export interface ProviderDetectParams { - email: string; - allProviderTypes?: boolean; -} - -export interface ProviderDetectResponse { - emailAddress: string; - detected: boolean; - provider?: string; - type?: string; -} - -export interface Provider { - name: string; - provider: string; - type: string; - settings?: ProviderSettings; -} - -interface ProviderSettings { - name?: string; - imapHost?: string; - imapPort?: number; - smtpHost?: string; - smtpPort?: number; - passwordLink?: string; - primary?: boolean; -} diff --git a/src/models/redirectUri.ts b/src/models/redirectUri.ts index ed97193b..b6f207f4 100644 --- a/src/models/redirectUri.ts +++ b/src/models/redirectUri.ts @@ -1,21 +1,74 @@ +/** + * Interface representation of a Redirect URI object + */ export type RedirectUri = { + /** + * Globally unique object identifier + */ id: string; + /** + * Redirect URL + */ url: string; + /** + * Platform identifier + */ platform: string; + /** + * Configuration settings + */ settings?: RedirectUriSettings; }; +/** + * Configuration settings for a Redirect URI object + */ export type RedirectUriSettings = { + /** + * Related to JS platform + */ origin?: string; + /** + * Related to iOS platform + */ bundleId?: string; + /** + * Related to iOS platform + */ + appStoreId?: string; + /** + * Related to iOS platform + */ + teamId?: string; + /** + * Related to Android platform + */ packageName?: string; + /** + * Related to Android platform + */ sha1CertificateFingerprint?: string; }; +/** + * Class representing a request to create a redirect uri. + */ export type CreateRedirectUriRequest = { + /** + * Redirect URL. + */ url: string; + /** + * Platform identifier. + */ platform: string; + /** + * Optional settings for the redirect uri. + */ settings?: RedirectUriSettings; }; +/** + * Interface representation of a Nylas update redirect uri request + */ export type UpdateRedirectUriRequest = Partial; diff --git a/src/models/response.ts b/src/models/response.ts index 4c3af79d..4c843968 100644 --- a/src/models/response.ts +++ b/src/models/response.ts @@ -1,36 +1,45 @@ +/** + * Interface representation of a Nylas response object + */ export interface NylasResponse { - requestId: string; + /** + * The requested data object + */ data: T; + /** + * The request ID + */ + requestId: string; } +/** + * Interface representation of a Nylas response object that contains a list of objects. + */ export interface NylasListResponse { - requestId: string; + /** + * The list of requested data objects. + */ data: T[]; - nextCursor?: string; -} - -export interface NylasApiErrorResponse { + /** + * The request ID. + */ requestId: string; - error: NylasApiError; -} - -export interface NylasApiError { - type: string; - message: string; - providerError?: Record; + /** + * The cursor to use to get the next page of data. + */ + nextCursor?: string; } +/** + * Interface representing a response to a delete request. + */ export interface NylasDeleteResponse { requestId: string; } -export interface AuthErrorResponse { - error: string; - errorCode: number; - errorDescription: string; - errorUri: string; -} - +/** + * Helper type for pagination + */ export type ListResponseInnerType = T extends NylasListResponse ? R : never; diff --git a/src/models/webhooks.ts b/src/models/webhooks.ts index 92b7d459..91bf00d9 100644 --- a/src/models/webhooks.ts +++ b/src/models/webhooks.ts @@ -6,6 +6,8 @@ export interface Webhook { status: 'active' | 'failing' | 'failed' | 'pause'; notificationEmailAddress?: string; statusUpdatedAt: number; + createdAt: number; + updatedAt: number; } export interface WebhookWithSecret extends Webhook { diff --git a/src/nylas.ts b/src/nylas.ts index 423eb79d..15b53f97 100644 --- a/src/nylas.ts +++ b/src/nylas.ts @@ -6,19 +6,47 @@ import { Auth } from './resources/auth'; import { Webhooks } from './resources/webhooks'; import { Applications } from './resources/applications'; +/** + * The entry point to the Node SDK + * + * A Nylas instance holds a configured http client pointing to a base URL and is intended to be reused and shared + * across threads and time. + */ export default class Nylas { + /** + * Access the Applications API + */ public applications: Applications; + /** + * Access the Auth API + */ public auth: Auth; + /** + * Access the Calendars API + */ public calendars: Calendars; + /** + * Access the Events API + */ public events: Events; + /** + * Access the Webhooks API + */ public webhooks: Webhooks; + /** + * The configured API client + * @ignore Not for public use + */ apiClient: APIClient; + /** + * @param config Configuration options for the Nylas SDK + */ constructor(config: NylasConfig) { this.apiClient = new APIClient({ apiKey: config.apiKey, - serverUrl: config.serverUrl || DEFAULT_SERVER_URL, + apiUri: config.apiUri || DEFAULT_SERVER_URL, timeout: config.timeout || 30, }); diff --git a/src/resources/auth.ts b/src/resources/auth.ts index 0e5a2546..085a83aa 100644 --- a/src/resources/auth.ts +++ b/src/resources/auth.ts @@ -10,6 +10,8 @@ import { PKCEAuthURL, TokenExchangeRequest, CodeExchangeResponse, + ProviderDetectParams, + ProviderDetectResponse, } from '../models/auth'; /** @@ -132,6 +134,21 @@ export class Auth extends Resource { return true; } + /** + * Detect provider from email address + * @param params The parameters to include in the request + * @return The detected provider, if found + */ + public async detectProvider( + params: ProviderDetectParams + ): Promise { + return this.apiClient.request({ + method: 'POST', + path: `/v3/grants/providers/detect`, + queryParams: params, + }); + } + private urlAuthBuilder(config: Record): URL { const url = new URL(`${this.apiClient.serverUrl}/v3/connect/auth`); url.searchParams.set('client_id', config.clientId); diff --git a/src/resources/resource.ts b/src/resources/resource.ts index 19516add..cb2c3de8 100644 --- a/src/resources/resource.ts +++ b/src/resources/resource.ts @@ -1,6 +1,6 @@ import APIClient from '../apiClient'; import { OverridableNylasConfig } from '../config'; -import { ListQueryParams } from '../models/request'; +import { ListQueryParams } from '../models/listQueryParams'; import { NylasResponse, NylasListResponse, diff --git a/src/resources/webhooks.ts b/src/resources/webhooks.ts index e4ffcb0d..0196875f 100644 --- a/src/resources/webhooks.ts +++ b/src/resources/webhooks.ts @@ -10,6 +10,13 @@ import { WebhookWithSecret, } from '../models/webhooks'; +/** + * @property webhookId The ID of the webhook destination to update + */ +interface FindWebhookParams { + webhookId: string; +} + /** * @property requestBody The webhook destination details */ @@ -33,6 +40,11 @@ interface DestroyWebhookParams { webhookId: string; } +/** + * Nylas Webhooks API + * + * The Nylas Webhooks API allows your application to receive notifications in real-time when certain events occur. + */ export class Webhooks extends Resource { /** * List all webhook destinations for the application @@ -47,6 +59,20 @@ export class Webhooks extends Resource { }); } + /** + * Return a webhook destination + * @return The webhook destination + */ + public find({ + webhookId, + overrides, + }: FindWebhookParams & Overrides): Promise> { + return super._find({ + path: `/v3/webhooks/${webhookId}`, + overrides, + }); + } + /** * Create a webhook destination * @returns The created webhook destination @@ -54,9 +80,7 @@ export class Webhooks extends Resource { public create({ requestBody, overrides, - }: CreateWebhookParams & Overrides): Promise< - NylasResponse - > { + }: CreateWebhookParams & Overrides): Promise> { return super._create({ path: `/v3/webhooks`, requestBody, @@ -96,12 +120,14 @@ export class Webhooks extends Resource { /** * Update the webhook secret value for a destination - * @returns The updated webhook destination + * @returns The updated webhook destination with the webhook secret */ public rotateSecret({ webhookId, overrides, - }: DestroyWebhookParams & Overrides): Promise> { + }: DestroyWebhookParams & Overrides): Promise< + NylasResponse + > { return super._update({ path: `/v3/webhooks/${webhookId}/rotate-secret`, requestBody: {}, diff --git a/src/utils.ts b/src/utils.ts index 0ea88abe..7a39769f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,19 @@ import { camelCase, snakeCase } from 'change-case'; +/** + * The type of function that converts a string to a different casing. + * @ignore Not for public use. + */ type CasingFunction = (input: string, options?: any) => string; +/** + * A utility function that recursively converts all keys in an object to a given case. + * @param obj The object to convert + * @param casingFunction The function to use to convert the keys + * @param excludeKeys An array of keys to exclude from conversion + * @returns The converted object + * @ignore Not for public use. + */ function convertCase( obj: Record, casingFunction: CasingFunction, @@ -31,7 +43,13 @@ function convertCase( return newObj; } -// function that recursively converts all keys in an object to camelCase +/** + * A utility function that recursively converts all keys in an object to camelCase. + * @param obj The object to convert + * @param exclude An array of keys to exclude from conversion + * @returns The converted object + * @ignore Not for public use. + */ export function objKeysToCamelCase( obj: Record, exclude?: string[] @@ -39,7 +57,12 @@ export function objKeysToCamelCase( return convertCase(obj, camelCase, exclude); } -// function that recursively converts all keys in an object to snake_case +/** + * A utility function that recursively converts all keys in an object to snake_case. + * @param obj The object to convert + * @param exclude An array of keys to exclude from conversion + * @returns The converted object + */ export function objKeysToSnakeCase( obj: Record, exclude?: string[] diff --git a/tests/apiClient.spec.ts b/tests/apiClient.spec.ts index 1da04512..82063722 100644 --- a/tests/apiClient.spec.ts +++ b/tests/apiClient.spec.ts @@ -20,7 +20,7 @@ describe('APIClient', () => { it('should initialize all the values', () => { const client = new APIClient({ apiKey: 'test', - serverUrl: 'https://test.api.nylas.com', + apiUri: 'https://test.api.nylas.com', timeout: 30, }); @@ -36,7 +36,7 @@ describe('APIClient', () => { beforeAll(() => { client = new APIClient({ apiKey: 'testApiKey', - serverUrl: 'https://api.us.nylas.com', + apiUri: 'https://api.us.nylas.com', timeout: 30, }); }); @@ -49,7 +49,7 @@ describe('APIClient', () => { headers: { 'X-SDK-Test-Header': 'This is a test' }, queryParams: { param: 'value' }, body: { id: 'abc123' }, - overrides: { serverUrl: 'https://test.api.nylas.com' }, + overrides: { apiUri: 'https://test.api.nylas.com' }, }); expect(options.method).toBe('GET'); @@ -107,7 +107,7 @@ describe('APIClient', () => { headers: { 'X-SDK-Test-Header': 'This is a test' }, queryParams: { param: 'value' }, body: { id: 'abc123' }, - overrides: { serverUrl: 'https://override.api.nylas.com' }, + overrides: { apiUri: 'https://override.api.nylas.com' }, }; const newRequest = client.newRequest(options); diff --git a/tests/auth.spec.ts b/tests/auth.spec.ts index dec118cb..a19a96f1 100644 --- a/tests/auth.spec.ts +++ b/tests/auth.spec.ts @@ -15,7 +15,7 @@ describe('Auth', () => { beforeAll(() => { apiClient = new APIClient({ apiKey: 'apiKey', - serverUrl: 'https://test.api.nylas.com', + apiUri: 'https://test.api.nylas.com', timeout: 30, }); diff --git a/tests/events.spec.ts b/tests/events.spec.ts index 0bf2f76e..e010f7a5 100644 --- a/tests/events.spec.ts +++ b/tests/events.spec.ts @@ -9,7 +9,7 @@ describe('Events', () => { beforeAll(() => { apiClient = new APIClient({ apiKey: 'apiKey', - serverUrl: 'https://test.api.nylas.com', + apiUri: 'https://test.api.nylas.com', timeout: 30, }) as jest.Mocked; @@ -25,7 +25,7 @@ describe('Events', () => { calendarId: 'calendar123', }, overrides: { - serverUrl: 'https://test.api.nylas.com', + apiUri: 'https://test.api.nylas.com', }, }); @@ -58,7 +58,7 @@ describe('Events', () => { calendarId: 'calendar123', }, overrides: { - serverUrl: 'https://test.api.nylas.com', + apiUri: 'https://test.api.nylas.com', }, }); apiClient.request.mockResolvedValueOnce({ @@ -102,7 +102,7 @@ describe('Events', () => { calendarId: 'calendar123', }, overrides: { - serverUrl: 'https://test.api.nylas.com', + apiUri: 'https://test.api.nylas.com', }, }); apiClient.request.mockResolvedValueOnce({ @@ -131,7 +131,7 @@ describe('Events', () => { calendarId: 'calendar123', }, overrides: { - serverUrl: 'https://test.api.nylas.com', + apiUri: 'https://test.api.nylas.com', }, }); @@ -162,7 +162,7 @@ describe('Events', () => { calendarId: 'calendar123', }, overrides: { - serverUrl: 'https://test.api.nylas.com', + apiUri: 'https://test.api.nylas.com', }, }); @@ -200,7 +200,7 @@ describe('Events', () => { calendarId: 'calendar123', }, overrides: { - serverUrl: 'https://test.api.nylas.com', + apiUri: 'https://test.api.nylas.com', }, }); @@ -232,7 +232,7 @@ describe('Events', () => { calendarId: 'calendar123', }, overrides: { - serverUrl: 'https://test.api.nylas.com', + apiUri: 'https://test.api.nylas.com', }, }); diff --git a/tests/nylas.spec.ts b/tests/nylas.spec.ts index a4622bdb..baf70c26 100644 --- a/tests/nylas.spec.ts +++ b/tests/nylas.spec.ts @@ -23,7 +23,7 @@ describe('Nylas', () => { it('should configure the apiClient', () => { const nylas = new Nylas({ apiKey: 'test', - serverUrl: 'https://test.nylas.com', + apiUri: 'https://test.nylas.com', timeout: 30, }); diff --git a/tsconfig.json b/tsconfig.json index 9bd05e0e..abaee7f7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,11 +12,12 @@ "noImplicitThis": true }, "typedocOptions": { - "entryPoints": ["src/nylas.ts"], + "entryPointStrategy": "expand", + "entryPoints": ["./src"], "out": "docs", - "plugin": ["typedoc-plugin-missing-exports"], + "plugin": ["typedoc-plugin-rename-defaults"], "excludeExternals": true, - "excludePrivate": true, + "excludePrivate": true }, "include": ["src/**/*"], "exclude": ["tests", "lib"]