diff --git a/Src/Notion.Client/Api/ApiEndpoints.cs b/Src/Notion.Client/Api/ApiEndpoints.cs index 300c2482..f3d060df 100644 --- a/Src/Notion.Client/Api/ApiEndpoints.cs +++ b/Src/Notion.Client/Api/ApiEndpoints.cs @@ -1,4 +1,6 @@ -namespace Notion.Client +using System; + +namespace Notion.Client { public static class ApiEndpoints { @@ -148,5 +150,15 @@ public static class FileUploadsApiUrls public static string List => "/v1/file_uploads"; public static string Retrieve(IRetrieveFileUploadPathParameters pathParameters) => $"/v1/file_uploads/{pathParameters.FileUploadId}"; } + + public static class DataSourcesApiUrls + { + private const string BasePath = "/v1/data_sources"; + public static string Retrieve(IRetrieveDataSourcePathParameters pathParameters) => $"{BasePath}/{pathParameters.DataSourceId}"; + internal static string CreateDataSource() => BasePath; + internal static string Update(IUpdateDataSourcePathParameters pathParameters) => $"{BasePath}/{pathParameters.DataSourceId}"; + internal static string ListDataSourceTemplates(IListDataSourceTemplatesPathParameters pathParameters) => $"/v1/data-sources/{pathParameters.DataSourceId}/templates"; + internal static string Query(IQueryDataSourcePathParameters pathParameters) => $"{BasePath}/{pathParameters.DataSourceId}/query"; + } } } diff --git a/Src/Notion.Client/Api/Blocks/RequestParams/BlocksUpdateParameters/UpdateBlocks/LinkToPageUpdateBlock.cs b/Src/Notion.Client/Api/Blocks/RequestParams/BlocksUpdateParameters/UpdateBlocks/LinkToPageUpdateBlock.cs index 69e088c5..4a62224a 100644 --- a/Src/Notion.Client/Api/Blocks/RequestParams/BlocksUpdateParameters/UpdateBlocks/LinkToPageUpdateBlock.cs +++ b/Src/Notion.Client/Api/Blocks/RequestParams/BlocksUpdateParameters/UpdateBlocks/LinkToPageUpdateBlock.cs @@ -5,6 +5,6 @@ namespace Notion.Client public class LinkToPageUpdateBlock : UpdateBlock { [JsonProperty("link_to_page")] - public IPageParentInput LinkToPage { get; set; } + public ILinkToPage LinkToPage { get; set; } } } diff --git a/Src/Notion.Client/Api/DataSources/Create/DataSourcesClient.cs b/Src/Notion.Client/Api/DataSources/Create/DataSourcesClient.cs new file mode 100644 index 00000000..d0c418b9 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Create/DataSourcesClient.cs @@ -0,0 +1,47 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Notion.Client +{ + public sealed partial class DataSourcesClient + { + public async Task CreateAsync( + CreateDataSourceRequest request, + CancellationToken cancellationToken = default) + { + var endpoint = ApiEndpoints.DataSourcesApiUrls.CreateDataSource(); + + if (request == null) + { + throw new ArgumentNullException(nameof(request)); + } + + ICreateDataSourceBodyParameters body = request; + + if (body.Parent == null) + { + throw new ArgumentNullException(nameof(body.Parent), "Parent property cannot be null."); + } + + if (body.Parent is DatabaseParentRequest dbParentRequest) + { + if (string.IsNullOrWhiteSpace(dbParentRequest.DatabaseId)) + { + throw new ArgumentException("DatabaseId in Parent cannot be null or empty when Parent is of type DatabaseParentRequest.", nameof(request.Parent)); + } + } + + if (body.Properties == null) + { + throw new ArgumentException("Properties cannot be null or empty.", nameof(body.Properties)); + } + + return await _restClient.PostAsync( + endpoint, + body, + cancellationToken: cancellationToken + ); + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Create/Request/CreateDataSourceRequest.cs b/Src/Notion.Client/Api/DataSources/Create/Request/CreateDataSourceRequest.cs new file mode 100644 index 00000000..7ec80efe --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Create/Request/CreateDataSourceRequest.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace Notion.Client +{ + public class CreateDataSourceRequest : ICreateDataSourceBodyParameters + { + public IParentOfDataSourceRequest Parent { get; set; } + public IDictionary Properties { get; set; } + public IEnumerable Title { get; set; } + public IPageIconRequest Icon { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Create/Request/ICreateDataSourceBodyParameters.cs b/Src/Notion.Client/Api/DataSources/Create/Request/ICreateDataSourceBodyParameters.cs new file mode 100644 index 00000000..818b65bd --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Create/Request/ICreateDataSourceBodyParameters.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface ICreateDataSourceBodyParameters + { + [JsonProperty("parent")] + public IParentOfDataSourceRequest Parent { get; set; } + + [JsonProperty("properties")] + public IDictionary Properties { get; set; } + + [JsonProperty("title")] + public IEnumerable Title { get; set; } + + [JsonProperty("icon")] + public IPageIconRequest Icon { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Create/Response/CreateDataSourceResponse.cs b/Src/Notion.Client/Api/DataSources/Create/Response/CreateDataSourceResponse.cs new file mode 100644 index 00000000..c9e10d96 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Create/Response/CreateDataSourceResponse.cs @@ -0,0 +1,6 @@ +namespace Notion.Client +{ + public class CreateDataSourceResponse : DataSourceResponse + { + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/DataSourcesClient.cs b/Src/Notion.Client/Api/DataSources/DataSourcesClient.cs new file mode 100644 index 00000000..e376d500 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/DataSourcesClient.cs @@ -0,0 +1,12 @@ +namespace Notion.Client +{ + public sealed partial class DataSourcesClient : IDataSourcesClient + { + private readonly IRestClient _restClient; + + public DataSourcesClient(IRestClient restClient) + { + _restClient = restClient; + } + } +} diff --git a/Src/Notion.Client/Api/DataSources/IDataSourcesClient.cs b/Src/Notion.Client/Api/DataSources/IDataSourcesClient.cs new file mode 100644 index 00000000..57832b7f --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/IDataSourcesClient.cs @@ -0,0 +1,63 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace Notion.Client +{ + public interface IDataSourcesClient + { + /// + /// Retrieves a data source by its ID. + /// + /// + /// + /// + Task RetrieveAsync( + RetrieveDataSourceRequest request, + CancellationToken cancellationToken = default + ); + + /// + /// Creates a new data source. + /// + /// + /// + /// + Task CreateAsync( + CreateDataSourceRequest request, + CancellationToken cancellationToken = default + ); + + /// + /// Updates an existing data source. + /// + /// + /// + /// + Task UpdateAsync( + UpdateDataSourceRequest request, + CancellationToken cancellationToken = default + ); + + /// + /// Lists the templates for a data source. + /// + /// + /// + /// + Task ListDataSourceTemplatesAsync( + ListDataSourceTemplatesRequest request, + CancellationToken cancellationToken = default + ); + + /// + /// Queries a data source. + /// + /// + /// + /// + Task QueryAsync( + QueryDataSourceRequest request, + CancellationToken cancellationToken = default + ); + } +} diff --git a/Src/Notion.Client/Api/DataSources/ListTemplates/DataSourcesClient.cs b/Src/Notion.Client/Api/DataSources/ListTemplates/DataSourcesClient.cs new file mode 100644 index 00000000..0f1f0e63 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/ListTemplates/DataSourcesClient.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Notion.Client +{ + public sealed partial class DataSourcesClient + { + public async Task ListDataSourceTemplatesAsync( + ListDataSourceTemplatesRequest request, + CancellationToken cancellationToken = default) + { + if (request == null) + { + throw new ArgumentNullException(nameof(request)); + } + + if (string.IsNullOrWhiteSpace(request.DataSourceId)) + { + throw new ArgumentException("DataSourceId cannot be null or empty.", nameof(request.DataSourceId)); + } + + IListDataSourceTemplatesPathParameters pathParameters = request; + + var endpoint = ApiEndpoints.DataSourcesApiUrls.ListDataSourceTemplates(pathParameters); + + IListDataSourceTemplatesQueryParameters queryParameters = request; + + var queryParams = new Dictionary() + { + { "name", queryParameters.Name }, + { "start_cursor", queryParameters.StartCursor }, + { "page_size", queryParameters.PageSize?.ToString() } + }; + + return await _restClient.GetAsync( + endpoint, + queryParams: queryParams, + cancellationToken: cancellationToken + ); + } + } +} diff --git a/Src/Notion.Client/Api/DataSources/ListTemplates/Request/IListDataSourceTemplatesPathParameters.cs b/Src/Notion.Client/Api/DataSources/ListTemplates/Request/IListDataSourceTemplatesPathParameters.cs new file mode 100644 index 00000000..bc3d8c93 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/ListTemplates/Request/IListDataSourceTemplatesPathParameters.cs @@ -0,0 +1,10 @@ +namespace Notion.Client +{ + public interface IListDataSourceTemplatesPathParameters + { + /// + /// The ID of the data source. + /// + public string DataSourceId { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/ListTemplates/Request/IListDataSourceTemplatesQueryParameters.cs b/Src/Notion.Client/Api/DataSources/ListTemplates/Request/IListDataSourceTemplatesQueryParameters.cs new file mode 100644 index 00000000..b2ceb565 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/ListTemplates/Request/IListDataSourceTemplatesQueryParameters.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IListDataSourceTemplatesQueryParameters : IPaginationParameters + { + /// + /// Filter templates by name (case-insensitive substring match). + /// + [JsonProperty("name")] + string Name { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/ListTemplates/Request/ListDataSourceTemplatesRequest.cs b/Src/Notion.Client/Api/DataSources/ListTemplates/Request/ListDataSourceTemplatesRequest.cs new file mode 100644 index 00000000..8e6f9315 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/ListTemplates/Request/ListDataSourceTemplatesRequest.cs @@ -0,0 +1,10 @@ +namespace Notion.Client +{ + public class ListDataSourceTemplatesRequest : IListDataSourceTemplatesPathParameters, IListDataSourceTemplatesQueryParameters + { + public string DataSourceId { get; set; } + public string Name { get; set; } + public string StartCursor { get; set; } + public int? PageSize { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/ListTemplates/Response/DataSourceTemplate.cs b/Src/Notion.Client/Api/DataSources/ListTemplates/Response/DataSourceTemplate.cs new file mode 100644 index 00000000..6470549d --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/ListTemplates/Response/DataSourceTemplate.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DataSourceTemplate + { + /// + /// The unique identifier of the data source template. + /// + [JsonProperty("id")] + public string Id { get; set; } + + /// + /// The name of the data source template. + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// Indicates whether the template is the default template for the data source. + /// + [JsonProperty("is_default")] + public bool IsDefault { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/ListTemplates/Response/ListDataSourceTemplatesResponse.cs b/Src/Notion.Client/Api/DataSources/ListTemplates/Response/ListDataSourceTemplatesResponse.cs new file mode 100644 index 00000000..18b579b8 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/ListTemplates/Response/ListDataSourceTemplatesResponse.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ListDataSourceTemplatesResponse + { + /// + /// A collection of data source templates. + /// + [JsonProperty("templates")] + public IEnumerable Templates { get; set; } + + /// + /// Indicates whether there are more templates to retrieve. + /// + [JsonProperty("has_more")] + public bool HasMore { get; set; } + + /// + /// The cursor to use for fetching the next page of templates. + /// + [JsonProperty("next_cursor")] + public string NextCursor { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/DataSourceResponse.cs b/Src/Notion.Client/Api/DataSources/Models/DataSourceResponse.cs new file mode 100644 index 00000000..14332f86 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/DataSourceResponse.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DataSourceResponse : IObject, IObjectModificationData, IQueryDataSourceResponseObject, ISearchResponseObject + { + public string Id { get; set; } + + public ObjectType Object => ObjectType.DataSource; + + /// + /// The title of the data source. + /// + [JsonProperty("title")] + public IEnumerable Title { get; set; } + + /// + /// A description of the data source. + /// + [JsonProperty("description")] + public IEnumerable Description { get; set; } + + /// + /// The parent of the data source. + /// + [JsonProperty("parent")] + public IParentOfDataSourceResponse Parent { get; set; } + + /// + /// The parent of the data source's containing database. This is typically a page, block, + /// or workspace, but can be another database in the case of wikis. + /// + [JsonProperty("database_parent")] + public IParentOfDatabaseResponse DatabaseParent { get; set; } + + /// + /// Indicates whether the data source is inline within its parent database. + /// + [JsonProperty("is_inline")] + public bool IsInline { get; set; } + + /// + /// Indicates whether the data source is archived. + /// + [JsonProperty("archived")] + public bool Archived { get; set; } + + /// + /// Indicates whether the data source is in the trash. + /// + [JsonProperty("in_trash")] + public bool InTrash { get; set; } + + public DateTime CreatedTime { get; set; } + + public DateTime LastEditedTime { get; set; } + + public PartialUser CreatedBy { get; set; } + + public PartialUser LastEditedBy { get; set; } + + /// + /// The properties schema of the data source. + /// + [JsonProperty("properties")] + public IDictionary Properties { get; set; } + + /// + /// The icon of the data source. + /// + [JsonProperty("icon")] + public IPageIconResponse Icon { get; set; } + + /// + /// The cover image of the data source. + /// + [JsonProperty("cover")] + public IPageCoverResponse Cover { get; set; } + + /// + /// The URL of the data source. + /// + [JsonProperty("url")] + public string Url { get; set; } + + /// + /// The public page URL if the data source has been published to the web. Otherwise, null. + /// + [JsonProperty("public_url")] + public string PublicUrl { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PageCover/ExternalPageCoverResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PageCover/ExternalPageCoverResponse.cs new file mode 100644 index 00000000..c9e2186d --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PageCover/ExternalPageCoverResponse.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ExternalPageCoverResponse : IPageCoverResponse + { + public string Type { get; set; } = "external"; + + [JsonProperty("external")] + public ExternalFileResponse External { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PageCover/FilePageCoverResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PageCover/FilePageCoverResponse.cs new file mode 100644 index 00000000..f567ae64 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PageCover/FilePageCoverResponse.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class FilePageCoverResponse : IPageCoverResponse + { + public string Type { get; set; } = "file"; + + [JsonProperty("file")] + public InternalFileResponse File { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PageCover/IPageCoverResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PageCover/IPageCoverResponse.cs new file mode 100644 index 00000000..9db1719e --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PageCover/IPageCoverResponse.cs @@ -0,0 +1,10 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IPageCoverResponse + { + [JsonProperty("type")] + string Type { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PageIcon/CustomEmojiPageIconResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PageIcon/CustomEmojiPageIconResponse.cs new file mode 100644 index 00000000..6cefac3e --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PageIcon/CustomEmojiPageIconResponse.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CustomEmojiPageIconResponse : IPageIconResponse + { + public string Type { get; set; } = "custom_emoji"; + + [JsonProperty("custom_emoji")] + public CustomEmojiResponse CustomEmoji { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PageIcon/CustomEmojiResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PageIcon/CustomEmojiResponse.cs new file mode 100644 index 00000000..ae227f60 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PageIcon/CustomEmojiResponse.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CustomEmojiResponse + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("url")] + public string Url { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PageIcon/EmojiPageIconResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PageIcon/EmojiPageIconResponse.cs new file mode 100644 index 00000000..0ebb1428 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PageIcon/EmojiPageIconResponse.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class EmojiPageIconResponse : IPageIconResponse + { + public string Type { get; set; } = "emoji"; + + [JsonProperty("emoji")] + public string Emoji { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PageIcon/ExternalFileResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PageIcon/ExternalFileResponse.cs new file mode 100644 index 00000000..414469cc --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PageIcon/ExternalFileResponse.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ExternalFileResponse + { + [JsonProperty("url")] + public string Url { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PageIcon/ExternalPageIconResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PageIcon/ExternalPageIconResponse.cs new file mode 100644 index 00000000..14852fb5 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PageIcon/ExternalPageIconResponse.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ExternalPageIconResponse : IPageIconResponse + { + public string Type { get; set; } = "external"; + + [JsonProperty("external")] + public ExternalFileResponse External { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PageIcon/FilePageIconResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PageIcon/FilePageIconResponse.cs new file mode 100644 index 00000000..3acdf762 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PageIcon/FilePageIconResponse.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class FilePageIconResponse : IPageIconResponse + { + public string Type { get; set; } = "file"; + + [JsonProperty("file")] + public InternalFileResponse File { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PageIcon/IPageIconResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PageIcon/IPageIconResponse.cs new file mode 100644 index 00000000..5d401c99 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PageIcon/IPageIconResponse.cs @@ -0,0 +1,16 @@ +using JsonSubTypes; +using Newtonsoft.Json; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "type")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(EmojiPageIconResponse), "emoji]")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(CustomEmojiPageIconResponse), "custom_emoji")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(FilePageIconResponse), "file")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(ExternalPageIconResponse), "external")] + public interface IPageIconResponse + { + [JsonProperty("type")] + string Type { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PageIcon/InternalFileResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PageIcon/InternalFileResponse.cs new file mode 100644 index 00000000..7979c08f --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PageIcon/InternalFileResponse.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class InternalFileResponse + { + [JsonProperty("url")] + public string Url { get; set; } + + [JsonProperty("expiry_time")] + public DateTime ExpiryTime { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Parents/BlockParentResponse.cs b/Src/Notion.Client/Api/DataSources/Models/Parents/BlockParentResponse.cs new file mode 100644 index 00000000..8a4a309b --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Parents/BlockParentResponse.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class BlockParentResponse : IParentOfDatabaseResponse + { + public string Type { get; set; } = "block_id"; + + [JsonProperty("block_id")] + public string BlockId { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Parents/DataSourceParentResponse.cs b/Src/Notion.Client/Api/DataSources/Models/Parents/DataSourceParentResponse.cs new file mode 100644 index 00000000..a1a6911b --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Parents/DataSourceParentResponse.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DataSourceParentResponse : IParentOfDataSourceResponse + { + public string Type { get; set; } = "data_source_id"; + + [JsonProperty("data_source_id")] + public string DataSourceId { get; set; } + + [JsonProperty("database_id")] + public string DatabaseId { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Parents/DatabaseParentResponse.cs b/Src/Notion.Client/Api/DataSources/Models/Parents/DatabaseParentResponse.cs new file mode 100644 index 00000000..93fc299c --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Parents/DatabaseParentResponse.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DatabaseParentResponse : IParentOfDataSourceResponse, IParentOfDatabaseResponse + { + public string Type { get; set; } = "database_id"; + + [JsonProperty("database_id")] + public string DatabaseId { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Parents/IParentOfDataSourceResponse.cs b/Src/Notion.Client/Api/DataSources/Models/Parents/IParentOfDataSourceResponse.cs new file mode 100644 index 00000000..9f842172 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Parents/IParentOfDataSourceResponse.cs @@ -0,0 +1,14 @@ +using JsonSubTypes; +using Newtonsoft.Json; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "type")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(DatabaseParentResponse), "database_id")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(DataSourceParentResponse), "data_source_id")] + public interface IParentOfDataSourceResponse + { + [JsonProperty("type")] + string Type { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Parents/IParentOfDatabaseResponse.cs b/Src/Notion.Client/Api/DataSources/Models/Parents/IParentOfDatabaseResponse.cs new file mode 100644 index 00000000..380ab5ca --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Parents/IParentOfDatabaseResponse.cs @@ -0,0 +1,16 @@ +using JsonSubTypes; +using Newtonsoft.Json; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "type")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(DatabaseParentResponse), "database_id")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(PageParentResponse), "page_id")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(WorkspaceParentResponse), "workspace")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(BlockParentResponse), "block_id")] + public interface IParentOfDatabaseResponse + { + [JsonProperty("type")] + string Type { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Parents/PageParentResponse.cs b/Src/Notion.Client/Api/DataSources/Models/Parents/PageParentResponse.cs new file mode 100644 index 00000000..554b2407 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Parents/PageParentResponse.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class PageParentResponse : IParentOfDatabaseResponse + { + public string Type { get; set; } = "page_id"; + + [JsonProperty("page_id")] + public string PageId { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Parents/WorkspaceParentResponse.cs b/Src/Notion.Client/Api/DataSources/Models/Parents/WorkspaceParentResponse.cs new file mode 100644 index 00000000..2c715f13 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Parents/WorkspaceParentResponse.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class WorkspaceParentResponse : IParentOfDatabaseResponse + { + public string Type { get; set; } = "workspace"; + + [JsonProperty("workspace")] + public bool Workspace { get; set; } = true; + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/ButtonDataSourcePropertyConfigResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/ButtonDataSourcePropertyConfigResponse.cs new file mode 100644 index 00000000..d6c98978 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/ButtonDataSourcePropertyConfigResponse.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ButtonDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse + { + public override string Type => DataSourcePropertyType.Button; + + [JsonProperty("button")] + public Dictionary Button { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CheckboxUpdatePropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/CheckboxDataSourcePropertyConfigResponse.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CheckboxUpdatePropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/CheckboxDataSourcePropertyConfigResponse.cs index a6890d6e..30683558 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CheckboxUpdatePropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/CheckboxDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class CheckboxUpdatePropertySchema : UpdatePropertySchema + public class CheckboxDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.Checkbox; + [JsonProperty("checkbox")] public Dictionary Checkbox { get; set; } } diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CreatedByUpdatePropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/CreatedByDataSourcePropertyConfigResponse.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CreatedByUpdatePropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/CreatedByDataSourcePropertyConfigResponse.cs index 08a5cf74..96baeacc 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CreatedByUpdatePropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/CreatedByDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class CreatedByUpdatePropertySchema : UpdatePropertySchema + public class CreatedByDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.CreatedBy; + [JsonProperty("created_by")] public Dictionary CreatedBy { get; set; } } diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CreatedTimeUpdatePropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/CreatedTimeDataSourcePropertyConfigResponse.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CreatedTimeUpdatePropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/CreatedTimeDataSourcePropertyConfigResponse.cs index 8089ecbb..b6933269 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CreatedTimeUpdatePropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/CreatedTimeDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class CreatedTimeUpdatePropertySchema : UpdatePropertySchema + public class CreatedTimeDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.CreatedTime; + [JsonProperty("created_time")] public Dictionary CreatedTime { get; set; } } diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/DataSourcePropertyConfigResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/DataSourcePropertyConfigResponse.cs new file mode 100644 index 00000000..8f64dfa7 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/DataSourcePropertyConfigResponse.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using JsonSubTypes; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "type")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(CheckboxDataSourcePropertyConfigResponse), DataSourcePropertyType.Checkbox)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(CreatedByDataSourcePropertyConfigResponse), DataSourcePropertyType.CreatedBy)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(CreatedTimeDataSourcePropertyConfigResponse), DataSourcePropertyType.CreatedTime)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(DateDataSourcePropertyConfigResponse), DataSourcePropertyType.Date)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(EmailDataSourcePropertyConfigResponse), DataSourcePropertyType.Email)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(FilesDataSourcePropertyConfigResponse), DataSourcePropertyType.Files)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(FormulaDataSourcePropertyConfigResponse), DataSourcePropertyType.Formula)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(LastEditedByDataSourcePropertyConfigResponse), DataSourcePropertyType.LastEditedBy)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(LastEditedTimeDataSourcePropertyConfigResponse), DataSourcePropertyType.LastEditedTime)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(MultiSelectDataSourcePropertyConfigResponse), DataSourcePropertyType.MultiSelect)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(NumberDataSourcePropertyConfigResponse), DataSourcePropertyType.Number)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(PeopleDataSourcePropertyConfigResponse), DataSourcePropertyType.People)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(PhoneNumberDataSourcePropertyConfigResponse), DataSourcePropertyType.PhoneNumber)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(RelationDataSourcePropertyConfigResponse), DataSourcePropertyType.Relation)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(RichTextDataSourcePropertyConfigResponse), DataSourcePropertyType.RichText)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(RollupDataSourcePropertyConfigResponse), DataSourcePropertyType.Rollup)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(SelectDataSourcePropertyConfigResponse), DataSourcePropertyType.Select)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(StatusDataSourcePropertyConfigResponse), DataSourcePropertyType.Status)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(TitleDataSourcePropertyConfigResponse), DataSourcePropertyType.Title)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(UrlDataSourcePropertyConfigResponse), DataSourcePropertyType.Url)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(UniqueIdDataSourcePropertyConfigResponse), DataSourcePropertyType.UniqueId)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(ButtonDataSourcePropertyConfigResponse), DataSourcePropertyType.Button)] + public class DataSourcePropertyConfigResponse + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("type")] + [JsonConverter(typeof(StringEnumConverter))] + public virtual string Type { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/DataSourcePropertyType.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/DataSourcePropertyType.cs new file mode 100644 index 00000000..79633208 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/DataSourcePropertyType.cs @@ -0,0 +1,28 @@ +namespace Notion.Client +{ + public static class DataSourcePropertyType + { + public const string Title = "title"; + public const string RichText = "rich_text"; + public const string Number = "number"; + public const string Select = "select"; + public const string MultiSelect = "multi_select"; + public const string Date = "date"; + public const string People = "people"; + public const string Files = "files"; + public const string Checkbox = "checkbox"; + public const string Url = "url"; + public const string Email = "email"; + public const string PhoneNumber = "phone_number"; + public const string Formula = "formula"; + public const string Relation = "relation"; + public const string Rollup = "rollup"; + public const string CreatedTime = "created_time"; + public const string CreatedBy = "created_by"; + public const string LastEditedBy = "last_edited_by"; + public const string LastEditedTime = "last_edited_time"; + public const string Status = "status"; + public const string UniqueId = "unique_id"; + public const string Button = "button"; + } +} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/DateUpdatePropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/DateDataSourcePropertyConfigResponse.cs similarity index 55% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/DateUpdatePropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/DateDataSourcePropertyConfigResponse.cs index 65487dd7..433c6f24 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/DateUpdatePropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/DateDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class DateUpdatePropertySchema : UpdatePropertySchema + public class DateDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.Date; + [JsonProperty("date")] public Dictionary Date { get; set; } } diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/EmailUpdatePropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/EmailDataSourcePropertyConfigResponse.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/EmailUpdatePropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/EmailDataSourcePropertyConfigResponse.cs index 5905e68e..af60e018 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/EmailUpdatePropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/EmailDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class EmailUpdatePropertySchema : UpdatePropertySchema + public class EmailDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.Email; + [JsonProperty("email")] public Dictionary Email { get; set; } } diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/FilesUpdatePropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/FilesDataSourcePropertyConfigResponse.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/FilesUpdatePropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/FilesDataSourcePropertyConfigResponse.cs index 9fb3b531..5af49732 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/FilesUpdatePropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/FilesDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class FilesUpdatePropertySchema : UpdatePropertySchema + public class FilesDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.Files; + [JsonProperty("files")] public Dictionary Files { get; set; } } diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/FormulaDataSourcePropertyConfigResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/FormulaDataSourcePropertyConfigResponse.cs new file mode 100644 index 00000000..af42e2a5 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/FormulaDataSourcePropertyConfigResponse.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class FormulaDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse + { + public override string Type => DataSourcePropertyType.Formula; + + [JsonProperty("formula")] + public FormulaResponse Formula { get; set; } + } + + public class FormulaResponse + { + [JsonProperty("expression")] + public string Expression { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/LastEditedByUpdatePropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/LastEditedByDataSourcePropertyConfigResponse.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/LastEditedByUpdatePropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/LastEditedByDataSourcePropertyConfigResponse.cs index c547538a..1e42ca2f 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/LastEditedByUpdatePropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/LastEditedByDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class LastEditedByUpdatePropertySchema : UpdatePropertySchema + public class LastEditedByDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.LastEditedBy; + [JsonProperty("last_edited_by")] public Dictionary LastEditedBy { get; set; } } diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/LastEditedTimeUpdatePropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/LastEditedTimeDataSourcePropertyConfigResponse.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/LastEditedTimeUpdatePropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/LastEditedTimeDataSourcePropertyConfigResponse.cs index 28c9e55b..e7e6acf0 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/LastEditedTimeUpdatePropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/LastEditedTimeDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class LastEditedTimeUpdatePropertySchema : UpdatePropertySchema + public class LastEditedTimeDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.LastEditedTime; + [JsonProperty("last_edited_time")] public Dictionary LastEditedTime { get; set; } } diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/MultiSelectDataSourcePropertyConfigResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/MultiSelectDataSourcePropertyConfigResponse.cs new file mode 100644 index 00000000..eb0a708d --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/MultiSelectDataSourcePropertyConfigResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class MultiSelectDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse + { + public override string Type => DataSourcePropertyType.MultiSelect; + + [JsonProperty("multi_select")] + public OptionWrapper MultiSelect { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/NumberDataSourcePropertyConfigResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/NumberDataSourcePropertyConfigResponse.cs new file mode 100644 index 00000000..0dcd7de6 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/NumberDataSourcePropertyConfigResponse.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class NumberDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse + { + public override string Type => DataSourcePropertyType.Number; + + [JsonProperty("number")] + public NumberResponse Number { get; set; } + } + + public class NumberResponse + { + [JsonProperty("format")] + public string Format { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/PeopleUpdatePropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/PeopleDataSourcePropertyConfigResponse.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/PeopleUpdatePropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/PeopleDataSourcePropertyConfigResponse.cs index 41a8892d..00124a83 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/PeopleUpdatePropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/PeopleDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class PeopleUpdatePropertySchema : UpdatePropertySchema + public class PeopleDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.People; + [JsonProperty("people")] public Dictionary People { get; set; } } diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/PhoneNumberPropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/PhoneNumberDataSourcePropertyConfigResponse.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/PhoneNumberPropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/PhoneNumberDataSourcePropertyConfigResponse.cs index b4b6d363..a7de1096 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/PhoneNumberPropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/PhoneNumberDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class PhoneNumberPropertySchema : IPropertySchema + public class PhoneNumberDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.PhoneNumber; + [JsonProperty("phone_number")] public Dictionary PhoneNumber { get; set; } } diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RelationProperty/DualPropertyRelationResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RelationProperty/DualPropertyRelationResponse.cs new file mode 100644 index 00000000..c042dcd1 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RelationProperty/DualPropertyRelationResponse.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DualPropertyRelationResponse : RelationDataResponse + { + public override string Type => "dual_property"; + + [JsonProperty("dual_property")] + public Data DualProperty { get; set; } + + public class Data + { + [JsonProperty("synced_property_name")] + public string SyncedPropertyName { get; set; } + + [JsonProperty("synced_property_id")] + public string SyncedPropertyId { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RelationProperty/RelationDataResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RelationProperty/RelationDataResponse.cs new file mode 100644 index 00000000..74c8c3ef --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RelationProperty/RelationDataResponse.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using JsonSubTypes; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "type")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(SinglePropertyRelationResponse), "single_property")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(DualPropertyRelationResponse), "dual_property")] + public abstract class RelationDataResponse + { + [JsonProperty("database_id")] + public string DatabaseId { get; set; } + + [JsonProperty("data_source_id")] + public string DataSourceId { get; set; } + + [JsonProperty("type")] + [JsonConverter(typeof(StringEnumConverter))] + public virtual string Type { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RelationProperty/RelationDataSourcePropertyConfigResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RelationProperty/RelationDataSourcePropertyConfigResponse.cs new file mode 100644 index 00000000..ab8754d0 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RelationProperty/RelationDataSourcePropertyConfigResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class RelationDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse + { + public override string Type => DataSourcePropertyType.Relation; + + [JsonProperty("relation")] + public RelationDataResponse Relation { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RelationProperty/SinglePropertyRelationResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RelationProperty/SinglePropertyRelationResponse.cs new file mode 100644 index 00000000..c50a75e9 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RelationProperty/SinglePropertyRelationResponse.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class SinglePropertyRelationResponse : RelationDataResponse + { + public override string Type => "single_property"; + + [JsonProperty("single_property")] + public Dictionary SingleProperty { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RichTextUpdatePropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RichTextDataSourcePropertyConfigResponse.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RichTextUpdatePropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RichTextDataSourcePropertyConfigResponse.cs index a20ca0ea..5d53cbe4 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RichTextUpdatePropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RichTextDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class RichTextUpdatePropertySchema : UpdatePropertySchema + public class RichTextDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.RichText; + [JsonProperty("rich_text")] public Dictionary RichText { get; set; } } diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RollupConfigUpdatePropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RollupDataSourcePropertyConfigResponse.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RollupConfigUpdatePropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RollupDataSourcePropertyConfigResponse.cs index 8ee2d908..afdad4a8 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RollupConfigUpdatePropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/RollupDataSourcePropertyConfigResponse.cs @@ -1,8 +1,17 @@ -using Newtonsoft.Json; +using System.Collections.Generic; +using Newtonsoft.Json; namespace Notion.Client { - public class RollupConfigUpdatePropertySchema : UpdatePropertySchema + public class RollupDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse + { + public override string Type => DataSourcePropertyType.Rollup; + + [JsonProperty("rollup")] + public RollupResponse Rollup { get; set; } + } + + public class RollupResponse { [JsonProperty("relation_property_name")] public string RelationPropertyName { get; set; } @@ -18,5 +27,8 @@ public class RollupConfigUpdatePropertySchema : UpdatePropertySchema [JsonProperty("function")] public string Function { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } } } diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/SelectDataSourcePropertyConfigResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/SelectDataSourcePropertyConfigResponse.cs new file mode 100644 index 00000000..ee7e6af4 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/SelectDataSourcePropertyConfigResponse.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace Notion.Client +{ + [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")] + public class SelectDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse + { + public override string Type => DataSourcePropertyType.Select; + + public OptionWrapper Select { get; set; } + } + + public class SelectOptionResponse + { + /// + /// Name of the option as it appears in Notion. + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// ID of the option. + /// + [JsonProperty("id")] + public string Id { get; set; } + + /// + /// Color of the option. Possible values are: "default", "gray", "brown", "red", "orange", "yellow", "green", "blue", + /// "purple", "pink". Defaults to "default". + /// + [JsonProperty("color")] + [JsonConverter(typeof(StringEnumConverter))] + public Color? Color { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/StatusDataSourcePropertyConfigResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/StatusDataSourcePropertyConfigResponse.cs new file mode 100644 index 00000000..727fc2a2 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/StatusDataSourcePropertyConfigResponse.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class StatusDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse + { + public override string Type => DataSourcePropertyType.Status; + + [JsonProperty("status")] + public Dictionary Status { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/TitlePropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/TitleDataSourcePropertyConfigResponse.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/TitlePropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/TitleDataSourcePropertyConfigResponse.cs index b7fb2f72..23f2fc68 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/TitlePropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/TitleDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class TitlePropertySchema : IPropertySchema + public class TitleDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.Title; + [JsonProperty("title")] public Dictionary Title { get; set; } } diff --git a/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/UniqueIdDataSourcePropertyConfigResponse.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/UniqueIdDataSourcePropertyConfigResponse.cs new file mode 100644 index 00000000..4ceac5ba --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/UniqueIdDataSourcePropertyConfigResponse.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class UniqueIdDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse + { + public override string Type => DataSourcePropertyType.UniqueId; + + [JsonProperty("unique_id")] + public Dictionary UniqueId { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/UrlPropertySchema.cs b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/UrlDataSourcePropertyConfigResponse.cs similarity index 55% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/UrlPropertySchema.cs rename to Src/Notion.Client/Api/DataSources/Models/PropertyConfig/UrlDataSourcePropertyConfigResponse.cs index 0860fa97..5e25eaa9 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/UrlPropertySchema.cs +++ b/Src/Notion.Client/Api/DataSources/Models/PropertyConfig/UrlDataSourcePropertyConfigResponse.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class UrlPropertySchema : IPropertySchema + public class UrlDataSourcePropertyConfigResponse : DataSourcePropertyConfigResponse { + public override string Type => DataSourcePropertyType.Url; + [JsonProperty("url")] public Dictionary Url { get; set; } } diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/CustomEmojiPageIconRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/CustomEmojiPageIconRequest.cs new file mode 100644 index 00000000..7764f461 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/CustomEmojiPageIconRequest.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CustomEmojiPageIconRequest : IPageIconRequest + { + [JsonProperty("type")] + public string Type => "custom_emoji"; + + [JsonProperty("custom_emoji")] + public CustomEmojiRequest CustomEmoji { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/CustomEmojiRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/CustomEmojiRequest.cs new file mode 100644 index 00000000..d3840836 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/CustomEmojiRequest.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CustomEmojiRequest + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("url")] + public string Url { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/EmojiPageIconRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/EmojiPageIconRequest.cs new file mode 100644 index 00000000..b343bbd8 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/EmojiPageIconRequest.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class EmojiPageIconRequest : IPageIconRequest + { + [JsonProperty("type")] + public string Type => "emoji"; + + [JsonProperty("emoji")] + public string Emoji { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/ExternalPageIconRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/ExternalPageIconRequest.cs new file mode 100644 index 00000000..da7ceded --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/ExternalPageIconRequest.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ExternalPageIconRequest : IPageIconRequest + { + [JsonProperty("type")] + public string Type => "external"; + + [JsonProperty("external")] + public ExternalUrl External { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + + public class ExternalUrl + { + [JsonProperty("url")] + public string Url { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/FileUploadIconRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/FileUploadIconRequest.cs new file mode 100644 index 00000000..bbfd5f74 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/FileUploadIconRequest.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class FileUploadIconRequest : IPageIconRequest + { + [JsonProperty("type")] + public string Type => "file_upload"; + + [JsonProperty("file_upload")] + public FileUploadRequest FileUpload { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + + public class FileUploadRequest + { + [JsonProperty("id")] + public string Id { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/IPageIconRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/IPageIconRequest.cs new file mode 100644 index 00000000..5973a09b --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PageIcon/IPageIconRequest.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IPageIconRequest + { + [JsonProperty("type")] + public string Type { get; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/Parents/IParentOfDataSourceRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/Parents/IParentOfDataSourceRequest.cs new file mode 100644 index 00000000..48d5378c --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/Parents/IParentOfDataSourceRequest.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IParentOfDataSourceRequest + { + [JsonProperty("type")] + public string Type { get; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/ButtonPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/ButtonPropertyConfigurationRequest.cs new file mode 100644 index 00000000..f1797176 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/ButtonPropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ButtonPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "button"; + + [JsonProperty("button")] + public IDictionary Button { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/CheckboxPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/CheckboxPropertyConfigurationRequest.cs new file mode 100644 index 00000000..6702f325 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/CheckboxPropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CheckboxPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "checkbox"; + + [JsonProperty("checkbox")] + public IDictionary Checkbox { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/CreatedByPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/CreatedByPropertyConfigurationRequest.cs new file mode 100644 index 00000000..cfbc4271 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/CreatedByPropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CreatedByPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "created_by"; + + [JsonProperty("created_by")] + public IDictionary CreatedBy { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/CreatedTimePropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/CreatedTimePropertyConfigurationRequest.cs new file mode 100644 index 00000000..420e2676 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/CreatedTimePropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CreatedTimePropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "created_time"; + + [JsonProperty("created_time")] + public IDictionary CreatedTime { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/DatePropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/DatePropertyConfigurationRequest.cs new file mode 100644 index 00000000..abc347b0 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/DatePropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DatePropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "date"; + + [JsonProperty("date")] + public IDictionary Date { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/DualPropertyRelationDataRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/DualPropertyRelationDataRequest.cs new file mode 100644 index 00000000..d46e6181 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/DualPropertyRelationDataRequest.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DualPropertyRelationDataRequest : IRelationDataRequest + { + public string DataSourceId { get; set; } + + [JsonProperty("type")] + public string Type => "dual_property"; + + [JsonProperty("dual_property")] + public Data DualProperty { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + + public class Data + { + [JsonProperty("synced_property_id")] + public string SyncedPropertyId { get; set; } + + [JsonProperty("synced_property_name")] + public string SyncedPropertyName { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/EmailPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/EmailPropertyConfigurationRequest.cs new file mode 100644 index 00000000..43017087 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/EmailPropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class EmailPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "email"; + + [JsonProperty("email")] + public IDictionary Email { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/FilesPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/FilesPropertyConfigurationRequest.cs new file mode 100644 index 00000000..6edf4ece --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/FilesPropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class FilesPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "files"; + + [JsonProperty("files")] + public IDictionary Files { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/FormulaPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/FormulaPropertyConfigurationRequest.cs new file mode 100644 index 00000000..476b2f22 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/FormulaPropertyConfigurationRequest.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class FormulaPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "formula"; + + [JsonProperty("formula")] + public FormulaPropertyConfiguration Formula { get; set; } + + public class FormulaPropertyConfiguration + { + [JsonProperty("expression")] + public string Expression { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/IRelationDataRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/IRelationDataRequest.cs new file mode 100644 index 00000000..aad0407c --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/IRelationDataRequest.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IRelationDataRequest + { + [JsonProperty("data_source_id")] + string DataSourceId { get; set; } + + [JsonProperty("type")] + string Type { get; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/LastEditedByPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/LastEditedByPropertyConfigurationRequest.cs new file mode 100644 index 00000000..ed685597 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/LastEditedByPropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LastEditedByPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "last_edited_by"; + + [JsonProperty("last_edited_by")] + public IDictionary LastEditedBy { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/LastEditedTimePropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/LastEditedTimePropertyConfigurationRequest.cs new file mode 100644 index 00000000..fcf2ffce --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/LastEditedTimePropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LastEditedTimePropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "last_edited_time"; + + [JsonProperty("last_edited_time")] + public IDictionary LastEditedTime { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/LastVisitedTimePropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/LastVisitedTimePropertyConfigurationRequest.cs new file mode 100644 index 00000000..a075a5b3 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/LastVisitedTimePropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LastVisitedTimePropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "last_visited_time"; + + [JsonProperty("last_visited_time")] + public IDictionary LastVisitedTime { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/LocationPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/LocationPropertyConfigurationRequest.cs new file mode 100644 index 00000000..d17e5d5e --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/LocationPropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LocationPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "location"; + + [JsonProperty("location")] + public IDictionary Location { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/MultiSelectPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/MultiSelectPropertyConfigurationRequest.cs new file mode 100644 index 00000000..01a7bd84 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/MultiSelectPropertyConfigurationRequest.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class MultiSelectPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "multi_select"; + + [JsonProperty("multi_select")] + public MultiSelectOptions MultiSelect { get; set; } + + public class MultiSelectOptions + { + [JsonProperty("options")] + public IEnumerable Options { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/NumberPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/NumberPropertyConfigurationRequest.cs new file mode 100644 index 00000000..24d78aa2 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/NumberPropertyConfigurationRequest.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class NumberPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "number"; + + [JsonProperty("number")] + public NumberFormat Number { get; set; } + + public class NumberFormat + { + [JsonProperty("format")] + public string Format { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/PeoplePropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/PeoplePropertyConfigurationRequest.cs new file mode 100644 index 00000000..2f6f9161 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/PeoplePropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class PeoplePropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "people"; + + [JsonProperty("people")] + public IDictionary People { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/PhoneNumberPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/PhoneNumberPropertyConfigurationRequest.cs new file mode 100644 index 00000000..98622827 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/PhoneNumberPropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class PhoneNumberPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "phone_number"; + + [JsonProperty("phone_number")] + public IDictionary PhoneNumber { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/PlacePropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/PlacePropertyConfigurationRequest.cs new file mode 100644 index 00000000..287e6d14 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/PlacePropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class PlacePropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "place"; + + [JsonProperty("place")] + public IDictionary Place { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/PropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/PropertyConfigurationRequest.cs new file mode 100644 index 00000000..e7cab7d2 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/PropertyConfigurationRequest.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class PropertyConfigurationRequest + { + [JsonProperty("type")] + public virtual string Type { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/RelationPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/RelationPropertyConfigurationRequest.cs new file mode 100644 index 00000000..4e8524b2 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/RelationPropertyConfigurationRequest.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class RelationPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "relation"; + + [JsonProperty("relation")] + public IRelationDataRequest Relation { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/RichTextPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/RichTextPropertyConfigurationRequest.cs new file mode 100644 index 00000000..00007987 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/RichTextPropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class RichTextPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "rich_text"; + + [JsonProperty("rich_text")] + public IDictionary RichText { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/RollupPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/RollupPropertyConfigurationRequest.cs new file mode 100644 index 00000000..fc25d45c --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/RollupPropertyConfigurationRequest.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class RollupPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "rollup"; + + [JsonProperty("rollup")] + public RollupOptions Rollup { get; set; } + + public class RollupOptions + { + [JsonProperty("relation_property_name")] + public string RelationPropertyName { get; set; } + + [JsonProperty("relation_property_id")] + public string RelationPropertyId { get; set; } + + [JsonProperty("rollup_property_name")] + public string RollupPropertyName { get; set; } + + [JsonProperty("rollup_property_id")] + public string RollupPropertyId { get; set; } + + [JsonProperty("function")] + public string Function { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/SelectOptionRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/SelectOptionRequest.cs new file mode 100644 index 00000000..b634bd90 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/SelectOptionRequest.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class SelectOptionRequest + { + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("color")] + public string Color { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/SelectPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/SelectPropertyConfigurationRequest.cs new file mode 100644 index 00000000..72e97f82 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/SelectPropertyConfigurationRequest.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class SelectPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "select"; + + [JsonProperty("select")] + public SelectOptions Select { get; set; } + + public class SelectOptions + { + [JsonProperty("options")] + public IEnumerable Options { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/SinglePropertyRelationDataRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/SinglePropertyRelationDataRequest.cs new file mode 100644 index 00000000..308730e3 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/SinglePropertyRelationDataRequest.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class SinglePropertyRelationDataRequest : IRelationDataRequest + { + public string DataSourceId { get; set; } + + [JsonProperty("type")] + public string Type => "single_property"; + + [JsonProperty("single_property")] + public IDictionary SingleProperty { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/StatusPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/StatusPropertyConfigurationRequest.cs new file mode 100644 index 00000000..d3070876 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/StatusPropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class StatusPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "status"; + + [JsonProperty("status")] + public IDictionary Status { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/TitlePropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/TitlePropertyConfigurationRequest.cs new file mode 100644 index 00000000..2da48a11 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/TitlePropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class TitlePropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "title"; + + [JsonProperty("title")] + public IDictionary Title { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/UniqueIdPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/UniqueIdPropertyConfigurationRequest.cs new file mode 100644 index 00000000..bc2a8c42 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/UniqueIdPropertyConfigurationRequest.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class UniqueIdPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "unique_id"; + + [JsonProperty("unique_id")] + public UniqueIdConfiguration UniqueId { get; set; } + + public class UniqueIdConfiguration + { + [JsonProperty("prefix")] + public string Prefix { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/UrlPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/UrlPropertyConfigurationRequest.cs new file mode 100644 index 00000000..cd8746c4 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/UrlPropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class UrlPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "url"; + + [JsonProperty("url")] + public IDictionary Url { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/VerificationPropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/VerificationPropertyConfigurationRequest.cs new file mode 100644 index 00000000..b6383e2a --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Models/Request/PropertyConfiguration/VerificationPropertyConfigurationRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class VerificationPropertyConfigurationRequest : PropertyConfigurationRequest + { + [JsonProperty("type")] + public override string Type => "verification"; + + [JsonProperty("verification")] + public IDictionary Verification { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Query/DataSourcesClient.cs b/Src/Notion.Client/Api/DataSources/Query/DataSourcesClient.cs new file mode 100644 index 00000000..fd43821d --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Query/DataSourcesClient.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Notion.Client +{ + public sealed partial class DataSourcesClient + { + public async Task QueryAsync( + QueryDataSourceRequest request, + CancellationToken cancellationToken = default) + { + IQueryDataSourcePathParameters pathParameters = request; + + if (pathParameters == null) + { + throw new ArgumentNullException(nameof(request), "Request cannot be null and must implement IQueryDataSourcePathParameters."); + } + + if (pathParameters.DataSourceId == null) + { + throw new ArgumentNullException( + nameof(pathParameters.DataSourceId), + "DataSourceId cannot be null. Ensure the request implements IQueryDataSourcePathParameters and has DataSourceId set." + ); + } + + IQueryDataSourceBodyParameters body = request; + + if (body == null) + { + throw new ArgumentNullException(nameof(request), "Request must implement IQueryDataSourceBodyParameters."); + } + + var path = ApiEndpoints.DataSourcesApiUrls.Query(pathParameters); + + var queryParameters = request as IQueryDataSourceQueryParameters; + var queryParams = queryParameters.FilterProperties? + .Select(x => new KeyValuePair("filter_properties", x)); + + // Create a clean body request with only the properties that should be serialized + var bodyRequest = QueryDataSourceBodyRequest.FromRequest(request); + + return await _restClient.PostAsync( + path, + bodyRequest, + queryParams, + cancellationToken: cancellationToken + ); + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Query/Request/IQueryDataSourceBodyParameters.cs b/Src/Notion.Client/Api/DataSources/Query/Request/IQueryDataSourceBodyParameters.cs new file mode 100644 index 00000000..50f22b9c --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Query/Request/IQueryDataSourceBodyParameters.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace Notion.Client +{ + public interface IQueryDataSourceBodyParameters : IPaginationParameters + { + /// + /// A list of sort objects to apply to the query results. + /// + [JsonProperty("sorts")] + IEnumerable Sorts { get; set; } + + /// + /// A filter object to apply to the query results. + /// + [JsonProperty("filter")] + Filter Filter { get; set; } + + /// + /// Whether to include archived results. + /// + [JsonProperty("archived")] + bool? Archived { get; set; } + + /// + /// Whether to include results in trash. + /// + [JsonProperty("in_trash")] + bool? InTrash { get; set; } + + /// + /// Optionally filter the results to only include pages or data sources. + /// + [JsonProperty("result_type")] + [JsonConverter(typeof(StringEnumConverter))] + QueryResultType? ResultType { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Query/Request/IQueryDataSourcePathParameters.cs b/Src/Notion.Client/Api/DataSources/Query/Request/IQueryDataSourcePathParameters.cs new file mode 100644 index 00000000..6fca48f5 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Query/Request/IQueryDataSourcePathParameters.cs @@ -0,0 +1,10 @@ +namespace Notion.Client +{ + public interface IQueryDataSourcePathParameters + { + /// + /// The ID of the data source to query. + /// + string DataSourceId { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Query/Request/IQueryDataSourceQueryParameters.cs b/Src/Notion.Client/Api/DataSources/Query/Request/IQueryDataSourceQueryParameters.cs new file mode 100644 index 00000000..d937d546 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Query/Request/IQueryDataSourceQueryParameters.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IQueryDataSourceQueryParameters + { + /// + /// List of properties to filter the results by. + /// + [JsonProperty("filter_properties")] + IEnumerable FilterProperties { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Query/Request/QueryDataSourceBodyRequest.cs b/Src/Notion.Client/Api/DataSources/Query/Request/QueryDataSourceBodyRequest.cs new file mode 100644 index 00000000..80bc9beb --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Query/Request/QueryDataSourceBodyRequest.cs @@ -0,0 +1,75 @@ +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace Notion.Client +{ + /// + /// Internal concrete implementation of IQueryDataSourceBodyParameters used for JSON serialization. + /// This class contains only the properties that should be serialized in the request body. + /// + internal class QueryDataSourceBodyRequest : IQueryDataSourceBodyParameters + { + /// + /// A list of sort objects to apply to the query results. + /// + [JsonProperty("sorts")] + public IEnumerable Sorts { get; set; } + + /// + /// A filter object to apply to the query results. + /// + [JsonProperty("filter")] + public Filter Filter { get; set; } + + /// + /// When supplied, returns a page of results starting after the cursor provided. + /// + [JsonProperty("start_cursor")] + public string StartCursor { get; set; } + + /// + /// The number of items from the full list desired in the response. Maximum: 100. + /// + [JsonProperty("page_size")] + public int? PageSize { get; set; } + + /// + /// Whether to include archived results. + /// + [JsonProperty("archived")] + public bool? Archived { get; set; } + + /// + /// Whether to include results in trash. + /// + [JsonProperty("in_trash")] + public bool? InTrash { get; set; } + + /// + /// Optionally filter the results to only include pages or data sources. + /// + [JsonProperty("result_type")] + [JsonConverter(typeof(StringEnumConverter))] + public QueryResultType? ResultType { get; set; } + + /// + /// Creates a QueryDataSourceBodyRequest from a QueryDataSourceRequest + /// + /// The source request containing all parameters + /// A new QueryDataSourceBodyRequest with only body parameters + internal static QueryDataSourceBodyRequest FromRequest(QueryDataSourceRequest source) + { + return new QueryDataSourceBodyRequest + { + Sorts = source.Sorts, + Filter = source.Filter, + StartCursor = source.StartCursor, + PageSize = source.PageSize, + Archived = source.Archived, + InTrash = source.InTrash, + ResultType = source.ResultType + }; + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Query/Request/QueryDataSourceRequest.cs b/Src/Notion.Client/Api/DataSources/Query/Request/QueryDataSourceRequest.cs new file mode 100644 index 00000000..0445aa45 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Query/Request/QueryDataSourceRequest.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace Notion.Client +{ + public class QueryDataSourceRequest : IQueryDataSourcePathParameters, IQueryDataSourceQueryParameters, IQueryDataSourceBodyParameters + { + /// + /// The ID of the data source to query. + /// + public string DataSourceId { get; set; } + + public IEnumerable FilterProperties { get; set; } + + /// + /// A list of sort objects to apply to the query results. + /// + [JsonProperty("sorts")] + public IEnumerable Sorts { get; set; } + + /// + /// A filter object to apply to the query results. + /// + [JsonProperty("filter")] + public Filter Filter { get; set; } + + /// + /// When supplied, returns a page of results starting after the cursor provided. + /// + [JsonProperty("start_cursor")] + public string StartCursor { get; set; } + + /// + /// The number of items from the full list desired in the response. Maximum: 100. + /// + [JsonProperty("page_size")] + public int? PageSize { get; set; } + + /// + /// Whether to include archived results. + /// + [JsonProperty("archived")] + public bool? Archived { get; set; } + + /// + /// Whether to include results in trash. + /// + [JsonProperty("in_trash")] + public bool? InTrash { get; set; } + + /// + /// Optionally filter the results to only include pages or data sources. + /// Regular, non-wiki databases only support page children. The default behavior + /// is no result type filtering, returning both pages and data sources for wikis. + /// + [JsonProperty("result_type")] + [JsonConverter(typeof(StringEnumConverter))] + public QueryResultType? ResultType { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Query/Request/QueryResultType.cs b/Src/Notion.Client/Api/DataSources/Query/Request/QueryResultType.cs new file mode 100644 index 00000000..744eb47c --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Query/Request/QueryResultType.cs @@ -0,0 +1,16 @@ +using System.Runtime.Serialization; + +namespace Notion.Client +{ + public enum QueryResultType + { + [EnumMember(Value = null)] + Unknown, + + [EnumMember(Value = "page")] + Page, + + [EnumMember(Value = "data_source")] + DataSource + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Query/Response/IQueryDataSourceResponseObject.cs b/Src/Notion.Client/Api/DataSources/Query/Response/IQueryDataSourceResponseObject.cs new file mode 100644 index 00000000..3c7a4349 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Query/Response/IQueryDataSourceResponseObject.cs @@ -0,0 +1,12 @@ +using JsonSubTypes; +using Newtonsoft.Json; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "type")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(Page), ObjectType.Page)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(DataSourceResponse), ObjectType.Database)] + public interface IQueryDataSourceResponseObject : IObject + { + } +} diff --git a/Src/Notion.Client/Api/DataSources/Query/Response/QueryDataSourceResponse.cs b/Src/Notion.Client/Api/DataSources/Query/Response/QueryDataSourceResponse.cs new file mode 100644 index 00000000..f2253237 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Query/Response/QueryDataSourceResponse.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class QueryDataSourceResponse : PaginatedList + { + [JsonProperty("page_or_data_source")] + public Dictionary PageOrDataSource { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Retrieve/DataSourcesClient.cs b/Src/Notion.Client/Api/DataSources/Retrieve/DataSourcesClient.cs new file mode 100644 index 00000000..41412911 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Retrieve/DataSourcesClient.cs @@ -0,0 +1,30 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Notion.Client +{ + public sealed partial class DataSourcesClient + { + public async Task RetrieveAsync( + RetrieveDataSourceRequest request, + CancellationToken cancellationToken = default) + { + IRetrieveDataSourcePathParameters pathParameters = request; + + if (pathParameters == null) + { + throw new ArgumentNullException(nameof(pathParameters)); + } + + if (string.IsNullOrWhiteSpace(pathParameters.DataSourceId)) + { + throw new ArgumentException("DataSourceId cannot be null or empty.", nameof(pathParameters.DataSourceId)); + } + + var endpoint = ApiEndpoints.DataSourcesApiUrls.Retrieve(pathParameters); + + return await _restClient.GetAsync(endpoint, cancellationToken: cancellationToken); + } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Retrieve/Request/IRetrieveDataSourcePathParameters.cs b/Src/Notion.Client/Api/DataSources/Retrieve/Request/IRetrieveDataSourcePathParameters.cs new file mode 100644 index 00000000..fcf97aaf --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Retrieve/Request/IRetrieveDataSourcePathParameters.cs @@ -0,0 +1,7 @@ +namespace Notion.Client +{ + public interface IRetrieveDataSourcePathParameters + { + string DataSourceId { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Retrieve/Request/RetrieveDataSourceRequest.cs b/Src/Notion.Client/Api/DataSources/Retrieve/Request/RetrieveDataSourceRequest.cs new file mode 100644 index 00000000..8d5d2727 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Retrieve/Request/RetrieveDataSourceRequest.cs @@ -0,0 +1,7 @@ +namespace Notion.Client +{ + public class RetrieveDataSourceRequest : IRetrieveDataSourcePathParameters + { + public string DataSourceId { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Retrieve/Response/RetrieveDataSourceResponse.cs b/Src/Notion.Client/Api/DataSources/Retrieve/Response/RetrieveDataSourceResponse.cs new file mode 100644 index 00000000..88a15e6a --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Retrieve/Response/RetrieveDataSourceResponse.cs @@ -0,0 +1,6 @@ +namespace Notion.Client +{ + public class RetrieveDataSourceResponse : DataSourceResponse + { + } +} diff --git a/Src/Notion.Client/Api/DataSources/Update/DataSourcesClient.cs b/Src/Notion.Client/Api/DataSources/Update/DataSourcesClient.cs new file mode 100644 index 00000000..b7485cc3 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Update/DataSourcesClient.cs @@ -0,0 +1,35 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Notion.Client +{ + public sealed partial class DataSourcesClient + { + public async Task UpdateAsync( + UpdateDataSourceRequest request, + CancellationToken cancellationToken = default) + { + if (request == null) + { + throw new ArgumentNullException(nameof(request)); + } + + if (request.DataSourceId == null) + { + throw new ArgumentNullException(nameof(request.DataSourceId)); + } + + var path = ApiEndpoints.DataSourcesApiUrls.Update(request); + + // Create a clean body request with only the properties that should be serialized + var bodyRequest = UpdateDataSourceBodyRequest.FromRequest(request); + + return await _restClient.PatchAsync( + path, + bodyRequest, + cancellationToken: cancellationToken + ); + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Update/Request/IUpdateDataSourceBodyParameters.cs b/Src/Notion.Client/Api/DataSources/Update/Request/IUpdateDataSourceBodyParameters.cs new file mode 100644 index 00000000..cced986c --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Update/Request/IUpdateDataSourceBodyParameters.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IUpdateDataSourceBodyParameters + { + /// + /// The title of the data source. + /// + IEnumerable Title { get; set; } + + /// + /// Page icon for data source. + /// + IPageIconRequest Icon { get; set; } + + IDictionary Properties { get; set; } + + /// + /// Whether the database should be moved to or from the trash. If not provided, the trash + /// status will not be updated. + /// + [JsonProperty("in_trash")] + bool InTrash { get; set; } + + /// + /// Whether the database should be moved to or from the trash. If not provided, the trash + /// status will not be updated. Equivalent to `in_trash`. + /// + [JsonProperty("archived")] + bool Archived { get; set; } + + /// + /// The parent of the data source. + /// + [JsonProperty("parent")] + IParentOfDataSourceRequest Parent { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Update/Request/IUpdateDataSourcePathParameters.cs b/Src/Notion.Client/Api/DataSources/Update/Request/IUpdateDataSourcePathParameters.cs new file mode 100644 index 00000000..63ecc229 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Update/Request/IUpdateDataSourcePathParameters.cs @@ -0,0 +1,10 @@ +namespace Notion.Client +{ + public interface IUpdateDataSourcePathParameters + { + /// + /// The ID of a Notion data source. + /// + string DataSourceId { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Update/Request/IUpdatePropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Update/Request/IUpdatePropertyConfigurationRequest.cs new file mode 100644 index 00000000..d37682bf --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Update/Request/IUpdatePropertyConfigurationRequest.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + /// + /// Non-generic base interface for update property configuration requests. + /// This allows different property types to be stored in the same collection. + /// + [JsonConverter(typeof(UpdatePropertyConfigurationRequestConverterFactory))] + public interface IUpdatePropertyConfigurationRequest + { + [JsonProperty("name")] + string Name { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Update/Request/UpdateDataSourceBodyRequest.cs b/Src/Notion.Client/Api/DataSources/Update/Request/UpdateDataSourceBodyRequest.cs new file mode 100644 index 00000000..e44e9371 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Update/Request/UpdateDataSourceBodyRequest.cs @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + /// + /// Internal concrete implementation of IUpdateDataSourceBodyParameters used for JSON serialization. + /// This class contains only the properties that should be serialized in the request body. + /// + internal class UpdateDataSourceBodyRequest : IUpdateDataSourceBodyParameters + { + /// + /// The title of the data source. + /// + [JsonProperty("title")] + public IEnumerable Title { get; set; } + + /// + /// Page icon for data source. + /// + [JsonProperty("icon")] + public IPageIconRequest Icon { get; set; } + + /// + /// Properties configuration for the data source. + /// + [JsonProperty("properties")] + public IDictionary Properties { get; set; } + + /// + /// Whether the database should be moved to or from the trash. If not provided, the trash + /// status will not be updated. + /// + [JsonProperty("in_trash")] + public bool InTrash { get; set; } + + /// + /// Whether the database should be moved to or from the trash. If not provided, the trash + /// status will not be updated. Equivalent to `in_trash`. + /// + [JsonProperty("archived")] + public bool Archived { get; set; } + + /// + /// The parent of the data source. + /// + [JsonProperty("parent")] + public IParentOfDataSourceRequest Parent { get; set; } + + /// + /// Creates an UpdateDataSourceBodyRequest from an UpdateDataSourceRequest + /// + /// The source request containing all parameters + /// A new UpdateDataSourceBodyRequest with only body parameters + internal static UpdateDataSourceBodyRequest FromRequest(UpdateDataSourceRequest source) + { + return new UpdateDataSourceBodyRequest + { + Title = source.Title, + Icon = source.Icon, + Properties = source.Properties, + InTrash = source.InTrash, + Archived = source.Archived, + Parent = source.Parent + }; + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/DataSources/Update/Request/UpdateDataSourceRequest.cs b/Src/Notion.Client/Api/DataSources/Update/Request/UpdateDataSourceRequest.cs new file mode 100644 index 00000000..6306e49c --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Update/Request/UpdateDataSourceRequest.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace Notion.Client +{ + public class UpdateDataSourceRequest : IUpdateDataSourcePathParameters, IUpdateDataSourceBodyParameters + { + public string DataSourceId { get; set; } + public IEnumerable Title { get; set; } + public IPageIconRequest Icon { get; set; } + public IDictionary Properties { get; set; } + public bool InTrash { get; set; } + public bool Archived { get; set; } + public IParentOfDataSourceRequest Parent { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Update/Request/UpdatePropertyConfigurationRequest.cs b/Src/Notion.Client/Api/DataSources/Update/Request/UpdatePropertyConfigurationRequest.cs new file mode 100644 index 00000000..d2ae2b9d --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Update/Request/UpdatePropertyConfigurationRequest.cs @@ -0,0 +1,19 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + [JsonConverter(typeof(UpdatePropertyConfigurationRequestConverterFactory))] + public class UpdatePropertyConfigurationRequest : IUpdatePropertyConfigurationRequest where T : PropertyConfigurationRequest + { + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// The property configuration details. + /// + /// This object will get flattened into the parent object when serialized. + /// If null or not provided, the property configuration will remain unchanged. + /// + public T PropertyRequest { get; set; } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Update/Request/UpdatePropertyConfigurationRequestConverter.cs b/Src/Notion.Client/Api/DataSources/Update/Request/UpdatePropertyConfigurationRequestConverter.cs new file mode 100644 index 00000000..bfc666f2 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Update/Request/UpdatePropertyConfigurationRequestConverter.cs @@ -0,0 +1,39 @@ +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Notion.Client +{ + // write custom json convert for UpdatePropertyConfigurationRequest to flatten PropertyRequest into parent object + public class UpdatePropertyConfigurationRequestConverter : JsonConverter> where T : PropertyConfigurationRequest + { + public override bool CanRead => false; + + public override void WriteJson(JsonWriter writer, UpdatePropertyConfigurationRequest value, JsonSerializer serializer) + { + writer.WriteStartObject(); + + if (value.Name != null) + { + writer.WritePropertyName("name"); + writer.WriteValue(value.Name); + } + + if (value.PropertyRequest != null) + { + var propertyRequestJson = JObject.FromObject(value.PropertyRequest, serializer); + foreach (var property in propertyRequestJson.Properties()) + { + property.WriteTo(writer); + } + } + + writer.WriteEndObject(); + } + + public override UpdatePropertyConfigurationRequest ReadJson(JsonReader reader, Type objectType, UpdatePropertyConfigurationRequest existingValue, bool hasExistingValue, JsonSerializer serializer) + { + throw new NotImplementedException("Deserialization is not implemented for UpdatePropertyConfigurationRequest."); + } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Update/Request/UpdatePropertyConfigurationRequestConverterFactory.cs b/Src/Notion.Client/Api/DataSources/Update/Request/UpdatePropertyConfigurationRequestConverterFactory.cs new file mode 100644 index 00000000..11c56231 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Update/Request/UpdatePropertyConfigurationRequestConverterFactory.cs @@ -0,0 +1,44 @@ +using System; +using Newtonsoft.Json; + +namespace Notion.Client +{ + /// + /// Converter factory that creates the appropriate generic converter for UpdatePropertyConfigurationRequest. + /// This solves the issue with open generic types in JsonConverter attributes. + /// + public class UpdatePropertyConfigurationRequestConverterFactory : JsonConverter + { + public override bool CanRead => false; + + public override bool CanWrite => true; + + public override bool CanConvert(Type objectType) + { + return objectType.IsGenericType && + objectType.GetGenericTypeDefinition() == typeof(UpdatePropertyConfigurationRequest<>) && + typeof(PropertyConfigurationRequest).IsAssignableFrom(objectType.GetGenericArguments()[0]); + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value == null) + { + writer.WriteNull(); + return; + } + + var objectType = value.GetType(); + var genericArgument = objectType.GetGenericArguments()[0]; + var converterType = typeof(UpdatePropertyConfigurationRequestConverter<>).MakeGenericType(genericArgument); + var converter = (JsonConverter)Activator.CreateInstance(converterType); + + converter.WriteJson(writer, value, serializer); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotImplementedException("Deserialization is not implemented for UpdatePropertyConfigurationRequest."); + } + } +} diff --git a/Src/Notion.Client/Api/DataSources/Update/Response/UpdateDataSourceResponse.cs b/Src/Notion.Client/Api/DataSources/Update/Response/UpdateDataSourceResponse.cs new file mode 100644 index 00000000..3eb5dd46 --- /dev/null +++ b/Src/Notion.Client/Api/DataSources/Update/Response/UpdateDataSourceResponse.cs @@ -0,0 +1,6 @@ +namespace Notion.Client +{ + public class UpdateDataSourceResponse : DataSourceResponse + { + } +} diff --git a/Src/Notion.Client/Api/Databases/Create/DatabasesClient.cs b/Src/Notion.Client/Api/Databases/Create/DatabasesClient.cs new file mode 100644 index 00000000..a37b15a3 --- /dev/null +++ b/Src/Notion.Client/Api/Databases/Create/DatabasesClient.cs @@ -0,0 +1,28 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using static Notion.Client.ApiEndpoints; + +namespace Notion.Client +{ + public sealed partial class DatabasesClient : IDatabasesClient + { + public async Task CreateAsync( + DatabasesCreateRequest databasesCreateParameters, + CancellationToken cancellationToken = default) + { + var body = (IDatabasesCreateBodyParameters)databasesCreateParameters; + + if (body.Parent == null) + { + throw new ArgumentNullException(nameof(body.Parent), "Parent cannot be null."); + } + + return await _client.PostAsync( + DatabasesApiUrls.Create, + body, + cancellationToken: cancellationToken + ); + } + } +} diff --git a/Src/Notion.Client/Api/Databases/Create/Request/DatabasesCreateRequest.cs b/Src/Notion.Client/Api/Databases/Create/Request/DatabasesCreateRequest.cs new file mode 100644 index 00000000..6ef138fd --- /dev/null +++ b/Src/Notion.Client/Api/Databases/Create/Request/DatabasesCreateRequest.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DatabasesCreateRequest : IDatabasesCreateBodyParameters + { + public IParentOfDatabaseRequest Parent { get; set; } + + public List Title { get; set; } + + public List Description { get; set; } + + public bool? IsInline { get; set; } + + public InitialDataSourceRequest InitialDataSource { get; set; } + + public IPageIconRequest Icon { get; set; } + + public FileObject Cover { get; set; } + } + + public class InitialDataSourceRequest + { + [JsonProperty("properties")] + public Dictionary Properties { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Databases/Create/Request/IDatabasesCreateBodyParameters.cs b/Src/Notion.Client/Api/Databases/Create/Request/IDatabasesCreateBodyParameters.cs new file mode 100644 index 00000000..b693eed3 --- /dev/null +++ b/Src/Notion.Client/Api/Databases/Create/Request/IDatabasesCreateBodyParameters.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IDatabasesCreateBodyParameters + { + /// + /// Specifies the parent page or workspace where the database will be created. + /// + [JsonProperty("parent")] + IParentOfDatabaseRequest Parent { get; set; } + + /// + /// The title of the database. + /// + [JsonProperty("title")] + List Title { get; set; } + + /// + /// The description of the database. + /// + [JsonProperty("description")] + List Description { get; set; } + + /// + /// Indicates whether the database is inline. + /// + [JsonProperty("is_inline")] + bool? IsInline { get; set; } + + /// + /// Initial data source configuration for the database. + /// + [JsonProperty("initial_data_source")] + InitialDataSourceRequest InitialDataSource { get; set; } + + /// + /// Page icon for the database. + /// + [JsonProperty("icon")] + public IPageIconRequest Icon { get; set; } + + /// + /// Cover image for the database. + /// + [JsonProperty("cover")] + public FileObject Cover { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/MentionInput.cs b/Src/Notion.Client/Api/Databases/Create/Request/MentionInput.cs similarity index 100% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/MentionInput.cs rename to Src/Notion.Client/Api/Databases/Create/Request/MentionInput.cs diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/ParentPageInput.cs b/Src/Notion.Client/Api/Databases/Create/Request/ParentPageInput.cs similarity index 73% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/ParentPageInput.cs rename to Src/Notion.Client/Api/Databases/Create/Request/ParentPageInput.cs index f931de63..fcd7cbc8 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/ParentPageInput.cs +++ b/Src/Notion.Client/Api/Databases/Create/Request/ParentPageInput.cs @@ -2,7 +2,7 @@ namespace Notion.Client { - public class ParentPageInput : IPageParentInput + public class ParentPageInput { [JsonProperty("page_id")] public string PageId { get; set; } diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/RichTextBaseInput.cs b/Src/Notion.Client/Api/Databases/Create/Request/RichTextBaseInput.cs similarity index 100% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/RichTextBaseInput.cs rename to Src/Notion.Client/Api/Databases/Create/Request/RichTextBaseInput.cs diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/RichTextEquationInput.cs b/Src/Notion.Client/Api/Databases/Create/Request/RichTextEquationInput.cs similarity index 100% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/RichTextEquationInput.cs rename to Src/Notion.Client/Api/Databases/Create/Request/RichTextEquationInput.cs diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/RichTextMentionInput.cs b/Src/Notion.Client/Api/Databases/Create/Request/RichTextMentionInput.cs similarity index 100% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/RichTextMentionInput.cs rename to Src/Notion.Client/Api/Databases/Create/Request/RichTextMentionInput.cs diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/RichTextTextInput.cs b/Src/Notion.Client/Api/Databases/Create/Request/RichTextTextInput.cs similarity index 100% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/RichTextTextInput.cs rename to Src/Notion.Client/Api/Databases/Create/Request/RichTextTextInput.cs diff --git a/Src/Notion.Client/Api/Databases/DatabasesClient.cs b/Src/Notion.Client/Api/Databases/DatabasesClient.cs index a3dc9a8c..8bb428f4 100644 --- a/Src/Notion.Client/Api/Databases/DatabasesClient.cs +++ b/Src/Notion.Client/Api/Databases/DatabasesClient.cs @@ -23,19 +23,5 @@ public async Task RetrieveAsync(string databaseId, CancellationToken c return await _client.GetAsync(DatabasesApiUrls.Retrieve(databaseId), cancellationToken: cancellationToken); } - - public async Task CreateAsync(DatabasesCreateParameters databasesCreateParameters, CancellationToken cancellationToken = default) - { - var body = (IDatabasesCreateBodyParameters)databasesCreateParameters; - - return await _client.PostAsync(DatabasesApiUrls.Create, body, cancellationToken: cancellationToken); - } - - public async Task UpdateAsync(string databaseId, DatabasesUpdateParameters databasesUpdateParameters, CancellationToken cancellationToken = default) - { - var body = (IDatabasesUpdateBodyParameters)databasesUpdateParameters; - - return await _client.PatchAsync(DatabasesApiUrls.Update(databaseId), body, cancellationToken: cancellationToken); - } } } diff --git a/Src/Notion.Client/Api/Databases/IDatabasesClient.cs b/Src/Notion.Client/Api/Databases/IDatabasesClient.cs index 98df1273..34f7113d 100644 --- a/Src/Notion.Client/Api/Databases/IDatabasesClient.cs +++ b/Src/Notion.Client/Api/Databases/IDatabasesClient.cs @@ -14,18 +14,6 @@ public interface IDatabasesClient /// Task RetrieveAsync(string databaseId, CancellationToken cancellationToken = default); - /// - /// Gets a list of Pages contained in the database, filtered and ordered according to the - /// filter conditions and sort criteria provided in the request. The response may contain - /// fewer than page_size of results. - /// - /// - /// - /// - /// - /// - Task QueryAsync(string databaseId, DatabasesQueryParameters databasesQueryParameters, CancellationToken cancellationToken = default); - /// /// Creates a database as a subpage in the specified parent page, with the specified properties schema. /// @@ -33,16 +21,15 @@ public interface IDatabasesClient /// /// /// - Task CreateAsync(DatabasesCreateParameters databasesCreateParameters, CancellationToken cancellationToken = default); + Task CreateAsync(DatabasesCreateRequest databasesCreateParameters, CancellationToken cancellationToken = default); /// /// Updates an existing database as specified by the parameters. /// - /// - /// + /// /// /// /// - Task UpdateAsync(string databaseId, DatabasesUpdateParameters databasesUpdateParameters, CancellationToken cancellationToken = default); + Task UpdateAsync(DatabasesUpdateRequest databasesUpdateRequest, CancellationToken cancellationToken = default); } } diff --git a/Src/Notion.Client/Api/Databases/Models/Request/IParentOfDatabaseRequest.cs b/Src/Notion.Client/Api/Databases/Models/Request/IParentOfDatabaseRequest.cs new file mode 100644 index 00000000..ed6d33ed --- /dev/null +++ b/Src/Notion.Client/Api/Databases/Models/Request/IParentOfDatabaseRequest.cs @@ -0,0 +1,10 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IParentOfDatabaseRequest + { + [JsonProperty("type")] + string Type { get; } + } +} diff --git a/Src/Notion.Client/Api/Databases/Models/Request/PageParentOfDatabaseRequest.cs b/Src/Notion.Client/Api/Databases/Models/Request/PageParentOfDatabaseRequest.cs new file mode 100644 index 00000000..c25262b8 --- /dev/null +++ b/Src/Notion.Client/Api/Databases/Models/Request/PageParentOfDatabaseRequest.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class PageParentOfDatabaseRequest : IParentOfDatabaseRequest + { + [JsonProperty("type")] + public string Type => "page_id"; + + [JsonProperty("page_id")] + public string PageId { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Databases/Models/Request/WorkspaceParentOfDatabaseRequest.cs b/Src/Notion.Client/Api/Databases/Models/Request/WorkspaceParentOfDatabaseRequest.cs new file mode 100644 index 00000000..b6689038 --- /dev/null +++ b/Src/Notion.Client/Api/Databases/Models/Request/WorkspaceParentOfDatabaseRequest.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class WorkspaceParentOfDatabaseRequest : IParentOfDatabaseRequest + { + [JsonProperty("type")] + public string Type => "workspace"; + + [JsonProperty("workspace")] + public bool Workspace => true; + } +} diff --git a/Src/Notion.Client/Api/Databases/Query/DatabasesClient.cs b/Src/Notion.Client/Api/Databases/Query/DatabasesClient.cs deleted file mode 100644 index 2d0c62be..00000000 --- a/Src/Notion.Client/Api/Databases/Query/DatabasesClient.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace Notion.Client -{ - public sealed partial class DatabasesClient - { - public async Task QueryAsync( - string databaseId, - DatabasesQueryParameters databasesQueryParameters, CancellationToken cancellationToken = default) - { - var body = (IDatabaseQueryBodyParameters)databasesQueryParameters; - var queryParameters = (IDatabaseQueryQueryParameters)databasesQueryParameters; - - var queryParams = queryParameters.FilterProperties? - .Select(x => new KeyValuePair("filter_properties", x)); - - return await _client.PostAsync( - ApiEndpoints.DatabasesApiUrls.Query(databaseId), - body, - queryParams, - cancellationToken: cancellationToken - ); - } - } -} diff --git a/Src/Notion.Client/Api/Databases/Query/Request/DatabasesQueryParameters.cs b/Src/Notion.Client/Api/Databases/Query/Request/DatabasesQueryParameters.cs deleted file mode 100644 index 2c2bb030..00000000 --- a/Src/Notion.Client/Api/Databases/Query/Request/DatabasesQueryParameters.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Collections.Generic; - -namespace Notion.Client -{ - public class DatabasesQueryParameters : IDatabaseQueryBodyParameters, IDatabaseQueryQueryParameters - { - public Filter Filter { get; set; } - - public List Sorts { get; set; } - - public string StartCursor { get; set; } - - public int? PageSize { get; set; } - - public List FilterProperties { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/Query/Request/IDatabaseQueryBodyParameters.cs b/Src/Notion.Client/Api/Databases/Query/Request/IDatabaseQueryBodyParameters.cs deleted file mode 100644 index 4ac46860..00000000 --- a/Src/Notion.Client/Api/Databases/Query/Request/IDatabaseQueryBodyParameters.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public interface IDatabaseQueryBodyParameters : IPaginationParameters - { - [JsonProperty("filter")] - Filter Filter { get; set; } - - [JsonProperty("sorts")] - List Sorts { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/Query/Request/IDatabaseQueryQueryParameters.cs b/Src/Notion.Client/Api/Databases/Query/Request/IDatabaseQueryQueryParameters.cs deleted file mode 100644 index f8ba1f41..00000000 --- a/Src/Notion.Client/Api/Databases/Query/Request/IDatabaseQueryQueryParameters.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public interface IDatabaseQueryQueryParameters - { - [JsonProperty("filter_properties")] - List FilterProperties { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/Query/Response/DatabaseQueryResponse.cs b/Src/Notion.Client/Api/Databases/Query/Response/DatabaseQueryResponse.cs deleted file mode 100644 index 5b7c9ec6..00000000 --- a/Src/Notion.Client/Api/Databases/Query/Response/DatabaseQueryResponse.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - // ReSharper disable once ClassNeverInstantiated.Global - public class DatabaseQueryResponse : PaginatedList - { - [JsonProperty("database")] - public Dictionary Database { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/DatabasesCreateParameters.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/DatabasesCreateParameters.cs deleted file mode 100644 index 9cb7086b..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/DatabasesCreateParameters.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class DatabasesCreateParameters : IDatabasesCreateBodyParameters, IDatabasesCreateQueryParameters - { - [JsonProperty("icon")] - public IPageIcon Icon { get; set; } - - [JsonProperty("cover")] - public FileObject Cover { get; set; } - - [JsonProperty("parent")] - public ParentPageInput Parent { get; set; } - - [JsonProperty("properties")] - public Dictionary Properties { get; set; } - - [JsonProperty("title")] - public List Title { get; set; } - - public bool? IsInline { get; set; } - - public List Description { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/IDatabasesCreateBodyParameters.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/IDatabasesCreateBodyParameters.cs deleted file mode 100644 index 7eb252f2..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/IDatabasesCreateBodyParameters.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public interface IDatabasesCreateBodyParameters - { - [JsonProperty("parent")] - ParentPageInput Parent { get; set; } - - [JsonProperty("properties")] - Dictionary Properties { get; set; } - - [JsonProperty("title")] - List Title { get; set; } - - [JsonProperty("is_inline")] - bool? IsInline { get; set; } - - [JsonProperty("description")] - List Description { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/IDatabasesCreateQueryParameters.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/IDatabasesCreateQueryParameters.cs deleted file mode 100644 index 309b5dba..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/IDatabasesCreateQueryParameters.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Notion.Client -{ - public interface IDatabasesCreateQueryParameters - { - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/CheckboxPropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/CheckboxPropertySchema.cs deleted file mode 100644 index fb955a3e..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/CheckboxPropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class CheckboxPropertySchema : IPropertySchema - { - [JsonProperty("checkbox")] - public Dictionary Checkbox { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/CreatedByPropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/CreatedByPropertySchema.cs deleted file mode 100644 index 1a2d8423..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/CreatedByPropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class CreatedByPropertySchema : IPropertySchema - { - [JsonProperty("created_by")] - public Dictionary CreatedBy { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/CreatedTimePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/CreatedTimePropertySchema.cs deleted file mode 100644 index 5e64ea2e..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/CreatedTimePropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class CreatedTimePropertySchema : IPropertySchema - { - [JsonProperty("created_time")] - public Dictionary CreatedTime { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/DatePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/DatePropertySchema.cs deleted file mode 100644 index 1dc37c20..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/DatePropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class DatePropertySchema : IPropertySchema - { - [JsonProperty("date")] - public Dictionary Date { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/EmailPropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/EmailPropertySchema.cs deleted file mode 100644 index 6a680c2b..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/EmailPropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class EmailPropertySchema : IPropertySchema - { - [JsonProperty("email")] - public Dictionary Email { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/FilePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/FilePropertySchema.cs deleted file mode 100644 index 4591a3fc..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/FilePropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class FilePropertySchema : IPropertySchema - { - [JsonProperty("files")] - public Dictionary Files { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/FormulaPropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/FormulaPropertySchema.cs deleted file mode 100644 index 97e7cb33..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/FormulaPropertySchema.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class FormulaPropertySchema : IPropertySchema - { - [JsonProperty("formula")] - public Formula Formula { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/IPropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/IPropertySchema.cs deleted file mode 100644 index f8b8ebf8..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/IPropertySchema.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Notion.Client -{ - public interface IPropertySchema - { - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/LastEditedByPropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/LastEditedByPropertySchema.cs deleted file mode 100644 index c5e797e7..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/LastEditedByPropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class LastEditedByPropertySchema : IPropertySchema - { - [JsonProperty("last_edited_by")] - public Dictionary LastEditedBy { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/LastEditedTimePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/LastEditedTimePropertySchema.cs deleted file mode 100644 index 47662e88..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/LastEditedTimePropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class LastEditedTimePropertySchema : IPropertySchema - { - [JsonProperty("last_edited_time")] - public Dictionary LastEditedTime { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/MultiSelectOptionSchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/MultiSelectOptionSchema.cs deleted file mode 100644 index a13d0930..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/MultiSelectOptionSchema.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace Notion.Client -{ - [SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")] - public class MultiSelectOptionSchema : SelectOptionSchema - { - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/MultiSelectPropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/MultiSelectPropertySchema.cs deleted file mode 100644 index 1417d3f5..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/MultiSelectPropertySchema.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class MultiSelectPropertySchema : IPropertySchema - { - [JsonProperty("multi_select")] - public OptionWrapper MultiSelect { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/NumberPropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/NumberPropertySchema.cs deleted file mode 100644 index dbb7fa28..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/NumberPropertySchema.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class NumberPropertySchema : IPropertySchema - { - [JsonProperty("number")] - public Number Number { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/PeoplePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/PeoplePropertySchema.cs deleted file mode 100644 index 5293746c..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/PeoplePropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class PeoplePropertySchema : IPropertySchema - { - [JsonProperty("people")] - public Dictionary People { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/RelationPropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/RelationPropertySchema.cs deleted file mode 100644 index 4c278ac2..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/RelationPropertySchema.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class RelationPropertySchema : IPropertySchema - { - [JsonProperty("relation")] - public RelationData Relation { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/RichTextPropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/RichTextPropertySchema.cs deleted file mode 100644 index f3c7e1e8..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/RichTextPropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class RichTextPropertySchema : IPropertySchema - { - [JsonProperty("rich_text")] - public Dictionary RichText { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/RollupConfigPropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/RollupConfigPropertySchema.cs deleted file mode 100644 index ac3c5220..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/RollupConfigPropertySchema.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class RollupConfigPropertySchema : IPropertySchema - { - [JsonProperty("relation_property_name")] - public string RelationPropertyName { get; set; } - - [JsonProperty("relation_property_id")] - public string RelationPropertyId { get; set; } - - [JsonProperty("rollup_property_name")] - public string RollupPropertyName { get; set; } - - [JsonProperty("rollup_property_id")] - public string RollupPropertyId { get; set; } - - [JsonProperty("function")] - public string Function { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/SelectOptionSchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/SelectOptionSchema.cs deleted file mode 100644 index b7fd8d82..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/SelectOptionSchema.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace Notion.Client -{ - public class SelectOptionSchema - { - [JsonProperty("name")] - public string Name { get; set; } - - [JsonProperty("color")] - [JsonConverter(typeof(StringEnumConverter))] - public Color? Color { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/SelectPropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/SelectPropertySchema.cs deleted file mode 100644 index 6e764bf3..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/SelectPropertySchema.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class SelectPropertySchema : IPropertySchema - { - [JsonProperty("select")] - public OptionWrapper Select { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/DatabasesUpdateParameters.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/DatabasesUpdateParameters.cs deleted file mode 100644 index 5147a6b0..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/DatabasesUpdateParameters.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections.Generic; - -namespace Notion.Client -{ - public class DatabasesUpdateParameters : IDatabasesUpdateBodyParameters - { - public Dictionary Properties { get; set; } - - public List Title { get; set; } - - public IPageIcon Icon { get; set; } - - public FileObject Cover { get; set; } - - public bool InTrash { get; set; } - - public bool? IsInline { get; set; } - - public List Description { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/DatabasesUpdateRequest.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/DatabasesUpdateRequest.cs new file mode 100644 index 00000000..3a3c5fae --- /dev/null +++ b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/DatabasesUpdateRequest.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DatabasesUpdateRequest : IDatabasesUpdatePathParameters, IDatabasesUpdateBodyParameters + { + public string DatabaseId { get; set; } + + public List Title { get; set; } + + public IPageIcon Icon { get; set; } + + public FileObject Cover { get; set; } + + public bool? InTrash { get; set; } + + public bool? IsInline { get; set; } + + public List Description { get; set; } + + public bool? IsLocked { get; set; } + + public IParentOfDatabaseRequest Parent { get; set; } + } + + public interface IDatabasesUpdatePathParameters + { + /// + /// The ID of the database to update. + /// + [JsonIgnore] + [JsonProperty("database_id")] + string DatabaseId { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/IDatabasesUpdateBodyParameters.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/IDatabasesUpdateBodyParameters.cs index f37df431..d4499bb5 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/IDatabasesUpdateBodyParameters.cs +++ b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/IDatabasesUpdateBodyParameters.cs @@ -5,8 +5,8 @@ namespace Notion.Client { public interface IDatabasesUpdateBodyParameters { - [JsonProperty("properties")] - Dictionary Properties { get; set; } + [JsonProperty("parent")] + IParentOfDatabaseRequest Parent { get; set; } [JsonProperty("title")] List Title { get; set; } @@ -18,12 +18,15 @@ public interface IDatabasesUpdateBodyParameters FileObject Cover { get; set; } [JsonProperty("in_trash")] - bool InTrash { get; set; } + bool? InTrash { get; set; } [JsonProperty("is_inline")] bool? IsInline { get; set; } [JsonProperty("description")] List Description { get; set; } + + [JsonProperty("is_locked")] + bool? IsLocked { get; set; } } } diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/FormulaUpdatePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/FormulaUpdatePropertySchema.cs deleted file mode 100644 index 40cc398a..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/FormulaUpdatePropertySchema.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class FormulaUpdatePropertySchema : UpdatePropertySchema - { - [JsonProperty("formula")] - public Formula Formula { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/IUpdatePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/IUpdatePropertySchema.cs deleted file mode 100644 index d0232472..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/IUpdatePropertySchema.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace Notion.Client -{ - public interface IUpdatePropertySchema - { - [JsonProperty("name")] - string Name { get; set; } - - [JsonProperty("type")] - [JsonConverter(typeof(StringEnumConverter))] - PropertyType? Type { get; set; } - } - - public abstract class UpdatePropertySchema : IUpdatePropertySchema - { - public string Name { get; set; } - - public PropertyType? Type { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/MultiSelectUpdatePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/MultiSelectUpdatePropertySchema.cs deleted file mode 100644 index 0b7b1c0c..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/MultiSelectUpdatePropertySchema.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class MultiSelectUpdatePropertySchema : UpdatePropertySchema - { - [JsonProperty("multi_select")] - public OptionWrapper MultiSelect { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/NumberUpdatePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/NumberUpdatePropertySchema.cs deleted file mode 100644 index 23f3ea3a..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/NumberUpdatePropertySchema.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class NumberUpdatePropertySchema : UpdatePropertySchema - { - [JsonProperty("number")] - public Number Number { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/PhoneNumberUpdatePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/PhoneNumberUpdatePropertySchema.cs deleted file mode 100644 index 7d01f506..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/PhoneNumberUpdatePropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class PhoneNumberUpdatePropertySchema : UpdatePropertySchema - { - [JsonProperty("phone_number")] - public Dictionary PhoneNumber { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RelationUpdatePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RelationUpdatePropertySchema.cs deleted file mode 100644 index 25f65cd4..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RelationUpdatePropertySchema.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class RelationUpdatePropertySchema : UpdatePropertySchema - { - [JsonProperty("relation")] - public RelationData Relation { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/SelectUpdatePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/SelectUpdatePropertySchema.cs deleted file mode 100644 index 678e452d..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/SelectUpdatePropertySchema.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class SelectUpdatePropertySchema : UpdatePropertySchema - { - [JsonProperty("select")] - public OptionWrapper Select { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/TitleUpdatePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/TitleUpdatePropertySchema.cs deleted file mode 100644 index 54052dfc..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/TitleUpdatePropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class TitleUpdatePropertySchema : UpdatePropertySchema - { - [JsonProperty("title")] - public Dictionary Title { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/URLUpdatePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/URLUpdatePropertySchema.cs deleted file mode 100644 index f56d6507..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/URLUpdatePropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class UrlUpdatePropertySchema : UpdatePropertySchema - { - [JsonProperty("url")] - public Dictionary Url { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Databases/Update/DatabasesClient.cs b/Src/Notion.Client/Api/Databases/Update/DatabasesClient.cs new file mode 100644 index 00000000..7f3d17e3 --- /dev/null +++ b/Src/Notion.Client/Api/Databases/Update/DatabasesClient.cs @@ -0,0 +1,33 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using static Notion.Client.ApiEndpoints; + +namespace Notion.Client +{ + public sealed partial class DatabasesClient + { + public async Task UpdateAsync(DatabasesUpdateRequest databasesUpdateRequest, CancellationToken cancellationToken = default) + { + IDatabasesUpdateBodyParameters body = databasesUpdateRequest; + + if (body == null) + { + throw new ArgumentNullException(nameof(databasesUpdateRequest)); + } + + if (string.IsNullOrEmpty(databasesUpdateRequest.DatabaseId)) + { + throw new ArgumentNullException(nameof(databasesUpdateRequest.DatabaseId)); + } + + var path = DatabasesApiUrls.Update(databasesUpdateRequest.DatabaseId); + + return await _client.PatchAsync( + path, + body, + cancellationToken: cancellationToken + ); + } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/DatabaseParentInput.cs b/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/DatabaseParentInput.cs deleted file mode 100644 index 285a63fa..00000000 --- a/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/DatabaseParentInput.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class DatabaseParentInput : IPageParentInput - { - [JsonProperty("database_id")] - public string DatabaseId { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/IPageParentInput.cs b/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/IPageParentInput.cs deleted file mode 100644 index f355b3ea..00000000 --- a/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/IPageParentInput.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Notion.Client -{ - public interface IPageParentInput - { - } -} diff --git a/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/IPagesCreateBodyParameters.cs b/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/IPagesCreateBodyParameters.cs index 9b9f0631..c59dc8d5 100644 --- a/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/IPagesCreateBodyParameters.cs +++ b/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/IPagesCreateBodyParameters.cs @@ -6,7 +6,7 @@ namespace Notion.Client public interface IPagesCreateBodyParameters { [JsonProperty("parent")] - IPageParentInput Parent { get; set; } + IParentOfPageRequest Parent { get; set; } [JsonProperty("properties")] IDictionary Properties { get; set; } diff --git a/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/PagesCreateParameters.cs b/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/PagesCreateParameters.cs index 08572811..c41722c6 100644 --- a/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/PagesCreateParameters.cs +++ b/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/PagesCreateParameters.cs @@ -1,10 +1,11 @@ using System.Collections.Generic; +using Newtonsoft.Json; namespace Notion.Client { public class PagesCreateParameters : IPagesCreateBodyParameters, IPagesCreateQueryParameters { - public IPageParentInput Parent { get; set; } + public IParentOfPageRequest Parent { get; set; } public IDictionary Properties { get; set; } diff --git a/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/PagesCreateParametersBuilder.cs b/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/PagesCreateParametersBuilder.cs index ed85117d..46980175 100644 --- a/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/PagesCreateParametersBuilder.cs +++ b/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/PagesCreateParametersBuilder.cs @@ -10,13 +10,13 @@ public class PagesCreateParametersBuilder private readonly Dictionary _properties = new(); private FileObject _cover; private IPageIcon _icon; - private IPageParentInput _parent; + private IParentOfPageRequest _parent; private PagesCreateParametersBuilder() { } - public static PagesCreateParametersBuilder Create(IPageParentInput parent) + public static PagesCreateParametersBuilder Create(IParentOfPageRequest parent) { return new PagesCreateParametersBuilder { _parent = parent }; } diff --git a/Src/Notion.Client/Api/Search/ISearchClient.cs b/Src/Notion.Client/Api/Search/ISearchClient.cs index accee1e1..552d61a3 100644 --- a/Src/Notion.Client/Api/Search/ISearchClient.cs +++ b/Src/Notion.Client/Api/Search/ISearchClient.cs @@ -1,20 +1,21 @@ -using System.Diagnostics.CodeAnalysis; -using System.Threading; +using System.Threading; using System.Threading.Tasks; namespace Notion.Client { - [SuppressMessage("ReSharper", "UnusedMemberInSuper.Global")] public interface ISearchClient { /// - /// Searches all original pages, databases, and child pages/databases that are shared with the integration. - /// It will not return linked databases, since these duplicate their source databases. + /// Searches all parent or child pages and data_sources that have been shared with an integration. + /// + /// Returns all pages or data_sources , excluding duplicated linked databases, that have titles that include the query param. + /// If no query param is provided, then the response contains all pages or data_sources that have been shared with the integration. + /// The results adhere to any limitations related to an integration’s capabilities. /// /// Search filters and body parameters /// /// - /// + /// /// Task SearchAsync( SearchRequest request, diff --git a/Src/Notion.Client/Api/Search/Request/ISearchBodyParameters.cs b/Src/Notion.Client/Api/Search/Request/ISearchBodyParameters.cs index 18965000..bedc813b 100644 --- a/Src/Notion.Client/Api/Search/Request/ISearchBodyParameters.cs +++ b/Src/Notion.Client/Api/Search/Request/ISearchBodyParameters.cs @@ -4,12 +4,24 @@ namespace Notion.Client { public interface ISearchBodyParameters : IPaginationParameters { + /// + /// The text that the API compares page and data_source titles against. + /// [JsonProperty("query")] string Query { get; set; } + /// + /// A set of criteria, direction and timestamp keys, that orders the results. + /// The only supported timestamp value is "last_edited_time". Supported direction values are "ascending" and "descending". + /// If sort is not provided, then the most recently edited results are returned first. + /// [JsonProperty("sort")] SearchSort Sort { get; set; } + /// + /// A set of criteria, value and property keys, that limits the results to either only pages or only data_sources. + /// Possible value values are "page" or "data_source". The only supported property value is "object". + /// [JsonProperty("filter")] SearchFilter Filter { get; set; } } diff --git a/Src/Notion.Client/Api/Search/Request/SearchFilter.cs b/Src/Notion.Client/Api/Search/Request/SearchFilter.cs index b36ca873..dbd5cf5f 100644 --- a/Src/Notion.Client/Api/Search/Request/SearchFilter.cs +++ b/Src/Notion.Client/Api/Search/Request/SearchFilter.cs @@ -1,11 +1,8 @@ -using System.Diagnostics.CodeAnalysis; -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Converters; namespace Notion.Client { - [SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")] - [SuppressMessage("ReSharper", "UnusedMember.Global")] public class SearchFilter { [JsonConverter(typeof(StringEnumConverter))] diff --git a/Src/Notion.Client/Api/Search/Request/SearchObjectType.cs b/Src/Notion.Client/Api/Search/Request/SearchObjectType.cs index e3e6181b..ee6e053c 100644 --- a/Src/Notion.Client/Api/Search/Request/SearchObjectType.cs +++ b/Src/Notion.Client/Api/Search/Request/SearchObjectType.cs @@ -1,15 +1,13 @@ -using System.Diagnostics.CodeAnalysis; -using System.Runtime.Serialization; +using System.Runtime.Serialization; namespace Notion.Client { - [SuppressMessage("ReSharper", "UnusedMember.Global")] public enum SearchObjectType { [EnumMember(Value = "page")] Page, - [EnumMember(Value = "database")] - Database + [EnumMember(Value = "data_source")] + DataSource } } diff --git a/Src/Notion.Client/Api/Search/Request/SearchSort.cs b/Src/Notion.Client/Api/Search/Request/SearchSort.cs index fed3f205..fa0cbd63 100644 --- a/Src/Notion.Client/Api/Search/Request/SearchSort.cs +++ b/Src/Notion.Client/Api/Search/Request/SearchSort.cs @@ -5,10 +5,16 @@ namespace Notion.Client { public class SearchSort { + /// + /// Supported direction values are "ascending" and "descending". + /// [JsonProperty("direction")] [JsonConverter(typeof(StringEnumConverter))] public SearchDirection Direction { get; set; } + /// + /// The only supported timestamp value is "last_edited_time". + /// [JsonProperty("timestamp")] public string Timestamp { get; set; } } diff --git a/Src/Notion.Client/Api/Search/Response/ISearchResponseObject.cs b/Src/Notion.Client/Api/Search/Response/ISearchResponseObject.cs new file mode 100644 index 00000000..8907e5a3 --- /dev/null +++ b/Src/Notion.Client/Api/Search/Response/ISearchResponseObject.cs @@ -0,0 +1,12 @@ +using JsonSubTypes; +using Newtonsoft.Json; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "object")] + [JsonSubtypes.KnownSubType(typeof(Page), ObjectType.Page)] + [JsonSubtypes.KnownSubType(typeof(DataSourceResponse), ObjectType.DataSource)] + public interface ISearchResponseObject : IObject + { + } +} diff --git a/Src/Notion.Client/Api/Search/Response/SearchResponse.cs b/Src/Notion.Client/Api/Search/Response/SearchResponse.cs index 2be0e2f1..603c5d21 100644 --- a/Src/Notion.Client/Api/Search/Response/SearchResponse.cs +++ b/Src/Notion.Client/Api/Search/Response/SearchResponse.cs @@ -3,9 +3,12 @@ namespace Notion.Client { - public class SearchResponse : PaginatedList + public class SearchResponse : PaginatedList { [JsonProperty("page_or_database")] public Dictionary PageOrDatabase { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } } } diff --git a/Src/Notion.Client/Constants.cs b/Src/Notion.Client/Constants.cs index 779bcb47..df7dd906 100644 --- a/Src/Notion.Client/Constants.cs +++ b/Src/Notion.Client/Constants.cs @@ -7,6 +7,6 @@ namespace Notion.Client internal static class Constants { internal const string BaseUrl = "https://api.notion.com/"; - internal const string DefaultNotionVersion = "2022-06-28"; + internal const string DefaultNotionVersion = "2025-09-03"; } } diff --git a/Src/Notion.Client/Models/Blocks/LinkToPageBlock.cs b/Src/Notion.Client/Models/Blocks/LinkToPageBlock.cs index ad688ca2..bfba462d 100644 --- a/Src/Notion.Client/Models/Blocks/LinkToPageBlock.cs +++ b/Src/Notion.Client/Models/Blocks/LinkToPageBlock.cs @@ -5,7 +5,7 @@ namespace Notion.Client public class LinkToPageBlock : Block, IColumnChildrenBlock, INonColumnBlock { [JsonProperty("link_to_page")] - public IPageParent LinkToPage { get; set; } + public ILinkToPage LinkToPage { get; set; } public override BlockType Type => BlockType.LinkToPage; } diff --git a/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/ILinkToPage.cs b/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/ILinkToPage.cs new file mode 100644 index 00000000..04b24273 --- /dev/null +++ b/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/ILinkToPage.cs @@ -0,0 +1,15 @@ +using JsonSubTypes; +using Newtonsoft.Json; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "type")] + [JsonSubtypes.KnownSubType(typeof(LinkPageToPage), "page_id")] + [JsonSubtypes.KnownSubType(typeof(LinkDatabaseToPage), "database_id")] + [JsonSubtypes.KnownSubType(typeof(LinkCommentToPage), "comment_id")] + public interface ILinkToPage + { + [JsonProperty("type")] + string Type { get; } + } +} diff --git a/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/LinkCommentToPage.cs b/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/LinkCommentToPage.cs new file mode 100644 index 00000000..c3f5e30a --- /dev/null +++ b/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/LinkCommentToPage.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LinkCommentToPage : ILinkToPage + { + [JsonProperty("type")] + public string Type => "comment_id"; + + [JsonProperty("comment_id")] + public string CommentId { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/LinkDatabaseToPage.cs b/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/LinkDatabaseToPage.cs new file mode 100644 index 00000000..6985e4f8 --- /dev/null +++ b/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/LinkDatabaseToPage.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LinkDatabaseToPage : ILinkToPage + { + [JsonProperty("type")] + public string Type => "database_id"; + + [JsonProperty("database_id")] + public string DatabaseId { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/LinkPageToPage.cs b/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/LinkPageToPage.cs new file mode 100644 index 00000000..3fc0f794 --- /dev/null +++ b/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/LinkPageToPage.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LinkPageToPage : ILinkToPage + { + [JsonProperty("type")] + public string Type => "page_id"; + + [JsonProperty("page_id")] + public string PageId { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlockRequest.cs b/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/LinkToPageBlockRequest.cs similarity index 84% rename from Src/Notion.Client/Models/Blocks/Request/LinkToPageBlockRequest.cs rename to Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/LinkToPageBlockRequest.cs index ec182df5..d80a3f65 100644 --- a/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlockRequest.cs +++ b/Src/Notion.Client/Models/Blocks/Request/LinkToPageBlock/LinkToPageBlockRequest.cs @@ -5,7 +5,7 @@ namespace Notion.Client public class LinkToPageBlockRequest : BlockObjectRequest, IColumnChildrenBlockRequest, INonColumnBlockRequest { [JsonProperty("link_to_page")] - public IPageParent LinkToPage { get; set; } + public ILinkToPage LinkToPage { get; set; } public override BlockType Type => BlockType.LinkToPage; } diff --git a/Src/Notion.Client/Models/Database/DataSourceReferenceResponse.cs b/Src/Notion.Client/Models/Database/DataSourceReferenceResponse.cs new file mode 100644 index 00000000..c6871641 --- /dev/null +++ b/Src/Notion.Client/Models/Database/DataSourceReferenceResponse.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DataSourceReferenceResponse + { + [JsonProperty("id")] + public string DataSourceId { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Database/Database.cs b/Src/Notion.Client/Models/Database/Database.cs index be288ea0..b30d308e 100644 --- a/Src/Notion.Client/Models/Database/Database.cs +++ b/Src/Notion.Client/Models/Database/Database.cs @@ -4,41 +4,38 @@ namespace Notion.Client { - public class Database : IObject, IObjectModificationData, IWikiDatabase + public class Database : IObject, IObjectModificationData { - [JsonProperty("title")] - public List Title { get; set; } - - [JsonProperty("properties")] - public Dictionary Properties { get; set; } - - [JsonProperty("parent")] - public IDatabaseParent Parent { get; set; } + public ObjectType Object => ObjectType.Database; - [JsonProperty("icon")] - public IPageIcon Icon { get; set; } + public string Id { get; set; } - [JsonProperty("cover")] - public FileObject Cover { get; set; } + /// + /// The title of the database. + /// + [JsonProperty("title")] + public List Title { get; set; } /// - /// The URL of the Notion database. + /// The description of the database. /// - [JsonProperty("url")] - public string Url { get; set; } + [JsonProperty("description")] + public IEnumerable Description { get; set; } - [JsonProperty("in_trash")] - public bool InTrash { get; set; } + /// + /// Parent of the database. + /// + [JsonProperty("parent")] + public IDatabaseParent Parent { get; set; } [JsonProperty("is_inline")] public bool IsInline { get; set; } - [JsonProperty("description")] - public IEnumerable Description { get; set; } - - public ObjectType Object => ObjectType.Database; + [JsonProperty("in_trash")] + public bool InTrash { get; set; } - public string Id { get; set; } + [JsonProperty("is_locked")] + public bool IsLocked { get; set; } [JsonProperty("created_time")] public DateTime CreatedTime { get; set; } @@ -51,7 +48,25 @@ public class Database : IObject, IObjectModificationData, IWikiDatabase public PartialUser LastEditedBy { get; set; } /// - /// The public page URL if the page has been published to the web. Otherwise, null. + /// The data sources associated with the database. + /// + [JsonProperty("data_sources")] + public IEnumerable DataSources { get; set; } + + [JsonProperty("icon")] + public IPageIconResponse Icon { get; set; } + + [JsonProperty("cover")] + public FileObject Cover { get; set; } + + /// + /// The URL of the Notion database. + /// + [JsonProperty("url")] + public string Url { get; set; } + + /// + /// The public page URL if the page has been published to the web. Otherwise, null. /// [JsonProperty("public_url")] public string PublicUrl { get; set; } diff --git a/Src/Notion.Client/Models/Database/IWikiDatabase.cs b/Src/Notion.Client/Models/Database/IWikiDatabase.cs deleted file mode 100644 index 59969175..00000000 --- a/Src/Notion.Client/Models/Database/IWikiDatabase.cs +++ /dev/null @@ -1,12 +0,0 @@ -using JsonSubTypes; -using Newtonsoft.Json; - -namespace Notion.Client -{ - [JsonConverter(typeof(JsonSubtypes), "object")] - [JsonSubtypes.KnownSubTypeAttribute(typeof(Page), ObjectType.Page)] - [JsonSubtypes.KnownSubTypeAttribute(typeof(Database), ObjectType.Database)] - public interface IWikiDatabase : IObject - { - } -} diff --git a/Src/Notion.Client/Models/Filters/CreatedByFilter.cs b/Src/Notion.Client/Models/Filters/CreatedByFilter.cs new file mode 100644 index 00000000..4859e36f --- /dev/null +++ b/Src/Notion.Client/Models/Filters/CreatedByFilter.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CreatedByFilter : SinglePropertyFilter + { + public CreatedByFilter( + string propertyName, + PeopleFilter.Condition createdBy) + { + Property = propertyName; + CreatedBy = createdBy; + } + + /// + /// Gets or sets the created by condition. + /// + [JsonProperty("created_by")] + public PeopleFilter.Condition CreatedBy { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Filters/CreatedTimeFilter.cs b/Src/Notion.Client/Models/Filters/CreatedTimeFilter.cs new file mode 100644 index 00000000..ae5223a2 --- /dev/null +++ b/Src/Notion.Client/Models/Filters/CreatedTimeFilter.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CreatedTimeFilter : SinglePropertyFilter + { + public CreatedTimeFilter( + string propertyName, + DateFilter.Condition createdTime) + { + Property = propertyName; + CreatedTime = createdTime; + } + + /// + /// Gets or sets the created time condition. + /// + [JsonProperty("created_time")] + public DateFilter.Condition CreatedTime { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Filters/LastEditedByFilter.cs b/Src/Notion.Client/Models/Filters/LastEditedByFilter.cs new file mode 100644 index 00000000..0e2f4d52 --- /dev/null +++ b/Src/Notion.Client/Models/Filters/LastEditedByFilter.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LastEditedByFilter : SinglePropertyFilter + { + public LastEditedByFilter( + string propertyName, + PeopleFilter.Condition lastEditedBy) + { + Property = propertyName; + LastEditedBy = lastEditedBy; + } + + /// + /// Gets or sets the last edited by condition. + /// + [JsonProperty("last_edited_by")] + public PeopleFilter.Condition LastEditedBy { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Filters/LastEditedTimeFilter.cs b/Src/Notion.Client/Models/Filters/LastEditedTimeFilter.cs new file mode 100644 index 00000000..1cdba4a5 --- /dev/null +++ b/Src/Notion.Client/Models/Filters/LastEditedTimeFilter.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LastEditedTimeFilter : SinglePropertyFilter + { + public LastEditedTimeFilter( + string propertyName, + DateFilter.Condition lastEditedTime) + { + Property = propertyName; + LastEditedTime = lastEditedTime; + } + + /// + /// Gets or sets the last edited time condition. + /// + [JsonProperty("last_edited_time")] + public DateFilter.Condition LastEditedTime { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Filters/UniqueIdFilter.cs b/Src/Notion.Client/Models/Filters/UniqueIdFilter.cs new file mode 100644 index 00000000..bf3ebb10 --- /dev/null +++ b/Src/Notion.Client/Models/Filters/UniqueIdFilter.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class UniqueIdFilter : SinglePropertyFilter + { + public UniqueIdFilter( + string propertyName, + NumberFilter.Condition uniqueId) + { + Property = propertyName; + UniqueId = uniqueId; + } + + /// + /// Gets or sets the unique id condition. + /// + [JsonProperty("unique_id")] + public NumberFilter.Condition UniqueId { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Filters/VerificationPropertyStatusFilter.cs b/Src/Notion.Client/Models/Filters/VerificationPropertyStatusFilter.cs new file mode 100644 index 00000000..cccca843 --- /dev/null +++ b/Src/Notion.Client/Models/Filters/VerificationPropertyStatusFilter.cs @@ -0,0 +1,35 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class VerificationPropertyStatusFilter : SinglePropertyFilter + { + public VerificationPropertyStatusFilter( + string propertyName, + Condition verificationStatus) + { + Property = propertyName; + VerificationStatus = verificationStatus; + } + + /// + /// Gets or sets the verification status condition. + /// + [JsonProperty("verification_status")] + public Condition VerificationStatus { get; set; } + + public class Condition + { + public Condition(VerificationStatus status) + { + Status = status; + } + + /// + /// Gets or sets the verification status. + /// + [JsonProperty("status")] + public VerificationStatus Status { get; set; } + } + } +} diff --git a/Src/Notion.Client/Models/Filters/VerificationStatus.cs b/Src/Notion.Client/Models/Filters/VerificationStatus.cs new file mode 100644 index 00000000..9dc86f70 --- /dev/null +++ b/Src/Notion.Client/Models/Filters/VerificationStatus.cs @@ -0,0 +1,19 @@ +using System.Runtime.Serialization; + +namespace Notion.Client +{ + /// + /// Verification status values. + /// + public enum VerificationStatus + { + [EnumMember(Value = "verified")] + Verified, + + [EnumMember(Value = "expired")] + Expired, + + [EnumMember(Value = "none")] + None + } +} diff --git a/Src/Notion.Client/Models/ObjectType.cs b/Src/Notion.Client/Models/ObjectType.cs index 61188a31..f3db8cf9 100644 --- a/Src/Notion.Client/Models/ObjectType.cs +++ b/Src/Notion.Client/Models/ObjectType.cs @@ -21,5 +21,8 @@ public enum ObjectType [EnumMember(Value = "file_upload")] FileUpload, + + [EnumMember(Value = "data_source")] + DataSource, } } diff --git a/Src/Notion.Client/Models/Page/IPageParent.cs b/Src/Notion.Client/Models/Page/IPageParent.cs index b9111d91..f2f4499f 100644 --- a/Src/Notion.Client/Models/Page/IPageParent.cs +++ b/Src/Notion.Client/Models/Page/IPageParent.cs @@ -8,6 +8,7 @@ namespace Notion.Client [JsonSubtypes.KnownSubTypeAttribute(typeof(PageParent), ParentType.PageId)] [JsonSubtypes.KnownSubTypeAttribute(typeof(WorkspaceParent), ParentType.Workspace)] [JsonSubtypes.KnownSubTypeAttribute(typeof(BlockParent), ParentType.BlockId)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(DataSourceParent), ParentType.DataSourceId)] public interface IPageParent : IParent { } diff --git a/Src/Notion.Client/Models/Page/Page.cs b/Src/Notion.Client/Models/Page/Page.cs index fe4eb0de..53e532f9 100644 --- a/Src/Notion.Client/Models/Page/Page.cs +++ b/Src/Notion.Client/Models/Page/Page.cs @@ -4,7 +4,7 @@ namespace Notion.Client { - public class Page : IObject, IObjectModificationData, IWikiDatabase + public class Page : IObject, IObjectModificationData, IQueryDataSourceResponseObject, ISearchResponseObject { /// /// The parent of this page. Can be a database, page, or workspace. diff --git a/Src/Notion.Client/Models/Page/PagePropertyOnId.cs b/Src/Notion.Client/Models/Page/PagePropertyOnId.cs deleted file mode 100644 index 00005986..00000000 --- a/Src/Notion.Client/Models/Page/PagePropertyOnId.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class PagePropertyOnId - { - [JsonProperty("id")] - public string Id { get; set; } - } -} diff --git a/Src/Notion.Client/Models/PaginatedList.cs b/Src/Notion.Client/Models/PaginatedList.cs index d0b1107f..f658b541 100644 --- a/Src/Notion.Client/Models/PaginatedList.cs +++ b/Src/Notion.Client/Models/PaginatedList.cs @@ -5,9 +5,16 @@ namespace Notion.Client { public interface IPaginationParameters { + /// + /// If supplied, this endpoint will return a page of results starting after the cursor provided. + /// If not supplied, this endpoint will return the first page of results. + /// [JsonProperty("start_cursor")] string StartCursor { get; set; } + /// + /// The number of items from the full list desired in the response. + /// [JsonProperty("page_size")] int? PageSize { get; set; } } diff --git a/Src/Notion.Client/Models/Parents/DataSourceParent.cs b/Src/Notion.Client/Models/Parents/DataSourceParent.cs new file mode 100644 index 00000000..3571f4d4 --- /dev/null +++ b/Src/Notion.Client/Models/Parents/DataSourceParent.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DataSourceParent : IPageParent + { + public ParentType Type { get; set; } + + [JsonProperty("data_source_id")] + public string DataSourceId { get; set; } + } +} \ No newline at end of file diff --git a/Src/Notion.Client/Models/Parents/ParentType.cs b/Src/Notion.Client/Models/Parents/ParentType.cs index 347414f9..fa037ab5 100644 --- a/Src/Notion.Client/Models/Parents/ParentType.cs +++ b/Src/Notion.Client/Models/Parents/ParentType.cs @@ -19,6 +19,9 @@ public enum ParentType Workspace, [EnumMember(Value = "block_id")] - BlockId + BlockId, + + [EnumMember(Value = "data_source_id")] + DataSourceId } } diff --git a/Src/Notion.Client/Models/PropertyValue/DateCustomConverter.cs b/Src/Notion.Client/Models/PropertyValue/DateCustomConverter.cs index 37b84bc5..2cd62779 100644 --- a/Src/Notion.Client/Models/PropertyValue/DateCustomConverter.cs +++ b/Src/Notion.Client/Models/PropertyValue/DateCustomConverter.cs @@ -21,10 +21,10 @@ public override Date ReadJson(JsonReader reader, Type objectType, Date existingV var date = new Date { - Start = ParseDateTime(jsonObject.Start, out bool includeTime), - End = ParseDateTime(jsonObject.End, out _), + Start = ParseDateTime(jsonObject.Start, out bool startIncludeTime), + End = ParseDateTime(jsonObject.End, out bool endIncludeTime), TimeZone = jsonObject.TimeZone, - IncludeTime = includeTime, + IncludeTime = startIncludeTime || endIncludeTime, }; return date; @@ -45,14 +45,14 @@ public override void WriteJson(JsonWriter writer, Date value, JsonSerializer ser { string startFormat = value.IncludeTime ? DateTimeFormat : DateFormat; writer.WritePropertyName("start"); - writer.WriteValue(value.Start.Value.ToString(startFormat, CultureInfo.InvariantCulture)); + writer.WriteValue(value.Start.Value.ToUniversalTime().ToString(startFormat, CultureInfo.InvariantCulture)); } if (value.End.HasValue) { string endFormat = value.IncludeTime ? DateTimeFormat : DateFormat; writer.WritePropertyName("end"); - writer.WriteValue(value.End.Value.ToString(endFormat, CultureInfo.InvariantCulture)); + writer.WriteValue(value.End.Value.ToUniversalTime().ToString(endFormat, CultureInfo.InvariantCulture)); } if (!string.IsNullOrEmpty(value.TimeZone)) @@ -64,7 +64,7 @@ public override void WriteJson(JsonWriter writer, Date value, JsonSerializer ser writer.WriteEndObject(); } - private static DateTime? ParseDateTime(string dateTimeString, out bool includeTime) + private static DateTimeOffset? ParseDateTime(string dateTimeString, out bool includeTime) { includeTime = false; @@ -75,7 +75,7 @@ public override void WriteJson(JsonWriter writer, Date value, JsonSerializer ser includeTime = dateTimeString.Contains("T") || dateTimeString.Contains(" "); - return DateTimeOffset.Parse(dateTimeString, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).UtcDateTime; + return DateTimeOffset.Parse(dateTimeString, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); } } } diff --git a/Src/Notion.Client/Models/Request/Parents/DataSourceParentRequest.cs b/Src/Notion.Client/Models/Request/Parents/DataSourceParentRequest.cs new file mode 100644 index 00000000..e97c3e10 --- /dev/null +++ b/Src/Notion.Client/Models/Request/Parents/DataSourceParentRequest.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DataSourceParentRequest : IParentOfPageRequest + { + [JsonProperty("type")] + public string Type => "data_source_id"; + + [JsonProperty("data_source_id")] + public string DataSourceId { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Request/Parents/DatabaseParentRequest.cs b/Src/Notion.Client/Models/Request/Parents/DatabaseParentRequest.cs new file mode 100644 index 00000000..4903f762 --- /dev/null +++ b/Src/Notion.Client/Models/Request/Parents/DatabaseParentRequest.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DatabaseParentRequest : IParentOfDataSourceRequest, IParentOfPageRequest + { + [JsonProperty("type")] + public string Type => "database_id"; + + [JsonProperty("database_id")] + public string DatabaseId { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Request/Parents/IParentOfDatabaseRequest.cs b/Src/Notion.Client/Models/Request/Parents/IParentOfDatabaseRequest.cs new file mode 100644 index 00000000..1fe47961 --- /dev/null +++ b/Src/Notion.Client/Models/Request/Parents/IParentOfDatabaseRequest.cs @@ -0,0 +1,10 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IParentOfPageRequest + { + [JsonProperty("type")] + string Type { get; } + } +} diff --git a/Src/Notion.Client/Models/Request/Parents/PageParentRequest.cs b/Src/Notion.Client/Models/Request/Parents/PageParentRequest.cs new file mode 100644 index 00000000..49c2a1f3 --- /dev/null +++ b/Src/Notion.Client/Models/Request/Parents/PageParentRequest.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class PageParentRequest : IParentOfPageRequest + { + [JsonProperty("type")] + public string Type => "page_id"; + + [JsonProperty("page_id")] + public string PageId { get; set; } + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Request/Parents/WorkspaceParentRequest.cs b/Src/Notion.Client/Models/Request/Parents/WorkspaceParentRequest.cs new file mode 100644 index 00000000..44e92fc5 --- /dev/null +++ b/Src/Notion.Client/Models/Request/Parents/WorkspaceParentRequest.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class WorkspaceParentRequest : IParentOfPageRequest + { + [JsonProperty("type")] + public string Type => "workspace"; + + [JsonProperty("workspace")] + public bool Workspace => true; + + /// + /// Additional data for future compatibility + /// If you encounter properties that are not yet supported, please open an issue on GitHub. + /// + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/NotionClient.cs b/Src/Notion.Client/NotionClient.cs index 6f21ccf7..6b0c705a 100644 --- a/Src/Notion.Client/NotionClient.cs +++ b/Src/Notion.Client/NotionClient.cs @@ -18,8 +18,11 @@ public interface INotionClient IBlocksClient Blocks { get; } ICommentsClient Comments { get; } + IFileUploadsClient FileUploads { get; } + IDataSourcesClient DataSources { get; } + IRestClient RestClient { get; } } @@ -34,7 +37,8 @@ public NotionClient( ICommentsClient comments, IBlocksClient blocks, IAuthenticationClient authenticationClient, - IFileUploadsClient fileUploadsClient) + IFileUploadsClient fileUploadsClient, + IDataSourcesClient dataSourcesClient) { RestClient = restClient; Users = users; @@ -45,6 +49,7 @@ public NotionClient( Blocks = blocks; AuthenticationClient = authenticationClient; FileUploads = fileUploadsClient; + DataSources = dataSourcesClient; } public IAuthenticationClient AuthenticationClient { get; } @@ -63,6 +68,8 @@ public NotionClient( public IFileUploadsClient FileUploads { get; } + public IDataSourcesClient DataSources { get; } + public IRestClient RestClient { get; } } } diff --git a/Src/Notion.Client/NotionClientFactory.cs b/Src/Notion.Client/NotionClientFactory.cs index 2fc9acac..d2720082 100644 --- a/Src/Notion.Client/NotionClientFactory.cs +++ b/Src/Notion.Client/NotionClientFactory.cs @@ -16,6 +16,7 @@ public static NotionClient Create(ClientOptions options) , new BlocksClient(restClient) , new AuthenticationClient(restClient) , new FileUploadsClient(restClient) + , new DataSourcesClient(restClient) ); } } diff --git a/Test/Notion.IntegrationTests/BlocksClientTests.cs b/Test/Notion.IntegrationTests/BlocksClientTests.cs index 5f1ca25b..81d6e0b6 100644 --- a/Test/Notion.IntegrationTests/BlocksClientTests.cs +++ b/Test/Notion.IntegrationTests/BlocksClientTests.cs @@ -16,7 +16,7 @@ public async Task InitializeAsync() { _page = await Client.Pages.CreateAsync( PagesCreateParametersBuilder.Create( - new ParentPageInput { PageId = ParentPageId } + new PageParentRequest { PageId = ParentPageId } ).Build() ); } @@ -338,22 +338,21 @@ private static IEnumerable BlockData() { new LinkToPageBlockRequest { - LinkToPage = new PageParent + LinkToPage = new LinkPageToPage { - Type = ParentType.PageId, PageId = "533578e3edf14c0a91a9da6b09bac3ee" } }, new LinkToPageUpdateBlock { - LinkToPage = new ParentPageInput { PageId = "3c357473a28149a488c010d2b245a589" } + LinkToPage = new LinkPageToPage { PageId = "3c357473a28149a488c010d2b245a589" } }, new Action((block, _) => { Assert.NotNull(block); var linkToPageBlock = Assert.IsType(block); - var pageParent = Assert.IsType(linkToPageBlock.LinkToPage); + var pageParent = Assert.IsType(linkToPageBlock.LinkToPage); // TODO: Currently the api doesn't allow to update the link_to_page block type // This will change to updated ID once api start to support diff --git a/Test/Notion.IntegrationTests/CommentsClientTests.cs b/Test/Notion.IntegrationTests/CommentsClientTests.cs index fac1fce1..0a8ff417 100644 --- a/Test/Notion.IntegrationTests/CommentsClientTests.cs +++ b/Test/Notion.IntegrationTests/CommentsClientTests.cs @@ -14,7 +14,7 @@ public async Task InitializeAsync() { _page = await Client.Pages.CreateAsync( PagesCreateParametersBuilder.Create( - new ParentPageInput { PageId = ParentPageId } + new PageParentRequest { PageId = ParentPageId } ).Build() ); } diff --git a/Test/Notion.IntegrationTests/DataSourcesClientTests.cs b/Test/Notion.IntegrationTests/DataSourcesClientTests.cs new file mode 100644 index 00000000..b1696bcf --- /dev/null +++ b/Test/Notion.IntegrationTests/DataSourcesClientTests.cs @@ -0,0 +1,314 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using FluentAssertions; +using Notion.Client; +using Xunit; + +namespace Notion.IntegrationTests +{ + public class DataSourcesClientTests : IntegrationTestBase, IAsyncLifetime + { + private Page _page = null!; + + public async Task InitializeAsync() + { + _page = await Client.Pages.CreateAsync( + PagesCreateParametersBuilder.Create( + new PageParentRequest { PageId = ParentPageId } + ).Build() + ); + } + + public async Task DisposeAsync() + { + await Client.Pages.UpdateAsync(_page.Id, new PagesUpdateParameters { InTrash = true }); + } + + [Fact] + public async Task CreateDataSource_ShouldReturnSuccess() + { + // Arrange + var database = await CreateDatabaseWithAPageAsync("Test Data Source DB"); + var request = new CreateDataSourceRequest + { + Parent = new DatabaseParentRequest + { + DatabaseId = database.Id + }, + Properties = new Dictionary + { + { + "Name", + new TitlePropertyConfigurationRequest { + Description = "The name of the data source", + Title = new Dictionary() + } + } + }, + Title = new List + { + new RichTextTextInput { Text = new Text { Content = "Test Data Source" } } + } + }; + + // Act + var response = await Client.DataSources.CreateAsync(request); + + // Assert + Assert.NotNull(response); + Assert.Equal("Test Data Source", response.Title.OfType().First().Text.Content); + Assert.Single(response.Properties); + Assert.True(response.Properties.ContainsKey("Name")); + Assert.Equal("The name of the data source", response.Properties["Name"].Description); + } + + // add tests for update + [Fact] + public async Task UpdateDataSource_ShouldReturnSuccess() + { + // Arrange + var database = await CreateDatabaseWithAPageAsync("Test Data Source DB"); + var createRequest = new CreateDataSourceRequest + { + Parent = new DatabaseParentRequest + { + DatabaseId = database.Id + }, + Properties = new Dictionary + { + { + "Name", + new TitlePropertyConfigurationRequest { + Description = "The name of the data source", + Title = new Dictionary() + } + }, + { + "Status", + new SelectPropertyConfigurationRequest { + Description = "The status of the data source", + Select = new SelectPropertyConfigurationRequest.SelectOptions + { + Options = new List + { + new() { Name = "Open", Color = "green" }, + new() { Name = "Closed", Color = "red" } + } + } + } + } + }, + Title = new List + { + new RichTextTextInput { Text = new Text { Content = "Initial Data Source" } } + } + }; + + var createResponse = await Client.DataSources.CreateAsync(createRequest); + + var updateRequest = new UpdateDataSourceRequest + { + DataSourceId = createResponse.Id, + Title = new List + { + new RichTextTextInput { Text = new Text { Content = "Updated Data Source" } } + }, + Properties = new Dictionary + { + { + "Status", + new UpdatePropertyConfigurationRequest + { + Name = "Item Status", + PropertyRequest = new SelectPropertyConfigurationRequest + { + Description = "Updated status of the data source", + Select = new SelectPropertyConfigurationRequest.SelectOptions + { + Options = new List + { + new() { Name = "In Progress", Color = "yellow" }, + new() { Name = "Completed", Color = "blue" } + } + } + } + } + } + } + }; + + // Act + var updateResponse = await Client.DataSources.UpdateAsync(updateRequest); + + // Assert + Assert.NotNull(updateResponse); + Assert.Equal("Updated Data Source", updateResponse.Title.OfType().First().Text.Content); + Assert.Equal(2, updateResponse.Properties.Count); + Assert.True(updateResponse.Properties.ContainsKey("Item Status")); + Assert.True(updateResponse.Properties.ContainsKey("Name")); + } + + // write test for query + [Fact] + public async Task QueryDataSourceAsync_ShouldReturnResults() + { + // Arrange + var databaseId = "29ee2842ccb5802397b8fdf6fed5ac93"; // TODO: Create a test database and set its ID here + var dataSourceId = await CreateAndGetDatasourceIdAsync(databaseId); + var queryRequest = new QueryDataSourceRequest + { + DataSourceId = dataSourceId, + }; + + // Act + var queryResponse = await Client.DataSources.QueryAsync(queryRequest); + + // Assert + Assert.NotNull(queryResponse); + Assert.NotNull(queryResponse.Results); + } + + private async Task CreateAndGetDatasourceIdAsync(string databaseId) + { + var request = new CreateDataSourceRequest + { + Parent = new DatabaseParentRequest + { + DatabaseId = databaseId + }, + Properties = new Dictionary + { + { + "Name", + new TitlePropertyConfigurationRequest { + Description = "The name of the data source", + Title = new Dictionary() + } + } + }, + Title = new List + { + new RichTextTextInput { Text = new Text { Content = "Test Data Source" } } + } + }; + + var response = await Client.DataSources.CreateAsync(request); + return response.Id; + } + + [Fact] + public async Task UpdateDatabaseRelationProperties() + { + // Arrange + var createdSourceDatabase = await CreateDatabaseWithAPageAsync("Test Relation Source"); + var createdDestinationDatabase = await CreateDatabaseWithAPageAsync("Test Relation Destination"); + + // Act + var response = await Client.DataSources.UpdateAsync( + new UpdateDataSourceRequest + { + DataSourceId = createdDestinationDatabase.DataSources.First().DataSourceId, + Properties = new Dictionary + { + { + "Single Relation", + new UpdatePropertyConfigurationRequest + { + Name = "Single Relation", + PropertyRequest = new RelationPropertyConfigurationRequest + { + Relation = new SinglePropertyRelationDataRequest + { + DataSourceId = createdSourceDatabase.DataSources.First().DataSourceId, + SingleProperty = new Dictionary() + } + } + } + }, + { + "Dual Relation", + new UpdatePropertyConfigurationRequest + { + Name = "Dual Relation", + PropertyRequest = new RelationPropertyConfigurationRequest + { + Relation = new DualPropertyRelationDataRequest + { + DataSourceId = createdSourceDatabase.DataSources.First().DataSourceId, + DualProperty = new DualPropertyRelationDataRequest.Data() + } + } + } + } + } + }); + + // Assert + await ValidateDatasourceProperties(createdDestinationDatabase.DataSources.First().DataSourceId, createdSourceDatabase.DataSources.First().DataSourceId); + } + + private async Task ValidateDatasourceProperties(string dataSourceId, string sourceDataSourceId) + { + var response = await Client.DataSources.RetrieveAsync(new RetrieveDataSourceRequest { DataSourceId = dataSourceId }); + + response.Properties.Should().NotBeNull(); + + response.Properties.Should().ContainKey("Single Relation"); + var singleRelation = response.Properties["Single Relation"].As().Relation; + singleRelation.Type.Should().Be("single_property"); + var singleRelationData = singleRelation.Should().BeOfType().Subject; + singleRelationData.DataSourceId.Should().Be(sourceDataSourceId); + + response.Properties.Should().ContainKey("Dual Relation"); + var dualRelation = response.Properties["Dual Relation"].As().Relation; + dualRelation.DataSourceId.Should().Be(sourceDataSourceId); + dualRelation.Type.Should().Be("dual_property"); + dualRelation.Should().BeOfType(); + } + + private async Task CreateDatabaseWithAPageAsync(string databaseName) + { + var createDbRequest = new DatabasesCreateRequest + { + Title = new List + { + new RichTextTextInput + { + Text = new Text + { + Content = databaseName, + Link = null + } + } + }, + InitialDataSource = new InitialDataSourceRequest + { + Properties = new Dictionary + { + { "Name", new TitlePropertyConfigurationRequest { Title = new Dictionary() } }, + } + }, + Parent = new PageParentOfDatabaseRequest { PageId = _page.Id } + }; + + var createdDatabase = await Client.Databases.CreateAsync(createDbRequest); + + var pagesCreateParameters = PagesCreateParametersBuilder + .Create(new DatabaseParentRequest { DatabaseId = createdDatabase.Id }) + .AddProperty("Name", + new TitlePropertyValue + { + Title = new List + { + new RichTextText { Text = new Text { Content = "Test Title" } } + } + }) + .Build(); + + await Client.Pages.CreateAsync(pagesCreateParameters); + + return createdDatabase; + } + } +} \ No newline at end of file diff --git a/Test/Notion.IntegrationTests/DatabasesClientTests.cs b/Test/Notion.IntegrationTests/DatabasesClientTests.cs index 7abd7b4e..aeebee7f 100644 --- a/Test/Notion.IntegrationTests/DatabasesClientTests.cs +++ b/Test/Notion.IntegrationTests/DatabasesClientTests.cs @@ -16,7 +16,7 @@ public async Task InitializeAsync() { _page = await Client.Pages.CreateAsync( PagesCreateParametersBuilder.Create( - new ParentPageInput { PageId = ParentPageId } + new PageParentRequest { PageId = ParentPageId } ).Build() ); } @@ -26,84 +26,9 @@ public async Task DisposeAsync() await Client.Pages.UpdateAsync(_page.Id, new PagesUpdateParameters { InTrash = true }); } - [Fact] - public async Task QueryDatabase() - { - // Arrange - var createdDatabase = await CreateDatabaseWithAPageAsync("Test List"); - - // Act - var response = await Client.Databases.QueryAsync(createdDatabase.Id, new DatabasesQueryParameters()); - - // Assert - response.Results.Should().NotBeNull(); - var page = response.Results.Should().ContainSingle().Subject.As(); - - page.Properties["Name"].As() - .Title.Cast().First() - .Text.Content.Should().Be("Test Title"); - } - - [Fact] - public async Task UpdateDatabaseRelationProperties() - { - // Arrange - var createdSourceDatabase = await CreateDatabaseWithAPageAsync("Test Relation Source"); - var createdDestinationDatabase = await CreateDatabaseWithAPageAsync("Test Relation Destination"); - - // Act - var response = await Client.Databases.UpdateAsync(createdDestinationDatabase.Id, - new DatabasesUpdateParameters - { - Properties = new Dictionary - { - { - "Single Relation", - new RelationUpdatePropertySchema - { - Relation = new SinglePropertyRelation - { - DatabaseId = createdSourceDatabase.Id, - SingleProperty = new Dictionary() - } - } - }, - { - "Dual Relation", - new RelationUpdatePropertySchema - { - Relation = new DualPropertyRelation - { - DatabaseId = createdSourceDatabase.Id, - DualProperty = new DualPropertyRelation.Data() - } - } - } - } - }); - - // Assert - response.Properties.Should().NotBeNull(); - - response.Properties.Should().ContainKey("Single Relation"); - var singleRelation = response.Properties["Single Relation"].As().Relation; - singleRelation.Should().BeEquivalentTo( - new SinglePropertyRelation - { - DatabaseId = createdSourceDatabase.Id, - SingleProperty = new Dictionary() - }); - - response.Properties.Should().ContainKey("Dual Relation"); - var dualRelation = response.Properties["Dual Relation"].As().Relation; - dualRelation.DatabaseId.Should().Be(createdSourceDatabase.Id); - dualRelation.Type.Should().Be(RelationType.Dual); - dualRelation.Should().BeOfType(); - } - private async Task CreateDatabaseWithAPageAsync(string databaseName) { - var createDbRequest = new DatabasesCreateParameters + var createDbRequest = new DatabasesCreateRequest { Title = new List { @@ -116,17 +41,20 @@ private async Task CreateDatabaseWithAPageAsync(string databaseName) } } }, - Properties = new Dictionary + InitialDataSource = new InitialDataSourceRequest { - { "Name", new TitlePropertySchema { Title = new Dictionary() } }, + Properties = new Dictionary + { + { "Name", new TitlePropertyConfigurationRequest { Title = new Dictionary() } }, + } }, - Parent = new ParentPageInput { PageId = _page.Id } + Parent = new PageParentOfDatabaseRequest { PageId = _page.Id } }; var createdDatabase = await Client.Databases.CreateAsync(createDbRequest); var pagesCreateParameters = PagesCreateParametersBuilder - .Create(new DatabaseParentInput { DatabaseId = createdDatabase.Id }) + .Create(new DatabaseParentRequest { DatabaseId = createdDatabase.Id }) .AddProperty("Name", new TitlePropertyValue { @@ -146,7 +74,7 @@ private async Task CreateDatabaseWithAPageAsync(string databaseName) public async Task Verify_mention_date_property_parsed_properly() { // Arrange - var createDbRequest = new DatabasesCreateParameters + var createDbRequest = new DatabasesCreateRequest { Title = new List { @@ -170,11 +98,14 @@ public async Task Verify_mention_date_property_parsed_properly() } } }, - Properties = new Dictionary + InitialDataSource = new InitialDataSourceRequest { - { "Name", new TitlePropertySchema { Title = new Dictionary() } }, + Properties = new Dictionary + { + { "Name", new TitlePropertyConfigurationRequest { Title = new Dictionary() } }, + } }, - Parent = new ParentPageInput { PageId = _page.Id } + Parent = new PageParentOfDatabaseRequest { PageId = _page.Id } }; // Act @@ -185,4 +116,47 @@ public async Task Verify_mention_date_property_parsed_properly() mention.Date.Start.Should().NotBeNull(); mention.Date.End.Should().NotBeNull(); } -} + + [Fact] + public async Task UpdateDatabase() + { + // Arrange + var createdDatabase = await CreateDatabaseWithAPageAsync("Initial DB Name"); + var updateRequest = new DatabasesUpdateRequest + { + DatabaseId = createdDatabase.Id, + Title = new List + { + new RichTextTextInput + { + Text = new Text + { + Content = "Updated DB Name", + Link = null + } + } + } + }; + + // Act + var updatedDatabase = await Client.Databases.UpdateAsync(updateRequest); + + // Assert + updatedDatabase.Title.OfType().First().Text.Content.Should().Be("Updated DB Name"); + } + + [Fact] + public async Task RetrieveDatabase() + { + // Arrange + var createdDatabase = await CreateDatabaseWithAPageAsync("Retrieve Test DB"); + + // Act + var retrievedDatabase = await Client.Databases.RetrieveAsync(createdDatabase.Id); + + // Assert + retrievedDatabase.Id.Should().Be(createdDatabase.Id); + retrievedDatabase.Title.OfType().First().Text.Content.Should().Be("Retrieve Test DB"); + retrievedDatabase.DataSources.Should().ContainSingle(); + } +} \ No newline at end of file diff --git a/Test/Notion.IntegrationTests/PageClientTests.cs b/Test/Notion.IntegrationTests/PageClientTests.cs index 4938bcfa..b52d6b9a 100644 --- a/Test/Notion.IntegrationTests/PageClientTests.cs +++ b/Test/Notion.IntegrationTests/PageClientTests.cs @@ -18,12 +18,12 @@ public async Task InitializeAsync() // Create a page _page = await Client.Pages.CreateAsync( PagesCreateParametersBuilder.Create( - new ParentPageInput { PageId = ParentPageId } + new PageParentRequest { PageId = ParentPageId } ).Build() ); // Create a database - var createDbRequest = new DatabasesCreateParameters + var createDbRequest = new DatabasesCreateRequest { Title = new List { @@ -36,26 +36,29 @@ public async Task InitializeAsync() } } }, - Properties = new Dictionary + InitialDataSource = new InitialDataSourceRequest { - { "Name", new TitlePropertySchema { Title = new Dictionary() } }, + Properties = new Dictionary { - "TestSelect", - new SelectPropertySchema + { "Name", new TitlePropertyConfigurationRequest { Title = new Dictionary() } }, { - Select = new OptionWrapper + "TestSelect", + new SelectPropertyConfigurationRequest { - Options = new List + Select = new SelectPropertyConfigurationRequest.SelectOptions { - new() { Name = "Red" }, - new() { Name = "Blue" } + Options = new List + { + new() { Name = "Red" }, + new() { Name = "Blue" } + } } } - } - }, - { "Number", new NumberPropertySchema { Number = new Number { Format = "number" } } } + }, + { "Number", new NumberPropertyConfigurationRequest { Number = new NumberPropertyConfigurationRequest.NumberFormat { Format = "number" } } } + } }, - Parent = new ParentPageInput { PageId = _page.Id } + Parent = new PageParentOfDatabaseRequest { PageId = _page.Id } }; _database = await Client.Databases.CreateAsync(createDbRequest); @@ -70,7 +73,7 @@ public async Task DisposeAsync() public async Task CreateAsync_CreatesANewPage() { var pagesCreateParameters = PagesCreateParametersBuilder - .Create(new DatabaseParentInput { DatabaseId = _database.Id }) + .Create(new DataSourceParentRequest { DataSourceId = _database.DataSources.First().DataSourceId }) .AddProperty("Name", new TitlePropertyValue { @@ -85,8 +88,8 @@ public async Task CreateAsync_CreatesANewPage() page.Should().NotBeNull(); - page.Parent.Should().BeOfType().Which - .DatabaseId.Should().Be(_database.Id); + page.Parent.Should().BeOfType().Which + .DataSourceId.Should().Be(_database.DataSources.First().DataSourceId); page.Properties.Should().ContainKey("Name"); var pageProperty = page.Properties["Name"].Should().BeOfType().Subject; @@ -107,7 +110,7 @@ public async Task Bug_unable_to_create_page_with_select_property() { // Arrange var pagesCreateParameters = PagesCreateParametersBuilder - .Create(new DatabaseParentInput { DatabaseId = _database.Id }) + .Create(new DataSourceParentRequest { DataSourceId = _database.DataSources.First().DataSourceId }) .AddProperty("Name", new TitlePropertyValue { @@ -126,8 +129,8 @@ public async Task Bug_unable_to_create_page_with_select_property() // Asserts page.Should().NotBeNull(); - page.Parent.Should().BeOfType().Which - .DatabaseId.Should().Be(_database.Id); + page.Parent.Should().BeOfType().Which + .DataSourceId.Should().Be(_database.DataSources.First().DataSourceId); page.Properties.Should().ContainKey("Name"); var titlePropertyValue = page.Properties["Name"].Should().BeOfType().Subject; @@ -143,7 +146,7 @@ public async Task Test_RetrievePagePropertyItemAsync() { // Arrange var pagesCreateParameters = PagesCreateParametersBuilder - .Create(new DatabaseParentInput { DatabaseId = _database.Id }) + .Create(new DataSourceParentRequest { DataSourceId = _database.DataSources.First().DataSourceId }) .AddProperty("Name", new TitlePropertyValue { @@ -188,21 +191,34 @@ public async Task Test_UpdatePageProperty_with_date_as_null() // Add property Date property to database const string DatePropertyName = "Test Date Property"; - var updateDatabaseParameters = new DatabasesUpdateParameters + var updateDatabaseParameters = new UpdateDataSourceRequest { - Properties = new Dictionary + DataSourceId = _database.DataSources.First().DataSourceId, + Properties = new Dictionary { - { "Name", new TitleUpdatePropertySchema { Title = new Dictionary() } }, + { + "Name", + new UpdatePropertyConfigurationRequest { + PropertyRequest = new TitlePropertyConfigurationRequest { Title = new Dictionary() } + } + }, { "Test Date Property", - new DateUpdatePropertySchema { Date = new Dictionary() } + new UpdatePropertyConfigurationRequest + { + Name = DatePropertyName, + PropertyRequest = new DatePropertyConfigurationRequest + { + Date = new Dictionary() + } + } } } }; // Create a page with the property having a date var pagesCreateParameters = PagesCreateParametersBuilder - .Create(new DatabaseParentInput { DatabaseId = _database.Id }) + .Create(new DataSourceParentRequest { DataSourceId = _database.DataSources.First().DataSourceId }) .AddProperty("Name", new TitlePropertyValue { @@ -217,12 +233,13 @@ public async Task Test_UpdatePageProperty_with_date_as_null() Date = new Date { Start = DateTimeOffset.Parse("2024-06-26T00:00:00.000+01:00"), - End = DateTimeOffset.Parse("2025-12-08").Date + End = DateTimeOffset.Parse("2025-12-08").Date, + IncludeTime = true } }) .Build(); - await Client.Databases.UpdateAsync(_database.Id, updateDatabaseParameters); + await Client.DataSources.UpdateAsync(updateDatabaseParameters); var page = await Client.Pages.CreateAsync(pagesCreateParameters); @@ -237,7 +254,7 @@ public async Task Test_UpdatePageProperty_with_date_as_null() // Assert setDate?.Date?.Start.Should().Be(DateTimeOffset.Parse("2024-06-26T00:00:00.000+01:00")); - setDate?.Date?.End.Should().Be(DateTimeOffset.Parse("2025-12-08T00:00:00.000+01:00")); + setDate?.Date?.End.Should().Be(DateTimeOffset.Parse("2025-12-08").Date); var pageUpdateParameters = new PagesUpdateParameters { @@ -265,7 +282,7 @@ public async Task Bug_Unable_To_Parse_NumberPropertyItem() { // Arrange var pagesCreateParameters = PagesCreateParametersBuilder - .Create(new DatabaseParentInput { DatabaseId = _database.Id }) + .Create(new DataSourceParentRequest { DataSourceId = _database.DataSources.First().DataSourceId }) .AddProperty("Name", new TitlePropertyValue { @@ -281,8 +298,8 @@ public async Task Bug_Unable_To_Parse_NumberPropertyItem() // Assert Assert.NotNull(page); - var pageParent = Assert.IsType(page.Parent); - Assert.Equal(_database.Id, pageParent.DatabaseId); + var pageParent = Assert.IsType(page.Parent); + Assert.Equal(_database.DataSources.First().DataSourceId, pageParent.DataSourceId); var titleProperty = (ListPropertyItem)await Client.Pages.RetrievePagePropertyItemAsync( new RetrievePropertyItemParameters @@ -307,51 +324,56 @@ public async Task Bug_Unable_To_Parse_NumberPropertyItem() public async Task Bug_exception_when_attempting_to_set_select_property_to_nothing() { // Arrange - var databaseCreateRequest = new DatabasesCreateParameters + var databaseCreateRequest = new DatabasesCreateRequest { - Title = - new List { new RichTextTextInput { Text = new Text { Content = "Test Database" } } }, - Parent = new ParentPageInput() { PageId = _page.Id }, - Properties = new Dictionary + Title = new List { - { "title", new TitlePropertySchema { Title = new Dictionary() } }, + new RichTextTextInput { Text = new Text { Content = "Test Database" } } + }, + Parent = new PageParentOfDatabaseRequest() { PageId = _page.Id }, + InitialDataSource = new InitialDataSourceRequest + { + Properties = new Dictionary { - "Colors1", - new SelectPropertySchema + { "title", new TitlePropertyConfigurationRequest { Title = new Dictionary() } }, { - Select = new OptionWrapper + "Colors1", + new SelectPropertyConfigurationRequest { - Options = new List + Select = new SelectPropertyConfigurationRequest.SelectOptions { - new() { Name = "Red" }, - new() { Name = "Green" }, - new() { Name = "Blue" } + Options = new List + { + new() { Name = "Red" }, + new() { Name = "Green" }, + new() { Name = "Blue" } + } } } - } - }, - { - "Colors2", - new SelectPropertySchema + }, { - Select = new OptionWrapper + "Colors2", + new SelectPropertyConfigurationRequest { - Options = new List + Select = new SelectPropertyConfigurationRequest.SelectOptions { - new() { Name = "Red" }, - new() { Name = "Green" }, - new() { Name = "Blue" } + Options = new List + { + new() { Name = "Red" }, + new() { Name = "Green" }, + new() { Name = "Blue" } + } } } - } - }, + }, + } } }; var database = await Client.Databases.CreateAsync(databaseCreateRequest); var pagesCreateParameters = PagesCreateParametersBuilder - .Create(new DatabaseParentInput { DatabaseId = database.Id }) + .Create(new DataSourceParentRequest { DataSourceId = database.DataSources.First().DataSourceId }) .AddProperty("title", new TitlePropertyValue { @@ -390,7 +412,7 @@ public async Task Bug_exception_when_attempting_to_set_select_property_to_nothin public async Task Verify_date_property_is_parsed_correctly_in_mention_object() { var pageRequest = PagesCreateParametersBuilder - .Create(new DatabaseParentInput { DatabaseId = _database.Id }) + .Create(new DataSourceParentRequest { DataSourceId = _database.DataSources.First().DataSourceId }) .AddProperty("Name", new TitlePropertyValue { @@ -414,8 +436,8 @@ public async Task Verify_date_property_is_parsed_correctly_in_mention_object() page.Should().NotBeNull(); - page.Parent.Should().BeOfType().Which - .DatabaseId.Should().Be(_database.Id); + page.Parent.Should().BeOfType().Which + .DataSourceId.Should().Be(_database.DataSources.First().DataSourceId); page.Properties.Should().ContainKey("Name"); var pageProperty = page.Properties["Name"].Should().BeOfType().Subject; diff --git a/Test/Notion.IntegrationTests/PageWithPageParentTests.cs b/Test/Notion.IntegrationTests/PageWithPageParentTests.cs index 3c6d3c6c..12aa81f3 100644 --- a/Test/Notion.IntegrationTests/PageWithPageParentTests.cs +++ b/Test/Notion.IntegrationTests/PageWithPageParentTests.cs @@ -14,7 +14,7 @@ public class PageWithPageParentTests : IntegrationTestBase, IAsyncLifetime public async Task InitializeAsync() { var pagesCreateParameters = PagesCreateParametersBuilder - .Create(new ParentPageInput() { PageId = ParentPageId }) + .Create(new PageParentRequest() { PageId = ParentPageId }) .AddProperty("title", new TitlePropertyValue { diff --git a/Test/Notion.UnitTests/DataSourcesClientTests.cs b/Test/Notion.UnitTests/DataSourcesClientTests.cs new file mode 100644 index 00000000..222be014 --- /dev/null +++ b/Test/Notion.UnitTests/DataSourcesClientTests.cs @@ -0,0 +1,380 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Moq; +using Moq.AutoMock; +using Notion.Client; +using Xunit; + +namespace Notion.UnitTests; + +public class DataSourcesClientTests +{ + private readonly AutoMocker _mocker = new(); + private readonly Mock _restClient; + private readonly IDataSourcesClient _dataSourcesClient; + private readonly CancellationToken _cancellationToken = CancellationToken.None; + + public DataSourcesClientTests() + { + _restClient = _mocker.GetMock(); + _dataSourcesClient = _mocker.CreateInstance(); + } + + #region RetrieveAsync Tests + + [Fact] + public async Task RetrieveAsync_ShouldThrowArgumentNullException_WhenRequestIsNull() + { + // Arrange + RetrieveDataSourceRequest request = null; + + // Act & Assert + await Assert.ThrowsAsync(() => _dataSourcesClient.RetrieveAsync(request, _cancellationToken)); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public async Task RetrieveAsync_ShouldThrowArgumentException_WhenDataSourceIdIsInvalid(string dataSourceId) + { + // Arrange + var request = new RetrieveDataSourceRequest + { + DataSourceId = dataSourceId + }; + + // Act & Assert + var exception = await Assert.ThrowsAsync(() => _dataSourcesClient.RetrieveAsync(request, _cancellationToken)); + Assert.Equal("DataSourceId cannot be null or empty. (Parameter 'DataSourceId')", exception.Message); + } + + [Fact] + public async Task RetrieveAsync_ShouldReturnDataSource() + { + // Arrange + var dataSourceId = "test-data-source-id"; + var expectedDataSource = new RetrieveDataSourceResponse + { + Id = dataSourceId, + Title = new RichTextBase[] + { + new RichTextText + { + Text = new Text + { + Content = "Test Data Source" + } + } + } + }; + + var request = new RetrieveDataSourceRequest + { + DataSourceId = dataSourceId + }; + + _restClient + .Setup(client => client.GetAsync(ApiEndpoints.DataSourcesApiUrls.Retrieve(request), null, null, null, _cancellationToken)) + .ReturnsAsync(expectedDataSource); + + // Act + var result = await _dataSourcesClient.RetrieveAsync(request, _cancellationToken); + + // Assert + Assert.Equal(expectedDataSource, result); + } + + #endregion RetrieveAsync Tests + + #region ListDataSourceTemplatesAsync Tests + + [Fact] + public async Task ListDataSourceTemplatesAsync_ShouldThrowArgumentNullException_WhenRequestIsNull() + { + // Arrange + ListDataSourceTemplatesRequest request = null; + + // Act & Assert + await Assert.ThrowsAsync(() => _dataSourcesClient.ListDataSourceTemplatesAsync(request, _cancellationToken)); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public async Task ListDataSourceTemplatesAsync_ShouldThrowArgumentException_WhenDataSourceIdIsInvalid(string dataSourceId) + { + // Arrange + var request = new ListDataSourceTemplatesRequest + { + DataSourceId = dataSourceId + }; + + // Act & Assert + var exception = await Assert.ThrowsAsync(() => _dataSourcesClient.ListDataSourceTemplatesAsync(request, _cancellationToken)); + Assert.Equal("DataSourceId cannot be null or empty. (Parameter 'DataSourceId')", exception.Message); + } + + [Fact] + public async Task ListDataSourceTemplatesAsync_ShouldReturnTemplates_WithValidRequest() + { + // Arrange + var dataSourceId = "test-data-source-id"; + var expectedResponse = new ListDataSourceTemplatesResponse + { + Templates = new[] + { + new DataSourceTemplate + { + Id = "template-1", + Name = "Default Template", + IsDefault = true + }, + new DataSourceTemplate + { + Id = "template-2", + Name = "Custom Template", + IsDefault = false + } + }, + HasMore = false, + NextCursor = null + }; + + var request = new ListDataSourceTemplatesRequest + { + DataSourceId = dataSourceId + }; + + var expectedEndpoint = $"/v1/data-sources/{dataSourceId}/templates"; + var expectedQueryParams = new Dictionary + { + { "name", null }, + { "start_cursor", null }, + { "page_size", null } + }; + + _restClient + .Setup(client => client.GetAsync( + expectedEndpoint, + expectedQueryParams, + null, + null, + _cancellationToken)) + .ReturnsAsync(expectedResponse); + + // Act + var result = await _dataSourcesClient.ListDataSourceTemplatesAsync(request, _cancellationToken); + + // Assert + Assert.Equal(expectedResponse, result); + Assert.Equal(2, result.Templates.Count()); + Assert.False(result.HasMore); + Assert.Null(result.NextCursor); + } + + [Fact] + public async Task ListDataSourceTemplatesAsync_ShouldPassAllQueryParameters_WhenProvided() + { + // Arrange + var dataSourceId = "test-data-source-id"; + var templateName = "Custom Template"; + var startCursor = "cursor123"; + var pageSize = 50; + + var expectedResponse = new ListDataSourceTemplatesResponse + { + Templates = new[] + { + new DataSourceTemplate + { + Id = "template-1", + Name = templateName, + IsDefault = false + } + }, + HasMore = true, + NextCursor = "next-cursor456" + }; + + var request = new ListDataSourceTemplatesRequest + { + DataSourceId = dataSourceId, + Name = templateName, + StartCursor = startCursor, + PageSize = pageSize + }; + + var expectedEndpoint = $"/v1/data-sources/{dataSourceId}/templates"; + var expectedQueryParams = new Dictionary + { + { "name", templateName }, + { "start_cursor", startCursor }, + { "page_size", pageSize.ToString() } + }; + + _restClient + .Setup(client => client.GetAsync( + expectedEndpoint, + expectedQueryParams, + null, + null, + _cancellationToken)) + .ReturnsAsync(expectedResponse); + + // Act + var result = await _dataSourcesClient.ListDataSourceTemplatesAsync(request, _cancellationToken); + + // Assert + Assert.Equal(expectedResponse, result); + Assert.Single(result.Templates); + Assert.True(result.HasMore); + Assert.Equal("next-cursor456", result.NextCursor); + + // Verify the REST client was called with correct parameters + _restClient.Verify(client => client.GetAsync( + expectedEndpoint, + expectedQueryParams, + null, + null, + _cancellationToken), Times.Once); + } + + [Fact] + public async Task ListDataSourceTemplatesAsync_ShouldReturnEmptyTemplates_WhenNoTemplatesFound() + { + // Arrange + var dataSourceId = "test-data-source-id"; + var expectedResponse = new ListDataSourceTemplatesResponse + { + Templates = new DataSourceTemplate[0], + HasMore = false, + NextCursor = null + }; + + var request = new ListDataSourceTemplatesRequest + { + DataSourceId = dataSourceId + }; + + var expectedEndpoint = $"/v1/data-sources/{dataSourceId}/templates"; + + _restClient + .Setup(client => client.GetAsync( + expectedEndpoint, + It.IsAny>(), + null, + null, + _cancellationToken)) + .ReturnsAsync(expectedResponse); + + // Act + var result = await _dataSourcesClient.ListDataSourceTemplatesAsync(request, _cancellationToken); + + // Assert + Assert.Equal(expectedResponse, result); + Assert.Empty(result.Templates); + Assert.False(result.HasMore); + Assert.Null(result.NextCursor); + } + + [Fact] + public async Task ListDataSourceTemplatesAsync_ShouldHandleNullPageSize_InQueryParameters() + { + // Arrange + var dataSourceId = "test-data-source-id"; + var request = new ListDataSourceTemplatesRequest + { + DataSourceId = dataSourceId, + Name = "Test Template", + StartCursor = "cursor123", + PageSize = null // Explicitly null + }; + + var expectedResponse = new ListDataSourceTemplatesResponse + { + Templates = new DataSourceTemplate[0], + HasMore = false, + NextCursor = null + }; + + var expectedEndpoint = $"/v1/data-sources/{dataSourceId}/templates"; + var expectedQueryParams = new Dictionary + { + { "name", "Test Template" }, + { "start_cursor", "cursor123" }, + { "page_size", null } // Should be null when PageSize is null + }; + + _restClient + .Setup(client => client.GetAsync( + expectedEndpoint, + expectedQueryParams, + null, + null, + _cancellationToken)) + .ReturnsAsync(expectedResponse); + + // Act + var result = await _dataSourcesClient.ListDataSourceTemplatesAsync(request, _cancellationToken); + + // Assert + Assert.Equal(expectedResponse, result); + + // Verify the REST client was called with correct parameters + _restClient.Verify(client => client.GetAsync( + expectedEndpoint, + expectedQueryParams, + null, + null, + _cancellationToken), Times.Once); + } + + [Fact] + public async Task ListDataSourceTemplatesAsync_ShouldUseCancellationToken() + { + // Arrange + var dataSourceId = "test-data-source-id"; + var customCancellationToken = new CancellationTokenSource().Token; + var request = new ListDataSourceTemplatesRequest + { + DataSourceId = dataSourceId + }; + + var expectedResponse = new ListDataSourceTemplatesResponse + { + Templates = new DataSourceTemplate[0], + HasMore = false, + NextCursor = null + }; + + _restClient + .Setup(client => client.GetAsync( + It.IsAny(), + It.IsAny>(), + null, + null, + customCancellationToken)) + .ReturnsAsync(expectedResponse); + + // Act + var result = await _dataSourcesClient.ListDataSourceTemplatesAsync(request, customCancellationToken); + + // Assert + Assert.Equal(expectedResponse, result); + + // Verify the custom cancellation token was used + _restClient.Verify(client => client.GetAsync( + It.IsAny(), + It.IsAny>(), + null, + null, + customCancellationToken), Times.Once); + } + + #endregion ListDataSourceTemplatesAsync Tests +} \ No newline at end of file diff --git a/Test/Notion.UnitTests/DatabasesClientTests.cs b/Test/Notion.UnitTests/DatabasesClientTests.cs deleted file mode 100644 index 30deae75..00000000 --- a/Test/Notion.UnitTests/DatabasesClientTests.cs +++ /dev/null @@ -1,521 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; -using FluentAssertions; -using Notion.Client; -using WireMock.ResponseBuilders; -using Xunit; - -namespace Notion.UnitTests; - -public class DatabasesClientTests : ApiTestBase -{ - private readonly IDatabasesClient _client; - private readonly IPagesClient _pagesClient; - - public DatabasesClientTests() - { - _client = new DatabasesClient(new RestClient(ClientOptions)); - _pagesClient = new PagesClient(new RestClient(ClientOptions)); - } - - [Fact] - public async Task QueryAsync() - { - var databaseId = "f0212efc-caf6-4afc-87f6-1c06f1dfc8a1"; - var path = ApiEndpoints.DatabasesApiUrls.Query(databaseId); - var jsonData = await File.ReadAllTextAsync("data/databases/DatabasesQueryResponse.json"); - - Server.Given(CreatePostRequestBuilder(path)) - .RespondWith( - Response.Create() - .WithStatusCode(200) - .WithBody(jsonData) - ); - - var databasesQueryParams = new DatabasesQueryParameters - { - Filter = new CompoundFilter - { - Or = new List - { - new CheckboxFilter( - "In stock", - true - ), - new NumberFilter( - "Cost of next trip", - greaterThanOrEqualTo: 2 - ) - } - }, - Sorts = new List - { - new() - { - Property = "Last ordered", - Direction = Direction.Ascending - } - } - }; - - var pagesPaginatedList = await _client.QueryAsync(databaseId, databasesQueryParams); - - pagesPaginatedList.Results.Should().ContainSingle(); - - foreach (var iWikiDatabase in pagesPaginatedList.Results) - { - var page = (Page)iWikiDatabase; - page.Parent.Should().BeAssignableTo(); - page.Object.Should().Be(ObjectType.Page); - } - } - - [Fact] - public async Task RetrieveDatabaseAsync() - { - var databaseId = "f0212efc-caf6-4afc-87f6-1c06f1dfc8a1"; - var path = ApiEndpoints.DatabasesApiUrls.Retrieve(databaseId); - var jsonData = await File.ReadAllTextAsync("data/databases/DatabaseRetrieveResponse.json"); - - Server.Given(CreateGetRequestBuilder(path)) - .RespondWith( - Response.Create() - .WithStatusCode(200) - .WithBody(jsonData) - ); - - var database = await _client.RetrieveAsync(databaseId); - - database.Parent.Type.Should().Be(ParentType.PageId); - database.Parent.Should().BeOfType(); - ((PageParent)database.Parent).PageId.Should().Be("649089db-8984-4051-98fb-a03593b852d8"); - - foreach (var property in database.Properties) - { - property.Key.Should().Be(property.Value.Name); - } - - HelperAsserts.IPageIconAsserts(database.Icon); - HelperAsserts.FileObjectAsserts(database.Cover); - } - - [Fact] - public async Task DatabasePropertyObjectContainNameProperty() - { - var databaseId = "f0212efc-caf6-4afc-87f6-1c06f1dfc8a1"; - var path = ApiEndpoints.DatabasesApiUrls.Retrieve(databaseId); - var jsonData = await File.ReadAllTextAsync("data/databases/DatabasePropertyObjectContainNameProperty.json"); - - Server.Given(CreateGetRequestBuilder(path)) - .RespondWith( - Response.Create() - .WithStatusCode(200) - .WithBody(jsonData) - ); - - var database = await _client.RetrieveAsync(databaseId); - - foreach (var property in database.Properties) - { - property.Key.Should().Be(property.Value.Name); - } - } - - [Fact] - public async Task DatabasePropertyObjectContainRelationProperty() - { - var databaseId = "f0212efc-caf6-4afc-87f6-1c06f1dfc8a1"; - var path = ApiEndpoints.DatabasesApiUrls.Retrieve(databaseId); - var jsonData = await File.ReadAllTextAsync("data/databases/DatabasePropertyObjectContainRelation.json"); - - Server.Given(CreateGetRequestBuilder(path)) - .RespondWith( - Response.Create() - .WithStatusCode(200) - .WithBody(jsonData) - ); - - var database = await _client.RetrieveAsync(databaseId); - - database.Properties.Should().ContainKey("Property").WhichValue.Should().BeEquivalentTo( - new RelationProperty - { - Id = "zDGa", - Name = "Property", - Relation = new DualPropertyRelation - { - DatabaseId = "f86f2262-0751-40f2-8f63-e3f7a3c39fcb", - DualProperty = new DualPropertyRelation.Data - { - SyncedPropertyName = "Related to sample table (Property)", - SyncedPropertyId = "VQ}{" - } - } - }); - } - - [Fact] - public async Task DatabasePropertyObjectContainParentProperty() - { - var databaseId = "f0212efc-caf6-4afc-87f6-1c06f1dfc8a1"; - var path = ApiEndpoints.DatabasesApiUrls.Retrieve(databaseId); - var jsonData = await File.ReadAllTextAsync("data/databases/DatabasePropertyObjectContainParentProperty.json"); - - Server.Given(CreateGetRequestBuilder(path)) - .RespondWith( - Response.Create() - .WithStatusCode(200) - .WithBody(jsonData) - ); - - var database = await _client.RetrieveAsync(databaseId); - - database.Parent.Type.Should().Be(ParentType.PageId); - database.Parent.Should().BeOfType(); - ((PageParent)database.Parent).PageId.Should().Be("649089db-8984-4051-98fb-a03593b852d8"); - } - - [Fact] - public async Task CreateDatabaseAsync() - { - var pageId = "533578e3-edf1-4c0a-91a9-da6b09bac3ee"; - var path = ApiEndpoints.DatabasesApiUrls.Create; - var jsonData = await File.ReadAllTextAsync("data/databases/CreateDatabaseResponse.json"); - - Server.Given(CreatePostRequestBuilder(path)) - .RespondWith( - Response.Create() - .WithStatusCode(200) - .WithBody(jsonData) - ); - - var createDatabaseParameters = new DatabasesCreateParameters - { - Parent = new ParentPageInput { PageId = pageId }, - Title = new List - { - new RichTextTextInput - { - Text = new Text - { - Content = "Grocery List", - Link = null - } - } - }, - Properties = new Dictionary - { - { "Name", new TitlePropertySchema { Title = new Dictionary() } }, - { "Price", new NumberPropertySchema { Number = new Number { Format = "dollar" } } }, - { - "Food group", - new SelectPropertySchema - { - Select = new OptionWrapper - { - Options = new List - { - new() - { - Color = Color.Green, - Name = "🥦Vegetable" - }, - new() - { - Color = Color.Red, - Name = "🍎Fruit" - }, - new() - { - Color = Color.Yellow, - Name = "💪Protein" - } - } - } - } - }, - { "Last ordered", new DatePropertySchema { Date = new Dictionary() } } - } - }; - - var database = await _client.CreateAsync(createDatabaseParameters); - - database.Parent.Type.Should().Be(ParentType.PageId); - database.Parent.Should().BeOfType(); - ((PageParent)database.Parent).PageId.Should().Be(pageId); - - database.Properties.Should().HaveCount(4); - - var selectOptions = (SelectProperty)database.Properties["Food group"]; - selectOptions.Name.Should().Be("Food group"); - - selectOptions.Select.Options.Should().SatisfyRespectively( - option => - { - option.Name.Should().Be("🥦Vegetable"); - option.Color.Should().Be(Color.Green); - }, - option => - { - option.Name.Should().Be("🍎Fruit"); - option.Color.Should().Be(Color.Red); - }, - option => - { - option.Name.Should().Be("💪Protein"); - option.Color.Should().Be(Color.Yellow); - } - ); - } - - [Fact] - public async Task UpdateDatabaseAsync() - { - var databaseId = "1e9eee34-9c5c-4fe6-a4e1-8244eb141ed8"; - var path = ApiEndpoints.DatabasesApiUrls.Update(databaseId); - var jsonData = await File.ReadAllTextAsync("data/databases/UpdateDatabaseResponse.json"); - - Server.Given(CreatePatchRequestBuilder(path)) - .RespondWith( - Response.Create() - .WithStatusCode(200) - .WithBody(jsonData) - ); - - var updateDatabaseParameters = new DatabasesUpdateParameters - { - Title = - new List - { - new RichTextTextInput - { - Text = new Text - { - Content = "Grocery List New", - Link = null - } - } - }, - Properties = new Dictionary - { - { "Name", new TitleUpdatePropertySchema { Title = new Dictionary() } }, - { "Price", new NumberUpdatePropertySchema { Number = new Number { Format = "yen" } } }, - { - "Food group", - new SelectUpdatePropertySchema - { - Select = new OptionWrapper - { - Options = new List - { - new() - { - Color = Color.Green, - Name = "🥦Vegetables" - }, - new() - { - Color = Color.Red, - Name = "🍎Fruit" - }, - new() - { - Color = Color.Yellow, - Name = "💪Protein" - } - } - } - } - }, - { "Last ordered", new DateUpdatePropertySchema { Date = new Dictionary() } } - } - }; - - var database = await _client.UpdateAsync(databaseId, updateDatabaseParameters); - - database.Parent.Type.Should().Be(ParentType.PageId); - database.Parent.Should().BeOfType(); - ((PageParent)database.Parent).PageId.Should().Be("533578e3-edf1-4c0a-91a9-da6b09bac3ee"); - - database.Properties.Should().HaveCount(4); - - database.Title.Should().ContainSingle(); - - database.Title.Should().SatisfyRespectively( - title => - { - title.Should().BeAssignableTo(); - ((RichTextText)title).Text.Content.Should().Be("Grocery List New"); - } - ); - - var selectOptions = (SelectProperty)database.Properties["Food group"]; - selectOptions.Name.Should().Be("Food group"); - - selectOptions.Select.Options.Should().SatisfyRespectively( - option => - { - option.Name.Should().Be("🥦Vegetables"); - option.Color.Should().Be(Color.Green); - }, - option => - { - option.Name.Should().Be("🍎Fruit"); - option.Color.Should().Be(Color.Red); - }, - option => - { - option.Name.Should().Be("💪Protein"); - option.Color.Should().Be(Color.Yellow); - } - ); - - var price = (NumberProperty)database.Properties["Price"]; - price.Number.Format.Should().Be("yen"); - } - - [Fact] - public async Task FormulaPropertyCanBeSetWhenCreatingDatabase() - { - var pageId = "98ad959b-2b6a-4774-80ee-00246fb0ea9b"; - var path = ApiEndpoints.DatabasesApiUrls.Create; - - var jsonData - = await File.ReadAllTextAsync("data/databases/FormulaPropertyCanBeSetWhenCreatingDatabaseResponse.json"); - - Server.Given(CreatePostRequestBuilder(path)) - .RespondWith( - Response.Create() - .WithStatusCode(200) - .WithBody(jsonData) - ); - - var createDatabaseParameters = new DatabasesCreateParameters - { - Parent = new ParentPageInput { PageId = pageId }, - Title = new List - { - new RichTextTextInput - { - Text = new Text - { - Content = "Grocery List", - Link = null - } - } - }, - Properties = new Dictionary - { - { - "Cost of next trip", - new FormulaPropertySchema - { - Formula = new Formula { Expression = "if(prop(\"In stock\"), 0, prop(\"Price\"))" } - } - }, - { "Price", new NumberPropertySchema { Number = new Number { Format = "dollar" } } } - } - }; - - var database = await _client.CreateAsync(createDatabaseParameters); - - database.Parent.Type.Should().Be(ParentType.PageId); - database.Parent.Should().BeOfType(); - ((PageParent)database.Parent).PageId.Should().Be(pageId); - - database.Properties.Should().HaveCount(2); - - var formulaProperty = (FormulaProperty)database.Properties["Cost of next trip"]; - formulaProperty.Formula.Expression.Should().Be("if(prop(\"In stock\"), 0, prop(\"Price\"))"); - } - - [Fact] - public async Task Fix123_QueryAsync_DateFormulaValue_Returns_Null() - { - var databaseId = "f86f2262-0751-40f2-8f63-e3f7a3c39fcb"; - var path = ApiEndpoints.DatabasesApiUrls.Query(databaseId); - - var jsonData - = await File.ReadAllTextAsync("data/databases/Fix123QueryAsyncDateFormulaValueReturnsNullResponse.json"); - - Server.Given(CreatePostRequestBuilder(path)) - .RespondWith( - Response.Create() - .WithStatusCode(200) - .WithBody(jsonData) - ); - - var databasesQueryParams = new DatabasesQueryParameters - { - Filter = new CompoundFilter - { - Or = new List - { - new CheckboxFilter( - "In stock", - true - ), - new NumberFilter( - "Cost of next trip", - greaterThanOrEqualTo: 2 - ) - } - }, - Sorts = new List - { - new() - { - Property = "Last ordered", - Direction = Direction.Ascending - } - } - }; - - var pagesPaginatedList = await _client.QueryAsync(databaseId, databasesQueryParams); - - pagesPaginatedList.Results.Should().ContainSingle(); - - foreach (var iWikiDatabase in pagesPaginatedList.Results) - { - var page = (Page)iWikiDatabase; - page.Parent.Should().BeAssignableTo(); - page.Object.Should().Be(ObjectType.Page); - - Server.Given(CreateGetRequestBuilder( - ApiEndpoints.PagesApiUrls.RetrievePropertyItem(page.Id, page.Properties["FormulaProp"].Id))) - .RespondWith( - Response.Create() - .WithStatusCode(200) - .WithBody( - "{\"object\":\"property_item\",\"id\":\"JwY^\",\"type\":\"formula\",\"formula\":{\"type\":\"date\",\"date\":{\"start\":\"2021-06-28\",\"end\":null}}}") - ); - - var formulaPropertyValue = (FormulaPropertyItem)await _pagesClient.RetrievePagePropertyItemAsync( - new RetrievePropertyItemParameters - { - PageId = page.Id, - PropertyId = page.Properties["FormulaProp"].Id - }); - - //var formulaPropertyValue = (FormulaPropertyValue)page.Properties["FormulaProp"]; - formulaPropertyValue.Formula.Date.Start.Should().Be(DateTimeOffset.Parse("2021-06-28", null, System.Globalization.DateTimeStyles.AssumeUniversal).UtcDateTime); - formulaPropertyValue.Formula.Date.End.Should().BeNull(); - } - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - public async Task RetrieveAsync_throws_argument_null_exception_if_database_id_is_null_or_empty(string databaseId) - { - // Arrange && Act - async Task Act() => await _client.RetrieveAsync(databaseId); - - // Assert - var exception = await Assert.ThrowsAsync(Act); - Assert.Equal("databaseId", exception.ParamName); - } -} diff --git a/Test/Notion.UnitTests/DateCustomConverterTests.cs b/Test/Notion.UnitTests/DateCustomConverterTests.cs index 81c33f57..b31833c6 100644 --- a/Test/Notion.UnitTests/DateCustomConverterTests.cs +++ b/Test/Notion.UnitTests/DateCustomConverterTests.cs @@ -216,4 +216,198 @@ public void Round_trip_preserves_data() Assert.Equal(originalDate.TimeZone, deserializedDate.TimeZone); Assert.True(deserializedDate.IncludeTime); } + + [Fact] + public void Serialize_with_timezone_offset_converts_to_utc() + { + // Arrange + var date = new Date + { + Start = new DateTimeOffset(2023, 5, 15, 14, 30, 45, TimeSpan.FromHours(2)), // +02:00 offset + End = new DateTimeOffset(2023, 5, 20, 16, 45, 0, TimeSpan.FromHours(-5)), // -05:00 offset + IncludeTime = true + }; + + // Act + var json = JsonConvert.SerializeObject(date); + + // Assert - dates should be converted to UTC + Assert.Contains("\"start\":\"2023-05-15T12:30:45Z\"", json); // 14:30:45 +02:00 -> 12:30:45 UTC + Assert.Contains("\"end\":\"2023-05-20T21:45:00Z\"", json); // 16:45:00 -05:00 -> 21:45:00 UTC + } + + [Fact] + public void Deserialize_with_timezone_offset_preserves_utc() + { + // Arrange - API returns UTC dates + const string Json = "{\"start\":\"2023-05-15T12:30:45Z\",\"end\":\"2023-05-20T21:45:00Z\"}"; + + // Act + var result = JsonConvert.DeserializeObject(Json); + + // Assert + Assert.NotNull(result); + Assert.Equal(new DateTimeOffset(2023, 5, 15, 12, 30, 45, TimeSpan.Zero), result.Start); + Assert.Equal(new DateTimeOffset(2023, 5, 20, 21, 45, 0, TimeSpan.Zero), result.End); + Assert.True(result.IncludeTime); + } + + [Fact] + public void Round_trip_with_timezone_offsets_preserves_utc_equivalent() + { + // Arrange - date with timezone offset + var originalDate = new Date + { + Start = new DateTimeOffset(2024, 6, 26, 0, 0, 0, TimeSpan.FromHours(1)), // +01:00 offset + End = new DateTimeOffset(2025, 12, 8, 0, 0, 0, TimeSpan.Zero), // UTC + IncludeTime = true + }; + + // Act + var json = JsonConvert.SerializeObject(originalDate); + var deserializedDate = JsonConvert.DeserializeObject(json); + + // Assert - should preserve the UTC equivalent times + Assert.NotNull(deserializedDate); + // Start: 2024-06-26T00:00:00+01:00 -> 2024-06-25T23:00:00Z + Assert.Equal(new DateTimeOffset(2024, 6, 25, 23, 0, 0, TimeSpan.Zero), deserializedDate.Start); + Assert.Equal(new DateTimeOffset(2025, 12, 8, 0, 0, 0, TimeSpan.Zero), deserializedDate.End); + Assert.True(deserializedDate.IncludeTime); + } + + [Fact] + public void Serialize_date_only_without_time_uses_date_format() + { + // Arrange + var date = new Date + { + Start = new DateTimeOffset(2023, 5, 15, 14, 30, 45, TimeSpan.FromHours(2)), + End = new DateTimeOffset(2023, 5, 20, 16, 45, 0, TimeSpan.FromHours(-3)), + IncludeTime = false + }; + + // Act + var json = JsonConvert.SerializeObject(date); + + // Assert - should use date format (yyyy-MM-dd) regardless of timezone + Assert.Contains("\"start\":\"2023-05-15\"", json); + Assert.Contains("\"end\":\"2023-05-20\"", json); + } + + [Fact] + public void Deserialize_empty_start_string_returns_null_start() + { + // Arrange + const string Json = "{\"start\":\"\",\"end\":\"2023-05-20\"}"; + + // Act + var result = JsonConvert.DeserializeObject(Json); + + // Assert + Assert.NotNull(result); + Assert.Null(result.Start); + Assert.Equal(new DateTimeOffset(2023, 5, 20, 0, 0, 0, TimeSpan.Zero), result.End); + Assert.False(result.IncludeTime); // Should be false since Start is null + } + + [Fact] + public void Deserialize_with_space_separator_sets_include_time_flag() + { + // Arrange - some systems might use space instead of T + const string Json = "{\"start\":\"2023-05-15 14:30:45\"}"; + + // Act + var result = JsonConvert.DeserializeObject(Json); + + // Assert + Assert.NotNull(result); + Assert.Equal(new DateTimeOffset(2023, 5, 15, 14, 30, 45, TimeSpan.Zero), result.Start); + Assert.True(result.IncludeTime); + } + + [Fact] + public void Serialize_only_start_date_omits_end_property() + { + // Arrange + var date = new Date + { + Start = new DateTimeOffset(2023, 5, 15, 14, 30, 45, TimeSpan.Zero), + End = null, + IncludeTime = true + }; + + // Act + var json = JsonConvert.SerializeObject(date); + + // Assert + Assert.Contains("\"start\":\"2023-05-15T14:30:45Z\"", json); + Assert.DoesNotContain("\"end\":", json); + } + + [Fact] + public void Serialize_only_end_date_omits_start_property() + { + // Arrange + var date = new Date + { + Start = null, + End = new DateTimeOffset(2023, 5, 20, 16, 45, 0, TimeSpan.Zero), + IncludeTime = true + }; + + // Act + var json = JsonConvert.SerializeObject(date); + + // Assert + Assert.DoesNotContain("\"start\":", json); + Assert.Contains("\"end\":\"2023-05-20T16:45:00Z\"", json); + } + + [Fact] + public void Deserialize_with_only_end_time_sets_include_time_flag() + { + // Arrange - Only end date has time, start is date-only + const string Json = "{\"start\":\"2023-05-15\",\"end\":\"2023-05-20T16:45:00\"}"; + + // Act + var result = JsonConvert.DeserializeObject(Json); + + // Assert + Assert.NotNull(result); + Assert.Equal(new DateTimeOffset(2023, 5, 15, 0, 0, 0, TimeSpan.Zero), result.Start); + Assert.Equal(new DateTimeOffset(2023, 5, 20, 16, 45, 0, TimeSpan.Zero), result.End); + Assert.True(result.IncludeTime); // Should be true because End has time + } + + [Fact] + public void Deserialize_with_only_start_time_sets_include_time_flag() + { + // Arrange - Only start date has time, end is date-only + const string Json = "{\"start\":\"2023-05-15T14:30:00\",\"end\":\"2023-05-20\"}"; + + // Act + var result = JsonConvert.DeserializeObject(Json); + + // Assert + Assert.NotNull(result); + Assert.Equal(new DateTimeOffset(2023, 5, 15, 14, 30, 0, TimeSpan.Zero), result.Start); + Assert.Equal(new DateTimeOffset(2023, 5, 20, 0, 0, 0, TimeSpan.Zero), result.End); + Assert.True(result.IncludeTime); // Should be true because Start has time + } + + [Fact] + public void Deserialize_with_neither_start_nor_end_time_clears_include_time_flag() + { + // Arrange - Both dates are date-only + const string Json = "{\"start\":\"2023-05-15\",\"end\":\"2023-05-20\"}"; + + // Act + var result = JsonConvert.DeserializeObject(Json); + + // Assert + Assert.NotNull(result); + Assert.Equal(new DateTimeOffset(2023, 5, 15, 0, 0, 0, TimeSpan.Zero), result.Start); + Assert.Equal(new DateTimeOffset(2023, 5, 20, 0, 0, 0, TimeSpan.Zero), result.End); + Assert.False(result.IncludeTime); // Should be false because neither has time + } } diff --git a/Test/Notion.UnitTests/PagesClientTests.cs b/Test/Notion.UnitTests/PagesClientTests.cs index 4dc75380..4141d8a6 100644 --- a/Test/Notion.UnitTests/PagesClientTests.cs +++ b/Test/Notion.UnitTests/PagesClientTests.cs @@ -57,7 +57,7 @@ public async Task CreateAsync() ); var pagesCreateParameters = PagesCreateParametersBuilder - .Create(new DatabaseParentInput { DatabaseId = "3c357473-a281-49a4-88c0-10d2b245a589" }) + .Create(new DatabaseParentRequest { DatabaseId = "3c357473-a281-49a4-88c0-10d2b245a589" }) .AddProperty( "Name", new TitlePropertyValue @@ -258,7 +258,7 @@ public async Task CreateAsync_Throws_ArgumentNullException_When_Properties_Is_Mi { var pagesCreateParameters = new PagesCreateParameters { - Parent = new ParentPageInput { PageId = "3c357473-a281-49a4-88c0-10d2b245a589" }, + Parent = new PageParentRequest { PageId = "3c357473-a281-49a4-88c0-10d2b245a589" }, Properties = null }; diff --git a/Test/Notion.UnitTests/SearchClientTest.cs b/Test/Notion.UnitTests/SearchClientTest.cs index a5a477cb..6df62898 100644 --- a/Test/Notion.UnitTests/SearchClientTest.cs +++ b/Test/Notion.UnitTests/SearchClientTest.cs @@ -49,10 +49,7 @@ public async Task Search() results.Should().SatisfyRespectively( obj => { - obj.Object.Should().Be(ObjectType.Database); - - var database = (Database)obj; - database.Properties.Should().HaveCount(2); + obj.Object.Should().Be(ObjectType.DataSource); }, obj => { diff --git a/Test/Notion.UnitTests/UpdatePropertyConfigurationRequestConverterFactoryTests.cs b/Test/Notion.UnitTests/UpdatePropertyConfigurationRequestConverterFactoryTests.cs new file mode 100644 index 00000000..5307bc8e --- /dev/null +++ b/Test/Notion.UnitTests/UpdatePropertyConfigurationRequestConverterFactoryTests.cs @@ -0,0 +1,112 @@ +using System.Collections.Generic; +using Newtonsoft.Json; +using Notion.Client; +using Xunit; + +namespace Notion.UnitTests +{ + public class UpdatePropertyConfigurationRequestConverterFactoryTests + { + [Fact] + public void ConverterFactory_WithSelectProperty_ShouldSerializeCorrectly() + { + // Arrange + var request = new UpdatePropertyConfigurationRequest + { + Name = "Status", + PropertyRequest = new SelectPropertyConfigurationRequest + { + Description = "Task status", + Select = new SelectPropertyConfigurationRequest.SelectOptions + { + Options = new List + { + new SelectOptionRequest { Name = "Done", Color = "green" } + } + } + } + }; + + // Cast to non-generic interface to simulate real usage + IUpdatePropertyConfigurationRequest nonGenericRequest = request; + + // Act + var json = JsonConvert.SerializeObject(nonGenericRequest); + + // Assert + Assert.Contains("\"name\":\"Status\"", json); + Assert.Contains("\"description\":\"Task status\"", json); + Assert.Contains("\"select\"", json); + Assert.Contains("\"options\"", json); + Assert.Contains("\"Done\"", json); + Assert.Contains("\"green\"", json); + } + + [Fact] + public void ConverterFactory_WithTitleProperty_ShouldSerializeCorrectly() + { + // Arrange + var request = new UpdatePropertyConfigurationRequest + { + Name = "Task Name", + PropertyRequest = new TitlePropertyConfigurationRequest + { + Description = "Name of the task" + } + }; + + // Cast to non-generic interface to simulate real usage + IUpdatePropertyConfigurationRequest nonGenericRequest = request; + + // Act + var json = JsonConvert.SerializeObject(nonGenericRequest); + + // Assert + Assert.Contains("\"name\":\"Task Name\"", json); + Assert.Contains("\"description\":\"Name of the task\"", json); + Assert.Contains("\"title\"", json); + } + + [Fact] + public void ConverterFactory_WithDictionary_ShouldSerializeAllProperties() + { + // Arrange + var properties = new Dictionary + { + { + "Status", + new UpdatePropertyConfigurationRequest + { + Name = "Status", + PropertyRequest = new SelectPropertyConfigurationRequest + { + Description = "Task status" + } + } + }, + { + "Title", + new UpdatePropertyConfigurationRequest + { + Name = "Task Name", + PropertyRequest = new TitlePropertyConfigurationRequest + { + Description = "Name of the task" + } + } + } + }; + + // Act + var json = JsonConvert.SerializeObject(properties); + + // Assert + Assert.Contains("\"Status\"", json); + Assert.Contains("\"Title\"", json); + Assert.Contains("\"Task status\"", json); + Assert.Contains("\"Name of the task\"", json); + Assert.Contains("\"select\"", json); + Assert.Contains("\"title\"", json); + } + } +} \ No newline at end of file diff --git a/Test/Notion.UnitTests/UpdatePropertyConfigurationRequestSerializationTests.cs b/Test/Notion.UnitTests/UpdatePropertyConfigurationRequestSerializationTests.cs new file mode 100644 index 00000000..16d224b5 --- /dev/null +++ b/Test/Notion.UnitTests/UpdatePropertyConfigurationRequestSerializationTests.cs @@ -0,0 +1,237 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Notion.Client; +using Xunit; + +namespace Notion.UnitTests; + +public class UpdatePropertyConfigurationRequestSerializationTests +{ + private string SerializeRequest(UpdatePropertyConfigurationRequest request) where T : PropertyConfigurationRequest + { + // Use JsonConvert.SerializeObject directly - this should now work with our converter factory + return JsonConvert.SerializeObject(request); + } + + [Fact] + public void UpdatePropertyConfigurationRequest_Should_Flatten_PropertyRequest_Into_Parent_Object_Via_JsonConvert() + { + // Arrange + var request = new UpdatePropertyConfigurationRequest + { + Name = "Test Property Name", + PropertyRequest = new TitlePropertyConfigurationRequest + { + Type = "title", + Description = "Test description", + Title = new Dictionary + { + { "some_title_config", "value" } + } + } + }; + + // Act - Using JsonConvert.SerializeObject which automatically uses the JsonConverter attribute + var json = SerializeRequest(request); + + // Assert + Assert.Contains("\"name\":\"Test Property Name\"", json); + Assert.Contains("\"type\":\"title\"", json); + Assert.Contains("\"description\":\"Test description\"", json); + Assert.Contains("\"title\":{\"some_title_config\":\"value\"}", json); + + // Verify that PropertyRequest is not present as a separate property + Assert.DoesNotContain("\"PropertyRequest\"", json); + Assert.DoesNotContain("\"propertyRequest\"", json); + } + + [Fact] + public void UpdatePropertyConfigurationRequestConverter_Should_Serialize_Only_Name_When_PropertyRequest_Is_Null() + { + // Arrange + var request = new UpdatePropertyConfigurationRequest + { + Name = "Test Property Name", + PropertyRequest = null + }; + + // Act + var json = SerializeRequest(request); + + // Assert + Assert.Contains("\"name\":\"Test Property Name\"", json); + Assert.DoesNotContain("\"type\"", json); + Assert.DoesNotContain("\"description\"", json); + Assert.DoesNotContain("\"title\"", json); + Assert.DoesNotContain("\"PropertyRequest\"", json); + Assert.DoesNotContain("\"propertyRequest\"", json); + } + + [Fact] + public void UpdatePropertyConfigurationRequestConverter_Should_Serialize_Only_PropertyRequest_Fields_When_Name_Is_Null() + { + // Arrange + var request = new UpdatePropertyConfigurationRequest + { + Name = null, + PropertyRequest = new TitlePropertyConfigurationRequest + { + Type = "title", + Description = "Test description", + Title = new Dictionary + { + { "some_title_config", "value" } + } + } + }; + + // Act + var json = SerializeRequest(request); + + // Assert + Assert.DoesNotContain("\"name\"", json); + Assert.Contains("\"type\":\"title\"", json); + Assert.Contains("\"description\":\"Test description\"", json); + Assert.Contains("\"title\":{\"some_title_config\":\"value\"}", json); + Assert.DoesNotContain("\"PropertyRequest\"", json); + Assert.DoesNotContain("\"propertyRequest\"", json); + } + + [Fact] + public void UpdatePropertyConfigurationRequestConverter_Should_Serialize_Empty_Object_When_Both_Name_And_PropertyRequest_Are_Null() + { + // Arrange + var request = new UpdatePropertyConfigurationRequest + { + Name = null, + PropertyRequest = null + }; + + // Act + var json = SerializeRequest(request); + + // Assert + Assert.Equal("{}", json); + } + + [Fact] + public void UpdatePropertyConfigurationRequestConverter_Should_Flatten_Different_Property_Types() + { + // Test with CheckboxPropertyConfigurationRequest + var checkboxRequest = new UpdatePropertyConfigurationRequest + { + Name = "Checkbox Property", + PropertyRequest = new CheckboxPropertyConfigurationRequest + { + Type = "checkbox", + Description = "Checkbox description", + Checkbox = new Dictionary + { + { "checkbox_config", true } + } + } + }; + + var checkboxJson = SerializeRequest(checkboxRequest); + + Assert.Contains("\"name\":\"Checkbox Property\"", checkboxJson); + Assert.Contains("\"type\":\"checkbox\"", checkboxJson); + Assert.Contains("\"description\":\"Checkbox description\"", checkboxJson); + Assert.Contains("\"checkbox\":{\"checkbox_config\":true}", checkboxJson); + Assert.DoesNotContain("\"PropertyRequest\"", checkboxJson); + } + + [Fact] + public void UpdatePropertyConfigurationRequestConverter_Should_Handle_PropertyRequest_With_AdditionalData() + { + // Arrange + var request = new UpdatePropertyConfigurationRequest + { + Name = "Test Property", + PropertyRequest = new TitlePropertyConfigurationRequest + { + Type = "title", + Description = "Test description", + Title = new Dictionary + { + { "some_title_config", "value" } + }, + AdditionalData = new Dictionary + { + { "custom_field", "custom_value" }, + { "another_field", 42 } + } + } + }; + + // Act + var json = SerializeRequest(request); + + // Assert + Assert.Contains("\"name\":\"Test Property\"", json); + Assert.Contains("\"type\":\"title\"", json); + Assert.Contains("\"description\":\"Test description\"", json); + Assert.Contains("\"title\":{\"some_title_config\":\"value\"}", json); + Assert.Contains("\"custom_field\":\"custom_value\"", json); + Assert.Contains("\"another_field\":42", json); + Assert.DoesNotContain("\"PropertyRequest\"", json); + Assert.DoesNotContain("\"AdditionalData\"", json); + } + + [Fact] + public void UpdatePropertyConfigurationRequestConverter_Should_Handle_Complex_Property_Configuration() + { + // Test with UniqueIdPropertyConfigurationRequest which has nested objects + var request = new UpdatePropertyConfigurationRequest + { + Name = "Unique ID Property", + PropertyRequest = new UniqueIdPropertyConfigurationRequest + { + Type = "unique_id", + Description = "Unique ID description", + UniqueId = new UniqueIdPropertyConfigurationRequest.UniqueIdConfiguration + { + Prefix = "TEST-", + AdditionalData = new Dictionary + { + { "nested_field", "nested_value" } + } + } + } + }; + + // Act + var json = SerializeRequest(request); + + // Assert + Assert.Contains("\"name\":\"Unique ID Property\"", json); + Assert.Contains("\"type\":\"unique_id\"", json); + Assert.Contains("\"description\":\"Unique ID description\"", json); + Assert.Contains("\"unique_id\":", json); + Assert.Contains("\"prefix\":\"TEST-\"", json); + Assert.Contains("\"nested_field\":\"nested_value\"", json); + Assert.DoesNotContain("\"PropertyRequest\"", json); + } + + [Fact] + public void UpdatePropertyConfigurationRequestConverter_Should_Not_Support_Reading() + { + // Arrange + var converter = new UpdatePropertyConfigurationRequestConverter(); + + // Act & Assert + Assert.False(converter.CanRead); + } + + [Fact] + public void UpdatePropertyConfigurationRequestConverter_ReadJson_Should_Throw_NotImplementedException() + { + // Arrange + var converter = new UpdatePropertyConfigurationRequestConverter(); + + // Act & Assert + Assert.Throws(() => + converter.ReadJson(null, typeof(UpdatePropertyConfigurationRequest), null, false, new JsonSerializer())); + } +} diff --git a/Test/Notion.UnitTests/data/databases/CreateDatabaseResponse.json b/Test/Notion.UnitTests/data/databases/CreateDatabaseResponse.json deleted file mode 100644 index 62450560..00000000 --- a/Test/Notion.UnitTests/data/databases/CreateDatabaseResponse.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "object": "database", - "id": "1e9eee34-9c5c-4fe6-a4e1-8244eb141ed8", - "created_time": "2021-08-18T17:39:00.000Z", - "last_edited_time": "2021-08-18T17:39:00.000Z", - "title": [ - { - "type": "text", - "text": { - "content": "Grocery List", - "link": null - }, - "annotations": { - "bold": false, - "italic": false, - "strikethrough": false, - "underline": false, - "code": false, - "color": "default" - }, - "plain_text": "Grocery List", - "href": null - } - ], - "properties": { - "Price": { - "id": "@xZm", - "name": "Price", - "type": "number", - "number": { - "format": "dollar" - } - }, - "Last ordered": { - "id": "SN;?", - "name": "Last ordered", - "type": "date", - "date": {} - }, - "Food group": { - "id": "zIZQ", - "name": "Food group", - "type": "select", - "select": { - "options": [ - { - "id": "49ca815e-c37a-4dce-9033-32a62233f483", - "name": "🥦Vegetable", - "color": "green" - }, - { - "id": "9fa8d118-59fb-47c7-b4c7-a8523609e37f", - "name": "🍎Fruit", - "color": "red" - }, - { - "id": "ef3c69d2-0cd1-4540-82fd-03ff9650fc44", - "name": "💪Protein", - "color": "yellow" - } - ] - } - }, - "Name": { - "id": "title", - "name": "Name", - "type": "title", - "title": {} - } - }, - "parent": { - "type": "page_id", - "page_id": "533578e3-edf1-4c0a-91a9-da6b09bac3ee" - } -} \ No newline at end of file diff --git a/Test/Notion.UnitTests/data/databases/DatabasePropertyObjectContainNameProperty.json b/Test/Notion.UnitTests/data/databases/DatabasePropertyObjectContainNameProperty.json deleted file mode 100644 index 2951f5f3..00000000 --- a/Test/Notion.UnitTests/data/databases/DatabasePropertyObjectContainNameProperty.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "object": "database", - "id": "f0212efc-caf6-4afc-87f6-1c06f1dfc8a1", - "created_time": "2021-05-22T18:44:00.000Z", - "last_edited_time": "2021-05-23T12:29:00.000Z", - "title": [ - { - "type": "text", - "text": { - "content": "sample table", - "link": null - }, - "annotations": { - "bold": false, - "italic": false, - "strikethrough": false, - "underline": false, - "code": false, - "color": "default" - }, - "plain_text": "sample table", - "href": null - } - ], - "properties": { - "Tags": { - "id": "YG~h", - "name": "Tags", - "type": "multi_select", - "multi_select": { - "options": [] - } - }, - "SimpleText": { - "id": "_Dfp", - "name": "SimpleText", - "type": "rich_text", - "rich_text": {} - }, - "Column": { - "id": "bxhl", - "name": "Column", - "type": "multi_select", - "multi_select": { - "options": [ - { - "id": "5a44a233-33be-435e-b358-2c0ed1799dcf", - "name": "what", - "color": "gray" - } - ] - } - }, - "SelectProp": { - "id": "eZ[y", - "name": "SelectProp", - "type": "select", - "select": { - "options": [ - { - "id": "362dc255-c867-4543-b3ea-7bd988638228", - "name": "Female", - "color": "green" - } - ] - } - }, - "Property": { - "id": "zDGa", - "name": "Property", - "type": "relation", - "relation": { - "database_id": "f86f2262-0751-40f2-8f63-e3f7a3c39fcb", - "type": "dual_property", - "dual_property": { - "synced_property_name": "Related to sample table (Property)", - "synced_property_id": "VQ}{" - } - } - }, - "Name": { - "id": "title", - "name": "Name", - "type": "title", - "title": {} - } - }, - "parent": { - "type": "page_id", - "page_id": "649089db-8984-4051-98fb-a03593b852d8" - } -} diff --git a/Test/Notion.UnitTests/data/databases/DatabasePropertyObjectContainParentProperty.json b/Test/Notion.UnitTests/data/databases/DatabasePropertyObjectContainParentProperty.json deleted file mode 100644 index 2951f5f3..00000000 --- a/Test/Notion.UnitTests/data/databases/DatabasePropertyObjectContainParentProperty.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "object": "database", - "id": "f0212efc-caf6-4afc-87f6-1c06f1dfc8a1", - "created_time": "2021-05-22T18:44:00.000Z", - "last_edited_time": "2021-05-23T12:29:00.000Z", - "title": [ - { - "type": "text", - "text": { - "content": "sample table", - "link": null - }, - "annotations": { - "bold": false, - "italic": false, - "strikethrough": false, - "underline": false, - "code": false, - "color": "default" - }, - "plain_text": "sample table", - "href": null - } - ], - "properties": { - "Tags": { - "id": "YG~h", - "name": "Tags", - "type": "multi_select", - "multi_select": { - "options": [] - } - }, - "SimpleText": { - "id": "_Dfp", - "name": "SimpleText", - "type": "rich_text", - "rich_text": {} - }, - "Column": { - "id": "bxhl", - "name": "Column", - "type": "multi_select", - "multi_select": { - "options": [ - { - "id": "5a44a233-33be-435e-b358-2c0ed1799dcf", - "name": "what", - "color": "gray" - } - ] - } - }, - "SelectProp": { - "id": "eZ[y", - "name": "SelectProp", - "type": "select", - "select": { - "options": [ - { - "id": "362dc255-c867-4543-b3ea-7bd988638228", - "name": "Female", - "color": "green" - } - ] - } - }, - "Property": { - "id": "zDGa", - "name": "Property", - "type": "relation", - "relation": { - "database_id": "f86f2262-0751-40f2-8f63-e3f7a3c39fcb", - "type": "dual_property", - "dual_property": { - "synced_property_name": "Related to sample table (Property)", - "synced_property_id": "VQ}{" - } - } - }, - "Name": { - "id": "title", - "name": "Name", - "type": "title", - "title": {} - } - }, - "parent": { - "type": "page_id", - "page_id": "649089db-8984-4051-98fb-a03593b852d8" - } -} diff --git a/Test/Notion.UnitTests/data/databases/DatabasePropertyObjectContainRelation.json b/Test/Notion.UnitTests/data/databases/DatabasePropertyObjectContainRelation.json deleted file mode 100644 index 2951f5f3..00000000 --- a/Test/Notion.UnitTests/data/databases/DatabasePropertyObjectContainRelation.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "object": "database", - "id": "f0212efc-caf6-4afc-87f6-1c06f1dfc8a1", - "created_time": "2021-05-22T18:44:00.000Z", - "last_edited_time": "2021-05-23T12:29:00.000Z", - "title": [ - { - "type": "text", - "text": { - "content": "sample table", - "link": null - }, - "annotations": { - "bold": false, - "italic": false, - "strikethrough": false, - "underline": false, - "code": false, - "color": "default" - }, - "plain_text": "sample table", - "href": null - } - ], - "properties": { - "Tags": { - "id": "YG~h", - "name": "Tags", - "type": "multi_select", - "multi_select": { - "options": [] - } - }, - "SimpleText": { - "id": "_Dfp", - "name": "SimpleText", - "type": "rich_text", - "rich_text": {} - }, - "Column": { - "id": "bxhl", - "name": "Column", - "type": "multi_select", - "multi_select": { - "options": [ - { - "id": "5a44a233-33be-435e-b358-2c0ed1799dcf", - "name": "what", - "color": "gray" - } - ] - } - }, - "SelectProp": { - "id": "eZ[y", - "name": "SelectProp", - "type": "select", - "select": { - "options": [ - { - "id": "362dc255-c867-4543-b3ea-7bd988638228", - "name": "Female", - "color": "green" - } - ] - } - }, - "Property": { - "id": "zDGa", - "name": "Property", - "type": "relation", - "relation": { - "database_id": "f86f2262-0751-40f2-8f63-e3f7a3c39fcb", - "type": "dual_property", - "dual_property": { - "synced_property_name": "Related to sample table (Property)", - "synced_property_id": "VQ}{" - } - } - }, - "Name": { - "id": "title", - "name": "Name", - "type": "title", - "title": {} - } - }, - "parent": { - "type": "page_id", - "page_id": "649089db-8984-4051-98fb-a03593b852d8" - } -} diff --git a/Test/Notion.UnitTests/data/databases/DatabaseRetrieveResponse.json b/Test/Notion.UnitTests/data/databases/DatabaseRetrieveResponse.json deleted file mode 100644 index 9e1acfb0..00000000 --- a/Test/Notion.UnitTests/data/databases/DatabaseRetrieveResponse.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "object": "database", - "id": "f0212efc-caf6-4afc-87f6-1c06f1dfc8a1", - "created_time": "2021-05-22T18:44:00.000Z", - "last_edited_time": "2021-05-23T12:29:00.000Z", - "title": [ - { - "type": "text", - "text": { - "content": "sample table", - "link": null - }, - "annotations": { - "bold": false, - "italic": false, - "strikethrough": false, - "underline": false, - "code": false, - "color": "default" - }, - "plain_text": "sample table", - "href": null - } - ], - "icon": { - "type": "emoji", - "emoji": "🎉" - }, - "cover": { - "type": "external", - "external": { - "url": "https://website.domain/images/image.png" - } - }, - "url": "https://www.notion.so/668d797c76fa49349b05ad288df2d136", - "in_trash" : false, - "properties": { - "Tags": { - "id": "YG~h", - "name": "Tags", - "type": "multi_select", - "multi_select": { - "options": [] - } - }, - "SimpleText": { - "id": "_Dfp", - "name": "SimpleText", - "type": "rich_text", - "rich_text": {} - }, - "Column": { - "id": "bxhl", - "name": "Column", - "type": "multi_select", - "multi_select": { - "options": [ - { - "id": "5a44a233-33be-435e-b358-2c0ed1799dcf", - "name": "what", - "color": "gray" - } - ] - } - }, - "SelectProp": { - "id": "eZ[y", - "name": "SelectProp", - "type": "select", - "select": { - "options": [ - { - "id": "362dc255-c867-4543-b3ea-7bd988638228", - "name": "Female", - "color": "green" - } - ] - } - }, - "Property": { - "id": "zDGa", - "name": "Property", - "type": "relation", - "relation": { - "database_id": "f86f2262-0751-40f2-8f63-e3f7a3c39fcb", - "type": "dual_property", - "dual_property": { - "synced_property_name": "Related to sample table (Property)", - "synced_property_id": "VQ}{" - } - } - }, - "SimpleButton": { - "id":"_ri%7C", - "name":"SimpleButton", - "type":"button", - "button": {} - }, - "Name": { - "id": "title", - "name": "Name", - "type": "title", - "title": {} - } - }, - "parent": { - "type": "page_id", - "page_id": "649089db-8984-4051-98fb-a03593b852d8" - } -} diff --git a/Test/Notion.UnitTests/data/databases/DatabasesListResponse.json b/Test/Notion.UnitTests/data/databases/DatabasesListResponse.json deleted file mode 100644 index ad0e5497..00000000 --- a/Test/Notion.UnitTests/data/databases/DatabasesListResponse.json +++ /dev/null @@ -1,228 +0,0 @@ -{ - "object": "list", - "results": [ - { - "object": "database", - "id": "f0212efc-caf6-4afc-87f6-1c06f1dfc8a1", - "created_time": "2021-05-22T18:44:00.000Z", - "last_edited_time": "2021-05-23T12:29:00.000Z", - "title": [ - { - "type": "text", - "text": { - "content": "sample table", - "link": null - }, - "annotations": { - "bold": false, - "italic": false, - "strikethrough": false, - "underline": false, - "code": false, - "color": "default" - }, - "plain_text": "sample table", - "href": null - } - ], - "properties": { - "Tags": { - "id": "YG~h", - "name": "Tags", - "type": "multi_select", - "multi_select": { - "options": [] - } - }, - "SimpleText": { - "id": "_Dfp", - "name": "SimpleText", - "type": "rich_text", - "rich_text": {} - }, - "Column": { - "id": "bxhl", - "name": "Column", - "type": "multi_select", - "multi_select": { - "options": [ - { - "id": "5a44a233-33be-435e-b358-2c0ed1799dcf", - "name": "what", - "color": "gray" - } - ] - } - }, - "SelectProp": { - "id": "eZ[y", - "name": "SelectProp", - "type": "select", - "select": { - "options": [ - { - "id": "362dc255-c867-4543-b3ea-7bd988638228", - "name": "Female", - "color": "green" - } - ] - } - }, - "Property": { - "id": "zDGa", - "name": "Property", - "type": "relation", - "relation": { - "database_id": "f86f2262-0751-40f2-8f63-e3f7a3c39fcb", - "type": "dual_property", - "dual_property": { - "synced_property_name": "Related to sample table (Property)", - "synced_property_id": "VQ}{" - } - } - }, - "SimpleButton": { - "id":"_ri%7C", - "name":"SimpleButton", - "type":"button", - "button": {} - }, - "Name": { - "id": "title", - "name": "Name", - "type": "title", - "title": {} - } - }, - "parent": { - "type": "page_id", - "page_id": "649089db-8984-4051-98fb-a03593b852d8" - } - }, - { - "object": "database", - "id": "b38b2eed-282c-40f2-b454-cae5d882fef5", - "created_time": "2021-05-22T18:43:00.000Z", - "last_edited_time": "2021-05-22T18:43:00.000Z", - "title": [], - "properties": { - "Created": { - "id": "?uvZ", - "name": "Created", - "type": "created_time", - "created_time": {} - }, - "Tags": { - "id": "{>_o", - "name": "Tags", - "type": "multi_select", - "multi_select": { - "options": [] - } - }, - "Name": { - "id": "title", - "name": "Name", - "type": "title", - "title": {} - } - }, - "parent": { - "type": "page_id", - "page_id": "649089db-8984-4051-98fb-a03593b852d8" - } - }, - { - "object": "database", - "id": "f86f2262-0751-40f2-8f63-e3f7a3c39fcb", - "created_time": "2021-05-22T18:30:00.000Z", - "last_edited_time": "2021-06-02T18:32:00.000Z", - "title": [ - { - "type": "text", - "text": { - "content": "SampleDB", - "link": null - }, - "annotations": { - "bold": false, - "italic": false, - "strikethrough": false, - "underline": false, - "code": false, - "color": "default" - }, - "plain_text": "SampleDB", - "href": null - } - ], - "properties": { - "Property": { - "id": "CfU;", - "type": "checkbox", - "checkbox": false - }, - "Add Page Button": { - "id":"_ri%7C", - "type":"button", - "button": {} - } - } - } - ], - "has_more": false, - "next_cursor": null -} diff --git a/Test/Notion.UnitTests/data/databases/Fix123QueryAsyncDateFormulaValueReturnsNullResponse.json b/Test/Notion.UnitTests/data/databases/Fix123QueryAsyncDateFormulaValueReturnsNullResponse.json deleted file mode 100644 index 00159d76..00000000 --- a/Test/Notion.UnitTests/data/databases/Fix123QueryAsyncDateFormulaValueReturnsNullResponse.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "object": "list", - "results": [ - { - "object": "page", - "id": "50b4321c-afc1-4468-b278-5a578643989c", - "created_time": "2021-05-22T18:30:00.000Z", - "last_edited_time": "2021-09-09T05:49:00.000Z", - "cover": null, - "icon": null, - "parent": { - "type": "database_id", - "database_id": "f86f2262-0751-40f2-8f63-e3f7a3c39fcb" - }, - "in_trash": false, - "properties": { - "Column": { - "id": "B[\\E", - "type": "rollup", - "rollup": { - "type": "array", - "array": [] - } - }, - "Property": { - "id": "Cf