Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [8.1.2] - 2026-05-19
## [Unreleased]

### Added
- Add Workspaces API support via `nylas.workspaces` — list, find, create, update (PATCH), destroy, plus `autoGroup()` and `manualAssign()` for grouping grants by domain, `default`, `policyId`, and `ruleIds`
- Add Agent Account Lists API support via `nylas.lists` — create lists with `name`, optional `description`, and immutable `type`, plus list, find, update, destroy, `listItems()`, `addItems()`, and `removeItems()` for managing `/v3/lists`
- Add Manage Domains API support via `nylas.domains` — list, find, create, update, destroy, plus `info()` and `verify()` for domain verification (`/v3/admin/domains`). Includes `ServiceAccountSigner` support for Nylas Service Account request signing, bearer-auth suppression, and canonical signed wire bodies.

### Fixed
- Correct `Policies` `PolicyLimits` to expose `limitCountDailyMessageReceived` and `limitCountDailyEmailSent` (replacing a non-existent per-grant field)
- Correct `Rules` `RuleEvaluation.messageId` to be omitted-when-absent (not nullable) and surface `blockedByEvaluationError` on applied actions
- Correct `Rules` list (`GET /v3/rules`) to normalize its nested `{ data: { items, nextCursor } }` envelope back to the flat `{ data, nextCursor }` shape the list machinery expects
- Correct `Applications` `ApplicationDetails` field `redirectUris` → `callbackUris` (V3 wire contract), widen `region`/`environment` to `string`, add hosted-auth/IdP public fields, and add `applications.update()` (PATCH)
- Correct `Applications` `applications.update()` to accept write-only `additionalSettings` (forwarded in the request body, stripped from the response)
- Correct `RedirectUris` `update()` to use PATCH (was PUT), fix `destroy()` return type, make `platform` optional with a typed `RedirectUriPlatform` enum, and surface `deletedAt` on `RedirectUri`

## [8.2.0] - 2026-06-11

### Added
- Add `attachments.downloadNodeStream()` as a Node.js convenience helper for converting attachment downloads to `NodeJS.ReadableStream` ([#731](https://github.com/nylas/nylas-nodejs/pull/731))
Expand Down
15 changes: 12 additions & 3 deletions src/apiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export interface RequestOptionsParams {
headers?: Record<string, string>;
queryParams?: Record<string, any>;
body?: any;
serializedBody?: string | Buffer;
form?: FormData;
overrides?: OverridableNylasConfig;
}
Expand Down Expand Up @@ -146,12 +147,17 @@ export default class APIClient {
...overrides?.headers,
};

return {
const defaultHeaders: Record<string, string> = {
Accept: 'application/json',
'User-Agent': `Nylas Node SDK v${SDK_VERSION}`,
Authorization: `Bearer ${overrides?.apiKey || this.apiKey}`,
...mergedHeaders,
};

if (!overrides?.skipAuth) {
defaultHeaders.Authorization = `Bearer ${overrides?.apiKey || this.apiKey}`;
}

return defaultHeaders;
}

private async sendRequest(options: RequestOptionsParams): Promise<Response> {
Expand Down Expand Up @@ -257,7 +263,10 @@ export default class APIClient {
requestOptions.headers = this.setRequestHeaders(optionParams);
requestOptions.method = optionParams.method;

if (optionParams.body) {
if (optionParams.serializedBody) {
requestOptions.body = optionParams.serializedBody;
requestOptions.headers['Content-Type'] = 'application/json';
} else if (optionParams.body) {
requestOptions.body = JSON.stringify(
objKeysToSnakeCase(optionParams.body, ['metadata']) // metadata should remain as is
);
Expand Down
6 changes: 6 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ export type NylasConfig = {
export type OverridableNylasConfig = {
apiKey?: string;
apiUri?: string;
/**
* Suppress the default bearer Authorization header for endpoints that use a
* different authentication mechanism.
* @ignore Not for public use
*/
skipAuth?: boolean;
/**
* @deprecated Providing timeout in milliseconds is deprecated and will be removed in the next major release. Please use seconds instead.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/models/agentLists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ export interface AgentListItem {

/**
* Interface representing a request to create a Nylas Agent Account list.
*
* The server derives `id`, `itemsCount`, `applicationId`, `organizationId`,
* `createdAt`, and `updatedAt`; they are intentionally not accepted here.
*/
export interface CreateAgentListRequest {
/**
Expand All @@ -89,6 +92,8 @@ export interface CreateAgentListRequest {

/**
* Interface representing a request to update a Nylas Agent Account list.
*
* List `type` is immutable after creation.
*/
export interface UpdateAgentListRequest {
/**
Expand Down
137 changes: 128 additions & 9 deletions src/models/applicationDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ export interface ApplicationDetails {
*/
organizationId: string;
/**
* Region identifier
* Region identifier (e.g. `us`, `eu`). Free-form string, not a closed enum.
*/
region: 'us' | 'eu';
region: string;
/**
* Environment identifier
* Environment identifier (e.g. `sandbox`). Free-form string, not a closed enum.
*/
environment: 'production' | 'staging';
environment: string;
/**
* White-label domain. Omitted when empty.
*/
domain?: string;
/**
* Branding details for the application
*/
Expand All @@ -29,15 +33,34 @@ export interface ApplicationDetails {
*/
hostedAuthentication?: HostedAuthentication;
/**
* List of redirect URIs
* Identity provider (IdP) settings for the application
*/
idpSettings?: IdpSettings;
/**
* List of callback (redirect) URIs.
*
* Read-only on the application object; manage entries via the dedicated
* redirect-uris endpoints (`Nylas.applications.redirectUris`).
*/
callbackUris?: RedirectUri[];
/**
* Unix timestamp (seconds) when the application was created. Omitted when empty.
*/
createdAt?: number;
/**
* Unix timestamp (seconds) when the application was last updated. Omitted when empty.
*/
updatedAt?: number;
/**
* Whether the application is blocked. Omitted when empty.
*/
redirectUris?: RedirectUri[];
blocked?: boolean;
}

/**
* Interface for branding details for the application
*/
interface Branding {
export interface Branding {
/**
* Name of the application
*/
Expand All @@ -51,15 +74,15 @@ interface Branding {
*/
websiteUrl?: string;
/**
* Description of the appli∏cati∏on
* Description of the application
*/
description?: string;
}

/**
* Interface for hosted authentication branding details
*/
interface HostedAuthentication {
export interface HostedAuthentication {
/**
* URL of the background image
*/
Expand Down Expand Up @@ -92,4 +115,100 @@ interface HostedAuthentication {
* CSS spacing attribute in px
*/
spacing?: number;
/**
* URL of the terms of service
*/
termsOfServiceUrl?: string;
/**
* URL of the privacy policy
*/
privacyPolicyUrl?: string;
}

/**
* Interface for identity provider (IdP) settings for the application
*/
export interface IdpSettings {
/**
* Comma-separated list of allowed origins. Each must be an absolute HTTPS URL
* (HTTP allowed for `localhost`/`127.0.0.1`) with no path, query, fragment, or userinfo.
*/
origins?: string;
/**
* Comma-separated list of allowed issuers.
*/
issuers?: string;
}

/**
* Interface for additional settings for the application.
*
* Write-only on update: these values can be set via `PATCH /v3/applications` but are
* stripped from every response, so they are not exposed on {@link ApplicationDetails}.
*/
export interface AdditionalSettings {
/**
* Login URL.
*/
loginUrl?: string;
/**
* Logout URL.
*/
logoutUrl?: string;
/**
* Absolute refresh-token expiration, in seconds.
*/
refreshTokenExpirationAbsolute?: number;
/**
* Idle refresh-token expiration, in seconds.
*/
refreshTokenExpirationIdle?: number;
/**
* Whether to rotate the refresh token on use.
*/
rotateRefreshToken?: boolean;
/**
* Whether to allow query parameters in redirect URIs.
*/
allowQueryParamInRedirectUri?: boolean;
}

/**
* Branding details accepted on the application update path.
*
* Unlike the response {@link Branding} type, `name` is optional here — the source does
* not require `branding.name` on `PATCH /v3/applications`.
*/
export type UpdateBranding = Partial<Branding>;

/**
* Interface representing a request to update application details.
*
* All fields are optional; each supplied nested object is a full replace, not a deep merge.
* Note: `callbackUris`/`redirectUris` are ignored by this endpoint — manage callback URIs
* via the dedicated redirect-uris endpoints.
*/
export interface UpdateApplicationRequest {
/**
* Branding details for the application.
*/
branding?: UpdateBranding;
/**
* Hosted authentication branding details.
*/
hostedAuthentication?: HostedAuthentication;
/**
* Identity provider (IdP) settings for the application.
*/
idpSettings?: IdpSettings;
/**
* White-label domain for the application.
*/
domain?: string;
/**
* Additional settings for the application.
*
* Write-only: persisted on update but stripped from the response.
*/
additionalSettings?: AdditionalSettings;
}
Loading
Loading