diff --git a/CHANGELOG.md b/CHANGELOG.md index 40eb19bf..cb17bc78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Support for `logo` field in `EmailTemplate` class to specify a custom logo URL for booking emails * Support for `show_nylas_branding` field in `EmailTemplate` class to control Nylas branding visibility in booking emails * Support for `metadata` field type in `AdditionalFieldType` enum for scheduler additional fields +* Support for `include_hidden_folders` query parameter in `ListFoldersQueryParams` for Microsoft accounts to control whether hidden folders are included in the response ## [2.10.0] - Release 2025-06-12 diff --git a/examples/src/main/java/com/nylas/examples/FoldersExample.java b/examples/src/main/java/com/nylas/examples/FoldersExample.java index 0a41ba05..319cc20b 100644 --- a/examples/src/main/java/com/nylas/examples/FoldersExample.java +++ b/examples/src/main/java/com/nylas/examples/FoldersExample.java @@ -62,6 +62,42 @@ public static void main(String[] args) { System.out.println(); } + System.out.println("\nšŸ“ Listing folders including hidden ones (Microsoft only)..."); + + // List folders including hidden folders (Microsoft only) + ListFoldersQueryParams hiddenFoldersParams = new ListFoldersQueryParams.Builder() + .includeHiddenFolders(true) // This is the new parameter - Microsoft only + .limit(50) + .build(); + + ListResponse hiddenFolders = nylasClient.folders().list(grantId, hiddenFoldersParams); + System.out.println("Found " + hiddenFolders.getData().size() + " folders including hidden ones:"); + for (Folder folder : hiddenFolders.getData()) { + System.out.println(" - " + folder.getName() + " (ID: " + folder.getId() + ")"); + } + + System.out.println("\nšŸ“ Demonstrating all parameters together..."); + + // Example with all parameters including both new ones + ListFoldersQueryParams comprehensiveParams = new ListFoldersQueryParams.Builder() + .singleLevel(false) // Multi-level hierarchy + .includeHiddenFolders(true) // Include hidden folders + .limit(10) + .select("id,name,parent_id,unread_count") + .build(); + + ListResponse comprehensiveFolders = nylasClient.folders().list(grantId, comprehensiveParams); + System.out.println("Found " + comprehensiveFolders.getData().size() + " folders with comprehensive options:"); + for (Folder folder : comprehensiveFolders.getData()) { + System.out.println(" - " + folder.getName()); + System.out.println(" ID: " + folder.getId()); + System.out.println(" Unread Count: " + (folder.getUnreadCount() != null ? folder.getUnreadCount() : 0)); + if (folder.getParentId() != null) { + System.out.println(" Parent ID: " + folder.getParentId()); + } + System.out.println(); + } + } catch (Exception exception) { System.out.println("āŒ Error listing folders: " + exception.getMessage()); System.out.println("Note: The single_level parameter is Microsoft-specific and may not work with other providers."); diff --git a/examples/src/main/kotlin/com/nylas/examples/KotlinFoldersExample.kt b/examples/src/main/kotlin/com/nylas/examples/KotlinFoldersExample.kt index fac44cab..631bdc49 100644 --- a/examples/src/main/kotlin/com/nylas/examples/KotlinFoldersExample.kt +++ b/examples/src/main/kotlin/com/nylas/examples/KotlinFoldersExample.kt @@ -59,6 +59,42 @@ fun main() { println() } + println("\nšŸ“ Listing folders including hidden ones (Microsoft only)...") + + // List folders including hidden folders (Microsoft only) + val hiddenFoldersParams = ListFoldersQueryParams.Builder() + .includeHiddenFolders(true) // This is the new parameter - Microsoft only + .limit(50) + .build() + + val hiddenFolders = nylasClient.folders().list(grantId, hiddenFoldersParams) + println("Found ${hiddenFolders.data.size} folders including hidden ones:") + hiddenFolders.data.forEach { folder -> + println(" - ${folder.name} (ID: ${folder.id})") + } + + println("\nšŸ“ Demonstrating all parameters together...") + + // Example with all parameters including both new ones + val comprehensiveParams = ListFoldersQueryParams.Builder() + .singleLevel(false) // Multi-level hierarchy + .includeHiddenFolders(true) // Include hidden folders + .limit(10) + .select("id,name,parent_id,unread_count") + .build() + + val comprehensiveFolders = nylasClient.folders().list(grantId, comprehensiveParams) + println("Found ${comprehensiveFolders.data.size} folders with comprehensive options:") + comprehensiveFolders.data.forEach { folder -> + println(" - ${folder.name}") + println(" ID: ${folder.id}") + println(" Unread Count: ${folder.unreadCount ?: 0}") + if (folder.parentId != null) { + println(" Parent ID: ${folder.parentId}") + } + println() + } + } catch (exception: Exception) { println("āŒ Error listing folders: ${exception.message}") println("Note: The single_level parameter is Microsoft-specific and may not work with other providers.") diff --git a/src/main/kotlin/com/nylas/models/ListFoldersQueryParams.kt b/src/main/kotlin/com/nylas/models/ListFoldersQueryParams.kt index bc0c39eb..39baa20c 100644 --- a/src/main/kotlin/com/nylas/models/ListFoldersQueryParams.kt +++ b/src/main/kotlin/com/nylas/models/ListFoldersQueryParams.kt @@ -37,6 +37,12 @@ data class ListFoldersQueryParams( */ @Json(name = "single_level") val singleLevel: Boolean? = null, + /** + * (Microsoft only) When true, Nylas includes hidden folders in its response. + * Defaults to false. + */ + @Json(name = "include_hidden_folders") + val includeHiddenFolders: Boolean? = null, ) : IQueryParams { class Builder { private var limit: Int? = null @@ -44,6 +50,7 @@ data class ListFoldersQueryParams( private var parentId: String? = null private var select: String? = null private var singleLevel: Boolean? = null + private var includeHiddenFolders: Boolean? = null /** * Sets the maximum number of objects to return. @@ -83,6 +90,13 @@ data class ListFoldersQueryParams( */ fun singleLevel(singleLevel: Boolean?) = apply { this.singleLevel = singleLevel } + /** + * Sets whether to include hidden folders in the response. (Microsoft only) + * @param includeHiddenFolders If true, includes hidden folders in the response. + * @return The builder. + */ + fun includeHiddenFolders(includeHiddenFolders: Boolean?) = apply { this.includeHiddenFolders = includeHiddenFolders } + /** * Builds the [ListFoldersQueryParams] object. * @return The [ListFoldersQueryParams] object. @@ -93,6 +107,7 @@ data class ListFoldersQueryParams( parentId = parentId, select = select, singleLevel = singleLevel, + includeHiddenFolders = includeHiddenFolders, ) } } diff --git a/src/test/kotlin/com/nylas/resources/FoldersTests.kt b/src/test/kotlin/com/nylas/resources/FoldersTests.kt index 56fcaf90..4beb8949 100644 --- a/src/test/kotlin/com/nylas/resources/FoldersTests.kt +++ b/src/test/kotlin/com/nylas/resources/FoldersTests.kt @@ -200,6 +200,89 @@ class FoldersTests { assertEquals(null, queryParams.singleLevel) } + @Test + fun `listing folders with include_hidden_folders parameter calls requests with the correct params`() { + val queryParams = + ListFoldersQueryParams( + limit = 10, + pageToken = "abc-123", + select = "id,updated_at", + includeHiddenFolders = true, + ) + + folders.list(grantId, queryParams) + + val pathCaptor = argumentCaptor() + val typeCaptor = argumentCaptor() + val queryParamCaptor = argumentCaptor() + val overrideParamCaptor = argumentCaptor() + verify(mockNylasClient).executeGet>( + pathCaptor.capture(), + typeCaptor.capture(), + queryParamCaptor.capture(), + overrideParamCaptor.capture(), + ) + + assertEquals("v3/grants/$grantId/folders", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(ListResponse::class.java, Folder::class.java), typeCaptor.firstValue) + assertEquals(queryParams, queryParamCaptor.firstValue) + } + + @Test + fun `listing folders with include_hidden_folders false calls requests with the correct params`() { + val queryParams = + ListFoldersQueryParams( + limit = 10, + includeHiddenFolders = false, + ) + + folders.list(grantId, queryParams) + + val pathCaptor = argumentCaptor() + val typeCaptor = argumentCaptor() + val queryParamCaptor = argumentCaptor() + val overrideParamCaptor = argumentCaptor() + verify(mockNylasClient).executeGet>( + pathCaptor.capture(), + typeCaptor.capture(), + queryParamCaptor.capture(), + overrideParamCaptor.capture(), + ) + + assertEquals("v3/grants/$grantId/folders", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(ListResponse::class.java, Folder::class.java), typeCaptor.firstValue) + assertEquals(queryParams, queryParamCaptor.firstValue) + } + + @Test + fun `builder includeHiddenFolders parameter works correctly`() { + val queryParams = ListFoldersQueryParams.Builder() + .limit(10) + .includeHiddenFolders(true) + .build() + + assertEquals(true, queryParams.includeHiddenFolders) + } + + @Test + fun `builder includeHiddenFolders false parameter works correctly`() { + val queryParams = ListFoldersQueryParams.Builder() + .limit(10) + .includeHiddenFolders(false) + .build() + + assertEquals(false, queryParams.includeHiddenFolders) + } + + @Test + fun `builder includeHiddenFolders null parameter works correctly`() { + val queryParams = ListFoldersQueryParams.Builder() + .limit(10) + .build() + + assertEquals(null, queryParams.includeHiddenFolders) + } + @Test fun `finding a folder calls requests with the correct params`() { val folderId = "folder-123"