diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..d6fab627 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "Newtonsoft" + ] +} \ No newline at end of file diff --git a/Src/Notion.Client/Api/ApiEndpoints.cs b/Src/Notion.Client/Api/ApiEndpoints.cs index 300c2482..07a26a68 100644 --- a/Src/Notion.Client/Api/ApiEndpoints.cs +++ b/Src/Notion.Client/Api/ApiEndpoints.cs @@ -148,5 +148,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/BlocksClient.cs b/Src/Notion.Client/Api/Blocks/BlocksClient.cs index 92713a78..cf0f5657 100644 --- a/Src/Notion.Client/Api/Blocks/BlocksClient.cs +++ b/Src/Notion.Client/Api/Blocks/BlocksClient.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using static Notion.Client.ApiEndpoints; diff --git a/Src/Notion.Client/Api/Blocks/RequestParams/BlocksUpdateParameters/UpdateBlocks/CalloutUpdateBlock.cs b/Src/Notion.Client/Api/Blocks/RequestParams/BlocksUpdateParameters/UpdateBlocks/CalloutUpdateBlock.cs index f4489ff8..1bc203d8 100644 --- a/Src/Notion.Client/Api/Blocks/RequestParams/BlocksUpdateParameters/UpdateBlocks/CalloutUpdateBlock.cs +++ b/Src/Notion.Client/Api/Blocks/RequestParams/BlocksUpdateParameters/UpdateBlocks/CalloutUpdateBlock.cs @@ -14,7 +14,7 @@ public class Info public IEnumerable RichText { get; set; } [JsonProperty("icon")] - public IPageIcon Icon { get; set; } + public IPageIconRequest Icon { get; set; } } } } 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/Comments/Create/CommentsClient.cs b/Src/Notion.Client/Api/Comments/Create/CommentsClient.cs index ac2244ea..6ab3c7c2 100644 --- a/Src/Notion.Client/Api/Comments/Create/CommentsClient.cs +++ b/Src/Notion.Client/Api/Comments/Create/CommentsClient.cs @@ -5,11 +5,11 @@ namespace Notion.Client { public partial class CommentsClient { - public async Task CreateAsync(CreateCommentParameters parameters, CancellationToken cancellationToken = default) + public async Task CreateAsync(CreateCommentRequest parameters, CancellationToken cancellationToken = default) { var body = (ICreateCommentsBodyParameters)parameters; - return await _client.PostAsync( + return await _client.PostAsync( ApiEndpoints.CommentsApiUrls.Create(), body, cancellationToken: cancellationToken diff --git a/Src/Notion.Client/Api/Comments/Create/Request/CreateCommentParameters.cs b/Src/Notion.Client/Api/Comments/Create/Request/CreateCommentParameters.cs deleted file mode 100644 index f9532726..00000000 --- a/Src/Notion.Client/Api/Comments/Create/Request/CreateCommentParameters.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public interface ICreateCommentsBodyParameters - { - [JsonProperty("rich_text")] - public IEnumerable RichText { get; set; } - } - - public interface ICreateDiscussionCommentBodyParameters : ICreateCommentsBodyParameters - { - [JsonProperty("discussion_id")] - public string DiscussionId { get; set; } - } - - public interface ICreatePageCommentBodyParameters : ICreateCommentsBodyParameters - { - [JsonProperty("parent")] - public ParentPageInput Parent { get; set; } - } - - public class CreateCommentParameters : ICreateDiscussionCommentBodyParameters, ICreatePageCommentBodyParameters - { - public string DiscussionId { get; set; } - - public IEnumerable RichText { get; set; } - - public ParentPageInput Parent { get; set; } - - public static CreateCommentParameters CreatePageComment( - ParentPageInput parent, - IEnumerable richText) - { - return new CreateCommentParameters - { - Parent = parent, - RichText = richText - }; - } - - public static CreateCommentParameters CreateDiscussionComment( - string discussionId, - IEnumerable richText) - { - return new CreateCommentParameters - { - DiscussionId = discussionId, - RichText = richText - }; - } - } -} diff --git a/Src/Notion.Client/Api/Comments/Create/Request/CreateCommentRequest.cs b/Src/Notion.Client/Api/Comments/Create/Request/CreateCommentRequest.cs new file mode 100644 index 00000000..44cd5b2b --- /dev/null +++ b/Src/Notion.Client/Api/Comments/Create/Request/CreateCommentRequest.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; + +namespace Notion.Client +{ + public class CreateCommentRequest : ICreateDiscussionCommentBodyParameters, ICreatePageCommentBodyParameters + { + public string DiscussionId { get; set; } + + public IEnumerable RichText { get; set; } + + public ParentPageInput Parent { get; set; } + + public static CreateCommentRequest CreatePageComment( + ParentPageInput parent, + IEnumerable richText) + { + return new CreateCommentRequest + { + Parent = parent, + RichText = richText + }; + } + + public static CreateCommentRequest CreateDiscussionComment( + string discussionId, + IEnumerable richText) + { + return new CreateCommentRequest + { + DiscussionId = discussionId, + RichText = richText + }; + } + } +} diff --git a/Src/Notion.Client/Api/Comments/Create/Request/ICreateCommentsBodyParameters.cs b/Src/Notion.Client/Api/Comments/Create/Request/ICreateCommentsBodyParameters.cs new file mode 100644 index 00000000..22be43cd --- /dev/null +++ b/Src/Notion.Client/Api/Comments/Create/Request/ICreateCommentsBodyParameters.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface ICreateCommentsBodyParameters + { + [JsonProperty("rich_text")] + public IEnumerable RichText { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Comments/Create/Request/ICreateDiscussionCommentBodyParameters.cs b/Src/Notion.Client/Api/Comments/Create/Request/ICreateDiscussionCommentBodyParameters.cs new file mode 100644 index 00000000..c3a60045 --- /dev/null +++ b/Src/Notion.Client/Api/Comments/Create/Request/ICreateDiscussionCommentBodyParameters.cs @@ -0,0 +1,10 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface ICreateDiscussionCommentBodyParameters : ICreateCommentsBodyParameters + { + [JsonProperty("discussion_id")] + public string DiscussionId { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Comments/Create/Request/ICreatePageCommentBodyParameters.cs b/Src/Notion.Client/Api/Comments/Create/Request/ICreatePageCommentBodyParameters.cs new file mode 100644 index 00000000..b2e35725 --- /dev/null +++ b/Src/Notion.Client/Api/Comments/Create/Request/ICreatePageCommentBodyParameters.cs @@ -0,0 +1,10 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface ICreatePageCommentBodyParameters : ICreateCommentsBodyParameters + { + [JsonProperty("parent")] + public ParentPageInput Parent { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Comments/Create/Response/CreateCommentResponse.cs b/Src/Notion.Client/Api/Comments/Create/Response/CreateCommentResponse.cs deleted file mode 100644 index 0171d92d..00000000 --- a/Src/Notion.Client/Api/Comments/Create/Response/CreateCommentResponse.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace Notion.Client -{ - [SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")] - public class CreateCommentResponse : Comment - { - } -} diff --git a/Src/Notion.Client/Api/Comments/ICommentsClient.cs b/Src/Notion.Client/Api/Comments/ICommentsClient.cs index 7b7af943..b90f86d5 100644 --- a/Src/Notion.Client/Api/Comments/ICommentsClient.cs +++ b/Src/Notion.Client/Api/Comments/ICommentsClient.cs @@ -5,8 +5,8 @@ namespace Notion.Client { public interface ICommentsClient { - Task CreateAsync(CreateCommentParameters createCommentParameters, CancellationToken cancellationToken = default); + Task CreateAsync(CreateCommentRequest createCommentParameters, CancellationToken cancellationToken = default); - Task RetrieveAsync(RetrieveCommentsParameters parameters, CancellationToken cancellationToken = default); + Task RetrieveAsync(RetrieveCommentsRequest parameters, CancellationToken cancellationToken = default); } } diff --git a/Src/Notion.Client/Api/Comments/Retrieve/CommentsClient.cs b/Src/Notion.Client/Api/Comments/Retrieve/CommentsClient.cs index 45c64f00..e8203f02 100644 --- a/Src/Notion.Client/Api/Comments/Retrieve/CommentsClient.cs +++ b/Src/Notion.Client/Api/Comments/Retrieve/CommentsClient.cs @@ -8,7 +8,7 @@ namespace Notion.Client public partial class CommentsClient { [SuppressMessage("ReSharper", "UnusedMember.Global")] - public async Task RetrieveAsync(RetrieveCommentsParameters parameters, CancellationToken cancellationToken = default) + public async Task RetrieveAsync(RetrieveCommentsRequest parameters, CancellationToken cancellationToken = default) { var qp = (IRetrieveCommentsQueryParameters)parameters; diff --git a/Src/Notion.Client/Api/Comments/Retrieve/Request/RetrieveCommentsParameters.cs b/Src/Notion.Client/Api/Comments/Retrieve/Request/RetrieveCommentsParameters.cs deleted file mode 100644 index 25d3d54d..00000000 --- a/Src/Notion.Client/Api/Comments/Retrieve/Request/RetrieveCommentsParameters.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace Notion.Client -{ - [SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")] - public class RetrieveCommentsParameters : IRetrieveCommentsQueryParameters - { - public string BlockId { get; set; } - - public string StartCursor { get; set; } - - public int? PageSize { get; set; } - } -} diff --git a/Src/Notion.Client/Api/Comments/Retrieve/Request/RetrieveCommentsRequest.cs b/Src/Notion.Client/Api/Comments/Retrieve/Request/RetrieveCommentsRequest.cs new file mode 100644 index 00000000..8dce942f --- /dev/null +++ b/Src/Notion.Client/Api/Comments/Retrieve/Request/RetrieveCommentsRequest.cs @@ -0,0 +1,11 @@ +namespace Notion.Client +{ + public class RetrieveCommentsRequest : IRetrieveCommentsQueryParameters + { + public string BlockId { get; set; } + + public string StartCursor { get; set; } + + public int? PageSize { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Comments/Retrieve/Response/Comments.cs b/Src/Notion.Client/Api/Comments/Retrieve/Response/RetrieveCommentsResponse.cs similarity index 100% rename from Src/Notion.Client/Api/Comments/Retrieve/Response/Comments.cs rename to Src/Notion.Client/Api/Comments/Retrieve/Response/RetrieveCommentsResponse.cs 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..2267a299 --- /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 + ); + } + } +} 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..b93fde90 --- /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..a9ab142e --- /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/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..a421e46b --- /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/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..c2dd5f4a --- /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(DataSource), ObjectType.DataSource)] + 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..6635e6fc --- /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/Update/DataSourcesClient.cs b/Src/Notion.Client/Api/DataSources/Update/DataSourcesClient.cs new file mode 100644 index 00000000..f0c9cccb --- /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 + ); + } + } +} 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..f4305eb8 --- /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 : DataSourcePropertyConfigRequest + { + [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..388269f7 --- /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 : DataSourcePropertyConfigRequest + { + 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..00de46c2 --- /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(DataSourcePropertyConfigRequest).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/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..3b2e419f --- /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 IPageCoverRequest 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..ad0a670e --- /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 IPageCoverRequest 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/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/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..cd58b896 --- /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 IPageIconRequest Icon { get; set; } + + public IPageCoverRequest 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..2a9f92a1 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/IDatabasesUpdateBodyParameters.cs +++ b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/IDatabasesUpdateBodyParameters.cs @@ -5,25 +5,28 @@ namespace Notion.Client { public interface IDatabasesUpdateBodyParameters { - [JsonProperty("properties")] - Dictionary Properties { get; set; } + [JsonProperty("parent")] + IParentOfDatabaseRequest Parent { get; set; } [JsonProperty("title")] List Title { get; set; } [JsonProperty("icon")] - IPageIcon Icon { get; set; } + IPageIconRequest Icon { get; set; } [JsonProperty("cover")] - FileObject Cover { get; set; } + IPageCoverRequest 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/CheckboxUpdatePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CheckboxUpdatePropertySchema.cs deleted file mode 100644 index a6890d6e..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CheckboxUpdatePropertySchema.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class CheckboxUpdatePropertySchema : UpdatePropertySchema - { - [JsonProperty("checkbox")] - public Dictionary Checkbox { 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/RollupConfigUpdatePropertySchema.cs b/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RollupConfigUpdatePropertySchema.cs deleted file mode 100644 index 8ee2d908..00000000 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RollupConfigUpdatePropertySchema.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class RollupConfigUpdatePropertySchema : UpdatePropertySchema - { - [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/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/FileUploads/Complete/FileUploads.cs b/Src/Notion.Client/Api/FileUploads/Complete/FileUploads.cs index b1fb108d..f7c6de01 100644 --- a/Src/Notion.Client/Api/FileUploads/Complete/FileUploads.cs +++ b/Src/Notion.Client/Api/FileUploads/Complete/FileUploads.cs @@ -6,7 +6,7 @@ namespace Notion.Client { public sealed partial class FileUploadsClient { - public async Task CompleteAsync( + public async Task CompleteAsync( CompleteFileUploadRequest completeFileUploadRequest, CancellationToken cancellationToken = default) { @@ -22,7 +22,7 @@ public async Task CompleteAsync( var path = ApiEndpoints.FileUploadsApiUrls.Complete(completeFileUploadRequest.FileUploadId); - return await _restClient.PostAsync( + return await _restClient.PostAsync( path, body: null, cancellationToken: cancellationToken diff --git a/Src/Notion.Client/Api/FileUploads/Complete/Response/CompleteFileUploadResponse.cs b/Src/Notion.Client/Api/FileUploads/Complete/Response/CompleteFileUploadResponse.cs deleted file mode 100644 index 317642e9..00000000 --- a/Src/Notion.Client/Api/FileUploads/Complete/Response/CompleteFileUploadResponse.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Notion.Client -{ - public class CompleteFileUploadResponse : FileObjectResponse - { - } -} diff --git a/Src/Notion.Client/Api/FileUploads/Create/FileUploadsClient.cs b/Src/Notion.Client/Api/FileUploads/Create/FileUploadsClient.cs index f60e22cc..bf8f5d91 100644 --- a/Src/Notion.Client/Api/FileUploads/Create/FileUploadsClient.cs +++ b/Src/Notion.Client/Api/FileUploads/Create/FileUploadsClient.cs @@ -4,9 +4,9 @@ namespace Notion.Client { - public sealed partial class FileUploadsClient : IFileUploadsClient + public sealed partial class FileUploadsClient { - public async Task CreateAsync( + public async Task CreateAsync( CreateFileUploadRequest fileUploadObjectRequest, CancellationToken cancellationToken = default) { @@ -17,7 +17,7 @@ public async Task CreateAsync( ICreateFileUploadBodyParameters body = fileUploadObjectRequest; - return await _restClient.PostAsync( + return await _restClient.PostAsync( ApiEndpoints.FileUploadsApiUrls.Create(), body, cancellationToken: cancellationToken diff --git a/Src/Notion.Client/Api/FileUploads/Create/Response/CreateFileUploadResponse.cs b/Src/Notion.Client/Api/FileUploads/Create/Response/CreateFileUploadResponse.cs deleted file mode 100644 index 13fbc105..00000000 --- a/Src/Notion.Client/Api/FileUploads/Create/Response/CreateFileUploadResponse.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Notion.Client -{ - public class CreateFileUploadResponse : FileObjectResponse - { - } -} diff --git a/Src/Notion.Client/Api/FileUploads/IFileUploadsClient.cs b/Src/Notion.Client/Api/FileUploads/IFileUploadsClient.cs index 21450db2..2109ae9b 100644 --- a/Src/Notion.Client/Api/FileUploads/IFileUploadsClient.cs +++ b/Src/Notion.Client/Api/FileUploads/IFileUploadsClient.cs @@ -11,7 +11,7 @@ public interface IFileUploadsClient /// /// /// - Task CreateAsync( + Task CreateAsync( CreateFileUploadRequest fileUploadObjectRequest, CancellationToken cancellationToken = default ); @@ -25,7 +25,7 @@ Task CreateAsync( /// /// /// - Task SendAsync( + Task SendAsync( SendFileUploadRequest sendFileUploadRequest, CancellationToken cancellationToken = default ); @@ -36,7 +36,7 @@ Task SendAsync( /// /// /// - Task CompleteAsync( + Task CompleteAsync( CompleteFileUploadRequest completeFileUploadRequest, CancellationToken cancellationToken = default ); @@ -58,9 +58,9 @@ Task ListAsync( /// /// /// - Task RetrieveAsync( + Task RetrieveAsync( RetrieveFileUploadRequest request, CancellationToken cancellationToken = default ); } -} \ No newline at end of file +} diff --git a/Src/Notion.Client/Api/FileUploads/List/Response/ListFileUploadsResponse.cs b/Src/Notion.Client/Api/FileUploads/List/Response/ListFileUploadsResponse.cs index 581c80f8..8f9d208d 100644 --- a/Src/Notion.Client/Api/FileUploads/List/Response/ListFileUploadsResponse.cs +++ b/Src/Notion.Client/Api/FileUploads/List/Response/ListFileUploadsResponse.cs @@ -3,7 +3,7 @@ namespace Notion.Client { - public class ListFileUploadsResponse : PaginatedList + public class ListFileUploadsResponse : PaginatedList { [JsonProperty("file_uploads")] public Dictionary FileUploads { get; set; } diff --git a/Src/Notion.Client/Api/FileUploads/Retrieve/FileUploadsClient.cs b/Src/Notion.Client/Api/FileUploads/Retrieve/FileUploadsClient.cs index ea30cd45..744786b8 100644 --- a/Src/Notion.Client/Api/FileUploads/Retrieve/FileUploadsClient.cs +++ b/Src/Notion.Client/Api/FileUploads/Retrieve/FileUploadsClient.cs @@ -6,7 +6,7 @@ namespace Notion.Client { public sealed partial class FileUploadsClient { - public async Task RetrieveAsync( + public async Task RetrieveAsync( RetrieveFileUploadRequest request, CancellationToken cancellationToken = default) { @@ -19,7 +19,7 @@ public async Task RetrieveAsync( var endpoint = ApiEndpoints.FileUploadsApiUrls.Retrieve(pathParameters); - return await _restClient.GetAsync( + return await _restClient.GetAsync( endpoint, cancellationToken: cancellationToken ); diff --git a/Src/Notion.Client/Api/FileUploads/Retrieve/Response/RetrieveFileUploadResponse.cs b/Src/Notion.Client/Api/FileUploads/Retrieve/Response/RetrieveFileUploadResponse.cs deleted file mode 100644 index 38bdd01b..00000000 --- a/Src/Notion.Client/Api/FileUploads/Retrieve/Response/RetrieveFileUploadResponse.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Notion.Client -{ - public class RetrieveFileUploadResponse : FileObjectResponse - { - } -} diff --git a/Src/Notion.Client/Api/FileUploads/Send/FileUploadsClient.cs b/Src/Notion.Client/Api/FileUploads/Send/FileUploadsClient.cs index 73a4de79..c97a3a82 100644 --- a/Src/Notion.Client/Api/FileUploads/Send/FileUploadsClient.cs +++ b/Src/Notion.Client/Api/FileUploads/Send/FileUploadsClient.cs @@ -6,7 +6,7 @@ namespace Notion.Client { public sealed partial class FileUploadsClient { - public async Task SendAsync( + public async Task SendAsync( SendFileUploadRequest sendFileUploadRequest, CancellationToken cancellationToken = default) { @@ -30,11 +30,11 @@ public async Task SendAsync( var path = ApiEndpoints.FileUploadsApiUrls.Send(sendFileUploadRequest.FileUploadId); - return await _restClient.PostAsync( + return await _restClient.PostAsync( path, formData: sendFileUploadRequest, cancellationToken: cancellationToken ); } } -} \ No newline at end of file +} diff --git a/Src/Notion.Client/Api/FileUploads/Send/Request/ISendFileUploadFormDataParameters.cs b/Src/Notion.Client/Api/FileUploads/Send/Request/ISendFileUploadFormDataParameters.cs index c4fe2b74..d26b66f8 100644 --- a/Src/Notion.Client/Api/FileUploads/Send/Request/ISendFileUploadFormDataParameters.cs +++ b/Src/Notion.Client/Api/FileUploads/Send/Request/ISendFileUploadFormDataParameters.cs @@ -1,6 +1,4 @@ -using Newtonsoft.Json; - -namespace Notion.Client +namespace Notion.Client { public interface ISendFileUploadFormDataParameters { diff --git a/Src/Notion.Client/Api/FileUploads/Send/Response/SendFileUploadResponse.cs b/Src/Notion.Client/Api/FileUploads/Send/Response/SendFileUploadResponse.cs deleted file mode 100644 index 1061683d..00000000 --- a/Src/Notion.Client/Api/FileUploads/Send/Response/SendFileUploadResponse.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Notion.Client -{ - public class SendFileUploadResponse : FileObjectResponse - { - } -} diff --git a/Src/Notion.Client/Api/Pages/IPagesClient.cs b/Src/Notion.Client/Api/Pages/IPagesClient.cs index 8dc8f5ce..dbbd1b95 100644 --- a/Src/Notion.Client/Api/Pages/IPagesClient.cs +++ b/Src/Notion.Client/Api/Pages/IPagesClient.cs @@ -15,6 +15,7 @@ public interface IPagesClient /// If the parent is a page, the only valid property is title. /// /// Create page parameters + /// Cancellation token /// Created object. Task CreateAsync(PagesCreateParameters pagesCreateParameters, CancellationToken cancellationToken = default); @@ -22,6 +23,7 @@ public interface IPagesClient /// Retrieves a Page object using the ID specified. /// /// Identifier for a Notion page + /// Cancellation token /// /// /// @@ -36,6 +38,7 @@ public interface IPagesClient /// Property values to update for this page. The keys are the names or IDs of the property /// and the values are property values. /// + /// Cancellation token /// Updated object Task UpdatePropertiesAsync( string pageId, @@ -47,6 +50,7 @@ Task UpdatePropertiesAsync( /// /// Identifier for a Notion page /// Update property parameters + /// Cancellation token /// Updated object Task UpdateAsync(string pageId, PagesUpdateParameters pagesUpdateParameters, CancellationToken cancellationToken = default); @@ -55,6 +59,7 @@ Task UpdatePropertiesAsync( /// returned will either be a value or a paginated list of property item values. /// /// Property body and query parameters + /// Cancellation token /// /// /// diff --git a/Src/Notion.Client/Api/Pages/RequestParams/IPagesUpdateBodyParameters.cs b/Src/Notion.Client/Api/Pages/RequestParams/IPagesUpdateBodyParameters.cs index b7ea1ea6..98fd007d 100644 --- a/Src/Notion.Client/Api/Pages/RequestParams/IPagesUpdateBodyParameters.cs +++ b/Src/Notion.Client/Api/Pages/RequestParams/IPagesUpdateBodyParameters.cs @@ -5,6 +5,12 @@ namespace Notion.Client { public interface IPagesUpdateBodyParameters { + [JsonProperty("icon")] + IPageIconRequest Icon { get; set; } + + [JsonProperty("cover")] + IPageCoverRequest Cover { get; set; } + [JsonProperty("in_trash")] bool InTrash { get; set; } 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..189ae78d 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; } @@ -15,9 +15,9 @@ public interface IPagesCreateBodyParameters IList Children { get; set; } [JsonProperty("icon")] - IPageIcon Icon { get; set; } + IPageIconRequest Icon { get; set; } [JsonProperty("cover")] - FileObject Cover { get; set; } + IPageCoverRequest Cover { 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..bf533d43 100644 --- a/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/PagesCreateParameters.cs +++ b/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/PagesCreateParameters.cs @@ -4,14 +4,14 @@ namespace Notion.Client { public class PagesCreateParameters : IPagesCreateBodyParameters, IPagesCreateQueryParameters { - public IPageParentInput Parent { get; set; } + public IParentOfPageRequest Parent { get; set; } public IDictionary Properties { get; set; } public IList Children { get; set; } - public IPageIcon Icon { get; set; } + public IPageIconRequest Icon { get; set; } - public FileObject Cover { get; set; } + public IPageCoverRequest Cover { 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..b22388a1 100644 --- a/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/PagesCreateParametersBuilder.cs +++ b/Src/Notion.Client/Api/Pages/RequestParams/PagesCreateParameters/PagesCreateParametersBuilder.cs @@ -8,15 +8,15 @@ public class PagesCreateParametersBuilder { private readonly IList _children = new List(); private readonly Dictionary _properties = new(); - private FileObject _cover; - private IPageIcon _icon; - private IPageParentInput _parent; + private IPageCoverRequest _cover; + private IPageIconRequest _icon; + private IParentOfPageRequest _parent; private PagesCreateParametersBuilder() { } - public static PagesCreateParametersBuilder Create(IPageParentInput parent) + public static PagesCreateParametersBuilder Create(IParentOfPageRequest parent) { return new PagesCreateParametersBuilder { _parent = parent }; } @@ -35,14 +35,14 @@ public PagesCreateParametersBuilder AddPageContent(IBlock block) return this; } - public PagesCreateParametersBuilder SetIcon(IPageIcon pageIcon) + public PagesCreateParametersBuilder SetIcon(IPageIconRequest pageIcon) { _icon = pageIcon; return this; } - public PagesCreateParametersBuilder SetCover(FileObject pageCover) + public PagesCreateParametersBuilder SetCover(IPageCoverRequest pageCover) { _cover = pageCover; diff --git a/Src/Notion.Client/Api/Pages/RequestParams/PagesUpdateParameters.cs b/Src/Notion.Client/Api/Pages/RequestParams/PagesUpdateParameters.cs index 6845f27b..5b74d88f 100644 --- a/Src/Notion.Client/Api/Pages/RequestParams/PagesUpdateParameters.cs +++ b/Src/Notion.Client/Api/Pages/RequestParams/PagesUpdateParameters.cs @@ -6,10 +6,10 @@ namespace Notion.Client public class PagesUpdateParameters : IPagesUpdateBodyParameters { [JsonProperty("icon")] - public IPageIcon Icon { get; set; } + public IPageIconRequest Icon { get; set; } [JsonProperty("cover")] - public FileObject Cover { get; set; } + public IPageCoverRequest Cover { get; set; } [JsonProperty("in_trash")] public bool InTrash { get; set; } 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..65f4b9b2 --- /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(DataSource), 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/Block.cs b/Src/Notion.Client/Models/Blocks/Block.cs index fa1ef612..a3a080e1 100644 --- a/Src/Notion.Client/Models/Blocks/Block.cs +++ b/Src/Notion.Client/Models/Blocks/Block.cs @@ -25,6 +25,6 @@ public abstract class Block : IBlock /// /// Information about the block's parent. /// - public IBlockParent Parent { get; set; } + public IParentOfBlock Parent { get; set; } } } diff --git a/Src/Notion.Client/Models/Blocks/IBlock.cs b/Src/Notion.Client/Models/Blocks/IBlock.cs index b06a3646..0113600e 100644 --- a/Src/Notion.Client/Models/Blocks/IBlock.cs +++ b/Src/Notion.Client/Models/Blocks/IBlock.cs @@ -51,6 +51,6 @@ public interface IBlock : IObject, IObjectModificationData bool InTrash { get; set; } [JsonProperty("parent")] - IBlockParent Parent { get; set; } + IParentOfBlock Parent { get; set; } } } diff --git a/Src/Notion.Client/Models/Blocks/IBlockParent.cs b/Src/Notion.Client/Models/Blocks/IBlockParent.cs deleted file mode 100644 index b2f8783f..00000000 --- a/Src/Notion.Client/Models/Blocks/IBlockParent.cs +++ /dev/null @@ -1,14 +0,0 @@ -using JsonSubTypes; -using Newtonsoft.Json; - -namespace Notion.Client -{ - [JsonConverter(typeof(JsonSubtypes), "type")] - [JsonSubtypes.KnownSubTypeAttribute(typeof(DatabaseParent), ParentType.DatabaseId)] - [JsonSubtypes.KnownSubTypeAttribute(typeof(PageParent), ParentType.PageId)] - [JsonSubtypes.KnownSubTypeAttribute(typeof(WorkspaceParent), ParentType.Workspace)] - [JsonSubtypes.KnownSubTypeAttribute(typeof(BlockParent), ParentType.BlockId)] - public interface IBlockParent : IParent - { - } -} 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/BlockObjectRequest.cs b/Src/Notion.Client/Models/Blocks/Request/BlockObjectRequest.cs index a3eb3182..d04af666 100644 --- a/Src/Notion.Client/Models/Blocks/Request/BlockObjectRequest.cs +++ b/Src/Notion.Client/Models/Blocks/Request/BlockObjectRequest.cs @@ -23,6 +23,6 @@ public abstract class BlockObjectRequest : IBlockObjectRequest /// /// Information about the block's parent. /// - public IBlockParent Parent { get; set; } + public IParentOfBlock Parent { get; set; } } } diff --git a/Src/Notion.Client/Models/Blocks/Request/CalloutBlockRequest.cs b/Src/Notion.Client/Models/Blocks/Request/CalloutBlockRequest.cs index b8a56823..9f879c36 100644 --- a/Src/Notion.Client/Models/Blocks/Request/CalloutBlockRequest.cs +++ b/Src/Notion.Client/Models/Blocks/Request/CalloutBlockRequest.cs @@ -17,7 +17,7 @@ public class Info public IEnumerable RichText { get; set; } [JsonProperty("icon")] - public IPageIcon Icon { get; set; } + public IPageIconRequest Icon { get; set; } [JsonProperty("color")] [JsonConverter(typeof(StringEnumConverter))] diff --git a/Src/Notion.Client/Models/Blocks/Request/IBlockObjectRequest.cs b/Src/Notion.Client/Models/Blocks/Request/IBlockObjectRequest.cs index b3fbaf55..d96ddda9 100644 --- a/Src/Notion.Client/Models/Blocks/Request/IBlockObjectRequest.cs +++ b/Src/Notion.Client/Models/Blocks/Request/IBlockObjectRequest.cs @@ -1,5 +1,4 @@ -using JsonSubTypes; -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Converters; namespace Notion.Client @@ -14,6 +13,6 @@ public interface IBlockObjectRequest : IObject, IObjectModificationData bool HasChildren { get; set; } [JsonProperty("parent")] - IBlockParent Parent { get; set; } + IParentOfBlock Parent { get; set; } } } 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/Api/Comments/Retrieve/Response/Comment.cs b/Src/Notion.Client/Models/Comment/Comment.cs similarity index 93% rename from Src/Notion.Client/Api/Comments/Retrieve/Response/Comment.cs rename to Src/Notion.Client/Models/Comment/Comment.cs index 9b9ef2ae..cdb62409 100644 --- a/Src/Notion.Client/Api/Comments/Retrieve/Response/Comment.cs +++ b/Src/Notion.Client/Models/Comment/Comment.cs @@ -7,7 +7,7 @@ namespace Notion.Client public class Comment : IObject { [JsonProperty("parent")] - public ICommentParent Parent { get; set; } + public IParentOfComment Parent { get; set; } [JsonProperty("discussion_id")] public string DiscussionId { get; set; } diff --git a/Src/Notion.Client/Models/CustomEmojiObject.cs b/Src/Notion.Client/Models/CustomEmojiObject.cs deleted file mode 100644 index 1faa4d74..00000000 --- a/Src/Notion.Client/Models/CustomEmojiObject.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class CustomEmojiObject : IPageIcon - { - [JsonProperty("custom_emoji")] - public CustomEmoji CustomEmoji { get; set; } - - [JsonProperty("type")] - public string Type { get; set; } - } -} diff --git a/Src/Notion.Client/Models/DataSource/DataSource.cs b/Src/Notion.Client/Models/DataSource/DataSource.cs new file mode 100644 index 00000000..00499061 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/DataSource.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DataSource : 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 IParentOfDatasource 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 IParentOfDatabase 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 IPageIcon Icon { get; set; } + + /// + /// The cover image of the data source. + /// + [JsonProperty("cover")] + public IPageCover 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/Models/DataSource/PropertyConfig/ButtonDataSourcePropertyConfig.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/ButtonDataSourcePropertyConfig.cs new file mode 100644 index 00000000..85a76641 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/ButtonDataSourcePropertyConfig.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ButtonDataSourcePropertyConfig : DataSourcePropertyConfig + { + public override string Type => DataSourcePropertyTypes.Button; + + [JsonProperty("button")] + public Dictionary Button { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/CheckboxPropertySchema.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/CheckboxDataSourcePropertyConfig.cs similarity index 57% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/CheckboxPropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/CheckboxDataSourcePropertyConfig.cs index fb955a3e..bc58ce22 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/CheckboxPropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/CheckboxDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class CheckboxPropertySchema : IPropertySchema + public class CheckboxDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.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/Models/DataSource/PropertyConfig/CreatedByDataSourcePropertyConfig.cs similarity index 57% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CreatedByUpdatePropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/CreatedByDataSourcePropertyConfig.cs index 08a5cf74..77570121 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CreatedByUpdatePropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/CreatedByDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class CreatedByUpdatePropertySchema : UpdatePropertySchema + public class CreatedByDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.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/Models/DataSource/PropertyConfig/CreatedTimeDataSourcePropertyConfig.cs similarity index 56% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CreatedTimeUpdatePropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/CreatedTimeDataSourcePropertyConfig.cs index 8089ecbb..4a2e9f7a 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/CreatedTimeUpdatePropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/CreatedTimeDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class CreatedTimeUpdatePropertySchema : UpdatePropertySchema + public class CreatedTimeDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.CreatedTime; + [JsonProperty("created_time")] public Dictionary CreatedTime { get; set; } } diff --git a/Src/Notion.Client/Models/DataSource/PropertyConfig/DataSourcePropertyConfig.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/DataSourcePropertyConfig.cs new file mode 100644 index 00000000..859d16d0 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/DataSourcePropertyConfig.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(CheckboxDataSourcePropertyConfig), DataSourcePropertyTypes.Checkbox)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(CreatedByDataSourcePropertyConfig), DataSourcePropertyTypes.CreatedBy)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(CreatedTimeDataSourcePropertyConfig), DataSourcePropertyTypes.CreatedTime)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(DateDataSourcePropertyConfig), DataSourcePropertyTypes.Date)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(EmailDataSourcePropertyConfig), DataSourcePropertyTypes.Email)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(FilesDataSourcePropertyConfig), DataSourcePropertyTypes.Files)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(FormulaDataSourcePropertyConfig), DataSourcePropertyTypes.Formula)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(LastEditedByDataSourcePropertyConfig), DataSourcePropertyTypes.LastEditedBy)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(LastEditedTimeDataSourcePropertyConfig), DataSourcePropertyTypes.LastEditedTime)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(MultiSelectDataSourcePropertyConfig), DataSourcePropertyTypes.MultiSelect)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(NumberDataSourcePropertyConfig), DataSourcePropertyTypes.Number)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(PeopleDataSourcePropertyConfig), DataSourcePropertyTypes.People)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(PhoneNumberDataSourcePropertyConfig), DataSourcePropertyTypes.PhoneNumber)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(RelationDataSourcePropertyConfig), DataSourcePropertyTypes.Relation)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(RichTextDataSourcePropertyConfig), DataSourcePropertyTypes.RichText)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(RollupDataSourcePropertyConfig), DataSourcePropertyTypes.Rollup)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(SelectDataSourcePropertyConfig), DataSourcePropertyTypes.Select)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(StatusDataSourcePropertyConfig), DataSourcePropertyTypes.Status)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(TitleDataSourcePropertyConfig), DataSourcePropertyTypes.Title)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(UrlDataSourcePropertyConfig), DataSourcePropertyTypes.Url)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(UniqueIdDataSourcePropertyConfig), DataSourcePropertyTypes.UniqueId)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(ButtonDataSourcePropertyConfig), DataSourcePropertyTypes.Button)] + public class DataSourcePropertyConfig + { + [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/Models/DataSource/PropertyConfig/DataSourcePropertyTypes.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/DataSourcePropertyTypes.cs new file mode 100644 index 00000000..373c38b0 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/DataSourcePropertyTypes.cs @@ -0,0 +1,28 @@ +namespace Notion.Client +{ + public static class DataSourcePropertyTypes + { + 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/Models/DataSource/PropertyConfig/DateDataSourcePropertyConfig.cs similarity index 57% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/DateUpdatePropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/DateDataSourcePropertyConfig.cs index 65487dd7..99b45382 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/DateUpdatePropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/DateDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class DateUpdatePropertySchema : UpdatePropertySchema + public class DateDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.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/Models/DataSource/PropertyConfig/EmailDataSourcePropertyConfig.cs similarity index 57% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/EmailUpdatePropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/EmailDataSourcePropertyConfig.cs index 5905e68e..4b8da704 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/EmailUpdatePropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/EmailDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class EmailUpdatePropertySchema : UpdatePropertySchema + public class EmailDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.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/Models/DataSource/PropertyConfig/FilesDataSourcePropertyConfig.cs similarity index 57% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/FilesUpdatePropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/FilesDataSourcePropertyConfig.cs index 9fb3b531..d7e873c3 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/FilesUpdatePropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/FilesDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class FilesUpdatePropertySchema : UpdatePropertySchema + public class FilesDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.Files; + [JsonProperty("files")] public Dictionary Files { get; set; } } diff --git a/Src/Notion.Client/Models/DataSource/PropertyConfig/FormulaDataSourcePropertyConfig.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/FormulaDataSourcePropertyConfig.cs new file mode 100644 index 00000000..1ee492e4 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/FormulaDataSourcePropertyConfig.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class FormulaDataSourcePropertyConfig : DataSourcePropertyConfig + { + public override string Type => DataSourcePropertyTypes.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/Models/DataSource/PropertyConfig/LastEditedByDataSourcePropertyConfig.cs similarity index 57% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/LastEditedByUpdatePropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/LastEditedByDataSourcePropertyConfig.cs index c547538a..e0aca110 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/LastEditedByUpdatePropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/LastEditedByDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class LastEditedByUpdatePropertySchema : UpdatePropertySchema + public class LastEditedByDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.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/Models/DataSource/PropertyConfig/LastEditedTimeDataSourcePropertyConfig.cs similarity index 56% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/LastEditedTimeUpdatePropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/LastEditedTimeDataSourcePropertyConfig.cs index 28c9e55b..c208e3aa 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/LastEditedTimeUpdatePropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/LastEditedTimeDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class LastEditedTimeUpdatePropertySchema : UpdatePropertySchema + public class LastEditedTimeDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.LastEditedTime; + [JsonProperty("last_edited_time")] public Dictionary LastEditedTime { get; set; } } diff --git a/Src/Notion.Client/Models/DataSource/PropertyConfig/MultiSelectDataSourcePropertyConfig.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/MultiSelectDataSourcePropertyConfig.cs new file mode 100644 index 00000000..50398136 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/MultiSelectDataSourcePropertyConfig.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class MultiSelectDataSourcePropertyConfig : DataSourcePropertyConfig + { + public override string Type => DataSourcePropertyTypes.MultiSelect; + + [JsonProperty("multi_select")] + public OptionWrapper MultiSelect { get; set; } + } +} diff --git a/Src/Notion.Client/Models/DataSource/PropertyConfig/NumberDataSourcePropertyConfig.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/NumberDataSourcePropertyConfig.cs new file mode 100644 index 00000000..379d8c80 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/NumberDataSourcePropertyConfig.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class NumberDataSourcePropertyConfig : DataSourcePropertyConfig + { + public override string Type => DataSourcePropertyTypes.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/Models/DataSource/PropertyConfig/PeopleDataSourcePropertyConfig.cs similarity index 57% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/PeopleUpdatePropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/PeopleDataSourcePropertyConfig.cs index 41a8892d..32cf5f59 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/PeopleUpdatePropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/PeopleDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class PeopleUpdatePropertySchema : UpdatePropertySchema + public class PeopleDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.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/Models/DataSource/PropertyConfig/PhoneNumberDataSourcePropertyConfig.cs similarity index 56% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/PhoneNumberPropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/PhoneNumberDataSourcePropertyConfig.cs index b4b6d363..6e84aff2 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/PhoneNumberPropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/PhoneNumberDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class PhoneNumberPropertySchema : IPropertySchema + public class PhoneNumberDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.PhoneNumber; + [JsonProperty("phone_number")] public Dictionary PhoneNumber { get; set; } } diff --git a/Src/Notion.Client/Models/DataSource/PropertyConfig/RelationProperty/DualPropertyRelationInfo.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/RelationProperty/DualPropertyRelationInfo.cs new file mode 100644 index 00000000..15f53b9f --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/RelationProperty/DualPropertyRelationInfo.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DualPropertyRelationInfo : RelationInfo + { + 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/Models/DataSource/PropertyConfig/RelationProperty/RelationDataSourcePropertyConfig.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/RelationProperty/RelationDataSourcePropertyConfig.cs new file mode 100644 index 00000000..79c685d2 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/RelationProperty/RelationDataSourcePropertyConfig.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class RelationDataSourcePropertyConfig : DataSourcePropertyConfig + { + public override string Type => DataSourcePropertyTypes.Relation; + + [JsonProperty("relation")] + public RelationInfo Relation { get; set; } + } +} diff --git a/Src/Notion.Client/Models/DataSource/PropertyConfig/RelationProperty/RelationInfo.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/RelationProperty/RelationInfo.cs new file mode 100644 index 00000000..3a337b30 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/RelationProperty/RelationInfo.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(SinglePropertyRelationInfo), "single_property")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(DualPropertyRelationInfo), "dual_property")] + public abstract class RelationInfo + { + [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/Models/DataSource/PropertyConfig/RelationProperty/SinglePropertyRelationInfo.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/RelationProperty/SinglePropertyRelationInfo.cs new file mode 100644 index 00000000..e9d27348 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/RelationProperty/SinglePropertyRelationInfo.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class SinglePropertyRelationInfo : RelationInfo + { + 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/Models/DataSource/PropertyConfig/RichTextDataSourcePropertyConfig.cs similarity index 57% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RichTextUpdatePropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/RichTextDataSourcePropertyConfig.cs index a20ca0ea..a8c099ae 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesUpdateParameters/PropertySchema/RichTextUpdatePropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/RichTextDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class RichTextUpdatePropertySchema : UpdatePropertySchema + public class RichTextDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.RichText; + [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/Models/DataSource/PropertyConfig/RollupDataSourcePropertyConfig.cs similarity index 54% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/RollupConfigPropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/RollupDataSourcePropertyConfig.cs index ac3c5220..a2f85d74 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/RollupConfigPropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/RollupDataSourcePropertyConfig.cs @@ -1,8 +1,17 @@ -using Newtonsoft.Json; +using System.Collections.Generic; +using Newtonsoft.Json; namespace Notion.Client { - public class RollupConfigPropertySchema : IPropertySchema + public class RollupDataSourcePropertyConfig : DataSourcePropertyConfig + { + public override string Type => DataSourcePropertyTypes.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 RollupConfigPropertySchema : IPropertySchema [JsonProperty("function")] public string Function { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } } } diff --git a/Src/Notion.Client/Models/DataSource/PropertyConfig/SelectDataSourcePropertyConfig.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/SelectDataSourcePropertyConfig.cs new file mode 100644 index 00000000..19784181 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/SelectDataSourcePropertyConfig.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 SelectDataSourcePropertyConfig : DataSourcePropertyConfig + { + public override string Type => DataSourcePropertyTypes.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/Models/DataSource/PropertyConfig/StatusDataSourcePropertyConfig.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/StatusDataSourcePropertyConfig.cs new file mode 100644 index 00000000..61f3b7c6 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/StatusDataSourcePropertyConfig.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class StatusDataSourcePropertyConfig : DataSourcePropertyConfig + { + public override string Type => DataSourcePropertyTypes.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/Models/DataSource/PropertyConfig/TitleDataSourcePropertyConfig.cs similarity index 57% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/TitlePropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/TitleDataSourcePropertyConfig.cs index b7fb2f72..aa8ee31f 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/TitlePropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/TitleDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class TitlePropertySchema : IPropertySchema + public class TitleDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.Title; + [JsonProperty("title")] public Dictionary Title { get; set; } } diff --git a/Src/Notion.Client/Models/DataSource/PropertyConfig/UniqueIdDataSourcePropertyConfig.cs b/Src/Notion.Client/Models/DataSource/PropertyConfig/UniqueIdDataSourcePropertyConfig.cs new file mode 100644 index 00000000..43be91a5 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/UniqueIdDataSourcePropertyConfig.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class UniqueIdDataSourcePropertyConfig : DataSourcePropertyConfig + { + public override string Type => DataSourcePropertyTypes.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/Models/DataSource/PropertyConfig/UrlDataSourcePropertyConfig.cs similarity index 57% rename from Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/UrlPropertySchema.cs rename to Src/Notion.Client/Models/DataSource/PropertyConfig/UrlDataSourcePropertyConfig.cs index 0860fa97..24a4abf5 100644 --- a/Src/Notion.Client/Api/Databases/RequestParams/DatabasesCreateParameters/PropertySchema/UrlPropertySchema.cs +++ b/Src/Notion.Client/Models/DataSource/PropertyConfig/UrlDataSourcePropertyConfig.cs @@ -3,8 +3,10 @@ namespace Notion.Client { - public class UrlPropertySchema : IPropertySchema + public class UrlDataSourcePropertyConfig : DataSourcePropertyConfig { + public override string Type => DataSourcePropertyTypes.Url; + [JsonProperty("url")] public Dictionary Url { get; set; } } diff --git a/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/ButtonDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/ButtonDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..13c84185 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/ButtonDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ButtonDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/CheckboxDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/CheckboxDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..a55d5aa8 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/CheckboxDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CheckboxDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/CreatedByDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/CreatedByDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..4e4f627b --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/CreatedByDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CreatedByDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/CreatedTimeDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/CreatedTimeDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..b63b9c95 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/CreatedTimeDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CreatedTimeDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/DataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/DataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..b96ef96f --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/DataSourcePropertyConfigRequest.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/DateDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/DateDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..2debcd5e --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/DateDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DateDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/EmailDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/EmailDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..55e5b25a --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/EmailDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class EmailDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/FilesDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/FilesDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..7c7b0ee3 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/FilesDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class FilesDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/FormulaDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/FormulaDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..26eb29fc --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/FormulaDataSourcePropertyConfigRequest.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class FormulaDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/LastEditedByDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/LastEditedByDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..c35b17d2 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/LastEditedByDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LastEditedByDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/LastEditedTimeDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/LastEditedTimeDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..3b12e9a5 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/LastEditedTimeDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LastEditedTimeDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/LastVisitedTimeDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/LastVisitedTimeDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..cd68f154 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/LastVisitedTimeDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LastVisitedTimeDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/LocationDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/LocationDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..f1fc8fe1 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/LocationDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class LocationDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/MultiSelectDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/MultiSelectDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..9e4515d8 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/MultiSelectDataSourcePropertyConfigRequest.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class MultiSelectDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/NumberDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/NumberDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..910d2696 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/NumberDataSourcePropertyConfigRequest.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class NumberDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/PeopleDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/PeopleDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..d832785d --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/PeopleDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class PeopleDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/PhoneNumberDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/PhoneNumberDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..ac40c081 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/PhoneNumberDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class PhoneNumberDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/PlaceDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/PlaceDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..c8f9bc28 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/PlaceDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class PlaceDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/RelationPropertyConfig/DualPropertyRelationInfoRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RelationPropertyConfig/DualPropertyRelationInfoRequest.cs new file mode 100644 index 00000000..e4ba3e98 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RelationPropertyConfig/DualPropertyRelationInfoRequest.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DualPropertyRelationInfoRequest : IRelationInfoRequest + { + 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; } + } + } +} diff --git a/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RelationPropertyConfig/IRelationInfoRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RelationPropertyConfig/IRelationInfoRequest.cs new file mode 100644 index 00000000..95136b55 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RelationPropertyConfig/IRelationInfoRequest.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IRelationInfoRequest + { + [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; } + } +} diff --git a/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RelationPropertyConfig/RelationDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RelationPropertyConfig/RelationDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..3aaf0f1f --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RelationPropertyConfig/RelationDataSourcePropertyConfigRequest.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class RelationDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [JsonProperty("type")] + public override string Type => "relation"; + + [JsonProperty("relation")] + public IRelationInfoRequest Relation { get; set; } + } +} diff --git a/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RelationPropertyConfig/SinglePropertyRelationInfoRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RelationPropertyConfig/SinglePropertyRelationInfoRequest.cs new file mode 100644 index 00000000..680ac195 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RelationPropertyConfig/SinglePropertyRelationInfoRequest.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class SinglePropertyRelationInfoRequest : IRelationInfoRequest + { + 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; } + } +} diff --git a/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RichTextDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RichTextDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..0578da00 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RichTextDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class RichTextDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/RollupDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RollupDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..618fbace --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/RollupDataSourcePropertyConfigRequest.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class RollupDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/SelectDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/SelectDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..8fcfd03a --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/SelectDataSourcePropertyConfigRequest.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class SelectDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/SelectOptionRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/SelectOptionRequest.cs new file mode 100644 index 00000000..b634bd90 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/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/Models/DataSource/Request/PropertyConfig/StatusDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/StatusDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..1c50c194 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/StatusDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class StatusDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/TitleDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/TitleDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..8acd95ce --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/TitleDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class TitleDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/UniqueIdDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/UniqueIdDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..99ee719b --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/UniqueIdDataSourcePropertyConfigRequest.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class UniqueIdDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/UrlDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/UrlDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..790cd671 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/UrlDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class UrlDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/Models/DataSource/Request/PropertyConfig/VerificationDataSourcePropertyConfigRequest.cs b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/VerificationDataSourcePropertyConfigRequest.cs new file mode 100644 index 00000000..a7733515 --- /dev/null +++ b/Src/Notion.Client/Models/DataSource/Request/PropertyConfig/VerificationDataSourcePropertyConfigRequest.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class VerificationDataSourcePropertyConfigRequest : DataSourcePropertyConfigRequest + { + [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/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..67428f7a 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 IParentOfDatabase 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,28 @@ 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 IPageIcon Icon { get; set; } + + /// + /// The cover image of the database. + /// + [JsonProperty("cover")] + public IPageCover 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/IDatabaseParent.cs b/Src/Notion.Client/Models/Database/IDatabaseParent.cs deleted file mode 100644 index 768f815b..00000000 --- a/Src/Notion.Client/Models/Database/IDatabaseParent.cs +++ /dev/null @@ -1,13 +0,0 @@ -using JsonSubTypes; -using Newtonsoft.Json; - -namespace Notion.Client -{ - [JsonConverter(typeof(JsonSubtypes), "type")] - [JsonSubtypes.KnownSubTypeAttribute(typeof(PageParent), ParentType.PageId)] - [JsonSubtypes.KnownSubTypeAttribute(typeof(WorkspaceParent), ParentType.Workspace)] - [JsonSubtypes.KnownSubTypeAttribute(typeof(BlockParent), ParentType.BlockId)] - public interface IDatabaseParent : IParent - { - } -} 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/Database/Properties/ButtonProperty.cs b/Src/Notion.Client/Models/Database/Properties/ButtonProperty.cs index 983138e2..3b2b1c40 100644 --- a/Src/Notion.Client/Models/Database/Properties/ButtonProperty.cs +++ b/Src/Notion.Client/Models/Database/Properties/ButtonProperty.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; using Newtonsoft.Json; -using System.Threading.Tasks; namespace Notion.Client { diff --git a/Src/Notion.Client/Models/EmojiObject.cs b/Src/Notion.Client/Models/EmojiObject.cs deleted file mode 100644 index 9b5c64df..00000000 --- a/Src/Notion.Client/Models/EmojiObject.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class EmojiObject : IPageIcon - { - [JsonProperty("emoji")] - public string Emoji { get; set; } - - [JsonProperty("type")] - public string Type { get; set; } - } -} diff --git a/Src/Notion.Client/Models/File/FileObject.cs b/Src/Notion.Client/Models/File/FileObject.cs index 0ac30a6c..839af54e 100644 --- a/Src/Notion.Client/Models/File/FileObject.cs +++ b/Src/Notion.Client/Models/File/FileObject.cs @@ -7,7 +7,7 @@ namespace Notion.Client [JsonConverter(typeof(JsonSubtypes), "type")] [JsonSubtypes.KnownSubTypeAttribute(typeof(UploadedFile), "file")] [JsonSubtypes.KnownSubTypeAttribute(typeof(ExternalFile), "external")] - public abstract class FileObject : IPageIcon + public abstract class FileObject { [JsonProperty("caption")] public IEnumerable Caption { get; set; } diff --git a/Src/Notion.Client/Api/FileUploads/FileUploadObjectResponse/FileImportError.cs b/Src/Notion.Client/Models/FileUpload/FileImportError.cs similarity index 100% rename from Src/Notion.Client/Api/FileUploads/FileUploadObjectResponse/FileImportError.cs rename to Src/Notion.Client/Models/FileUpload/FileImportError.cs diff --git a/Src/Notion.Client/Api/FileUploads/FileUploadObjectResponse/FileImportErrorResult.cs b/Src/Notion.Client/Models/FileUpload/FileImportErrorResult.cs similarity index 100% rename from Src/Notion.Client/Api/FileUploads/FileUploadObjectResponse/FileImportErrorResult.cs rename to Src/Notion.Client/Models/FileUpload/FileImportErrorResult.cs diff --git a/Src/Notion.Client/Api/FileUploads/FileUploadObjectResponse/FileImportResult.cs b/Src/Notion.Client/Models/FileUpload/FileImportResult.cs similarity index 100% rename from Src/Notion.Client/Api/FileUploads/FileUploadObjectResponse/FileImportResult.cs rename to Src/Notion.Client/Models/FileUpload/FileImportResult.cs diff --git a/Src/Notion.Client/Api/FileUploads/FileUploadObjectResponse/FileImportSuccessResult.cs b/Src/Notion.Client/Models/FileUpload/FileImportSuccessResult.cs similarity index 100% rename from Src/Notion.Client/Api/FileUploads/FileUploadObjectResponse/FileImportSuccessResult.cs rename to Src/Notion.Client/Models/FileUpload/FileImportSuccessResult.cs diff --git a/Src/Notion.Client/Api/FileUploads/FileUploadObjectResponse/FileUploadObjectResponse.cs b/Src/Notion.Client/Models/FileUpload/FileUpload.cs similarity index 96% rename from Src/Notion.Client/Api/FileUploads/FileUploadObjectResponse/FileUploadObjectResponse.cs rename to Src/Notion.Client/Models/FileUpload/FileUpload.cs index 39285c3b..564a713d 100644 --- a/Src/Notion.Client/Api/FileUploads/FileUploadObjectResponse/FileUploadObjectResponse.cs +++ b/Src/Notion.Client/Models/FileUpload/FileUpload.cs @@ -3,7 +3,7 @@ namespace Notion.Client { - public class FileObjectResponse : IObject + public class FileUpload : IObject { public string Id { get; set; } public ObjectType Object => ObjectType.FileUpload; 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/IPageIcon.cs b/Src/Notion.Client/Models/Page/IPageIcon.cs deleted file mode 100644 index 5d692185..00000000 --- a/Src/Notion.Client/Models/Page/IPageIcon.cs +++ /dev/null @@ -1,16 +0,0 @@ -using JsonSubTypes; -using Newtonsoft.Json; - -namespace Notion.Client -{ - [JsonConverter(typeof(JsonSubtypes), "type")] - [JsonSubtypes.KnownSubTypeAttribute(typeof(EmojiObject), "emoji")] - [JsonSubtypes.KnownSubTypeAttribute(typeof(CustomEmojiObject), "custom_emoji")] - [JsonSubtypes.KnownSubTypeAttribute(typeof(FileObject), "file")] - [JsonSubtypes.KnownSubTypeAttribute(typeof(FileObject), "external")] - public interface IPageIcon - { - [JsonProperty("type")] - string Type { get; set; } - } -} diff --git a/Src/Notion.Client/Models/Page/IPageParent.cs b/Src/Notion.Client/Models/Page/IPageParent.cs deleted file mode 100644 index b9111d91..00000000 --- a/Src/Notion.Client/Models/Page/IPageParent.cs +++ /dev/null @@ -1,14 +0,0 @@ -using JsonSubTypes; -using Newtonsoft.Json; - -namespace Notion.Client -{ - [JsonConverter(typeof(JsonSubtypes), "type")] - [JsonSubtypes.KnownSubTypeAttribute(typeof(DatabaseParent), ParentType.DatabaseId)] - [JsonSubtypes.KnownSubTypeAttribute(typeof(PageParent), ParentType.PageId)] - [JsonSubtypes.KnownSubTypeAttribute(typeof(WorkspaceParent), ParentType.Workspace)] - [JsonSubtypes.KnownSubTypeAttribute(typeof(BlockParent), ParentType.BlockId)] - public interface IPageParent : IParent - { - } -} diff --git a/Src/Notion.Client/Models/Page/Page.cs b/Src/Notion.Client/Models/Page/Page.cs index fe4eb0de..ef736e4f 100644 --- a/Src/Notion.Client/Models/Page/Page.cs +++ b/Src/Notion.Client/Models/Page/Page.cs @@ -4,13 +4,13 @@ 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. /// [JsonProperty("parent")] - public IPageParent Parent { get; set; } + public IParentOfPage Parent { get; set; } /// /// Indicates whether the page is currently in the trash. @@ -37,10 +37,10 @@ public class Page : IObject, IObjectModificationData, IWikiDatabase public IPageIcon Icon { get; set; } /// - /// Page cover image. + /// The cover image of the page. /// [JsonProperty("cover")] - public FileObject Cover { get; set; } + public IPageCover Cover { get; set; } /// /// Object type diff --git a/Src/Notion.Client/Models/Page/PageCover/ExternalPageCover.cs b/Src/Notion.Client/Models/Page/PageCover/ExternalPageCover.cs new file mode 100644 index 00000000..21360b0e --- /dev/null +++ b/Src/Notion.Client/Models/Page/PageCover/ExternalPageCover.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ExternalPageCover : IPageCover + { + public string Type { get; set; } = "external"; + + [JsonProperty("external")] + public ExternalFileInfo External { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Page/PageCover/FilePageCover.cs b/Src/Notion.Client/Models/Page/PageCover/FilePageCover.cs new file mode 100644 index 00000000..78050ce0 --- /dev/null +++ b/Src/Notion.Client/Models/Page/PageCover/FilePageCover.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class FilePageCover : IPageCover + { + public string Type { get; set; } = "file"; + + [JsonProperty("file")] + public InternalFileInfo File { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Page/PageCover/IPageCover.cs b/Src/Notion.Client/Models/Page/PageCover/IPageCover.cs new file mode 100644 index 00000000..a935e08c --- /dev/null +++ b/Src/Notion.Client/Models/Page/PageCover/IPageCover.cs @@ -0,0 +1,10 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IPageCover + { + [JsonProperty("type")] + string Type { get; set; } + } +} diff --git a/Src/Notion.Client/Models/CustomEmoji.cs b/Src/Notion.Client/Models/Page/PageIcon/CustomEmoji.cs similarity index 69% rename from Src/Notion.Client/Models/CustomEmoji.cs rename to Src/Notion.Client/Models/Page/PageIcon/CustomEmoji.cs index 0f7a4c48..be21281b 100644 --- a/Src/Notion.Client/Models/CustomEmoji.cs +++ b/Src/Notion.Client/Models/Page/PageIcon/CustomEmoji.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Newtonsoft.Json; namespace Notion.Client @@ -12,5 +13,8 @@ public class CustomEmoji [JsonProperty("url")] public string Url { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } } } diff --git a/Src/Notion.Client/Models/Page/PageIcon/CustomEmojiPageIcon.cs b/Src/Notion.Client/Models/Page/PageIcon/CustomEmojiPageIcon.cs new file mode 100644 index 00000000..024b9cea --- /dev/null +++ b/Src/Notion.Client/Models/Page/PageIcon/CustomEmojiPageIcon.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class CustomEmojiPageIcon : IPageIcon + { + public string Type { get; set; } = PageIconTypes.CustomEmoji; + + [JsonProperty(PageIconTypes.CustomEmoji)] + public CustomEmoji CustomEmoji { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Page/PageIcon/EmojiPageIcon.cs b/Src/Notion.Client/Models/Page/PageIcon/EmojiPageIcon.cs new file mode 100644 index 00000000..cffd8808 --- /dev/null +++ b/Src/Notion.Client/Models/Page/PageIcon/EmojiPageIcon.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class EmojiPageIcon : IPageIcon + { + public string Type { get; set; } = PageIconTypes.Emoji; + + [JsonProperty(PageIconTypes.Emoji)] + public string Emoji { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Page/PageIcon/ExternalFileInfo.cs b/Src/Notion.Client/Models/Page/PageIcon/ExternalFileInfo.cs new file mode 100644 index 00000000..c6c9845e --- /dev/null +++ b/Src/Notion.Client/Models/Page/PageIcon/ExternalFileInfo.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ExternalFileInfo + { + [JsonProperty("url")] + public string Url { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Page/PageIcon/ExternalPageIcon.cs b/Src/Notion.Client/Models/Page/PageIcon/ExternalPageIcon.cs new file mode 100644 index 00000000..171d8048 --- /dev/null +++ b/Src/Notion.Client/Models/Page/PageIcon/ExternalPageIcon.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ExternalPageIcon : IPageIcon + { + public string Type { get; set; } = PageIconTypes.External; + + [JsonProperty(PageIconTypes.External)] + public ExternalFileInfo External { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Page/PageIcon/FilePageIcon.cs b/Src/Notion.Client/Models/Page/PageIcon/FilePageIcon.cs new file mode 100644 index 00000000..c37037ec --- /dev/null +++ b/Src/Notion.Client/Models/Page/PageIcon/FilePageIcon.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class FilePageIcon : IPageIcon + { + public string Type { get; set; } = PageIconTypes.File; + + [JsonProperty(PageIconTypes.File)] + public InternalFileInfo File { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Page/PageIcon/IPageIcon.cs b/Src/Notion.Client/Models/Page/PageIcon/IPageIcon.cs new file mode 100644 index 00000000..9d944217 --- /dev/null +++ b/Src/Notion.Client/Models/Page/PageIcon/IPageIcon.cs @@ -0,0 +1,16 @@ +using JsonSubTypes; +using Newtonsoft.Json; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "type")] + [JsonSubtypes.KnownSubType(typeof(EmojiPageIcon), PageIconTypes.Emoji)] + [JsonSubtypes.KnownSubType(typeof(CustomEmojiPageIcon), PageIconTypes.CustomEmoji)] + [JsonSubtypes.KnownSubType(typeof(FilePageIcon), PageIconTypes.File)] + [JsonSubtypes.KnownSubType(typeof(ExternalPageIcon), PageIconTypes.External)] + public interface IPageIcon + { + [JsonProperty("type")] + string Type { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Page/PageIcon/InternalFileInfo.cs b/Src/Notion.Client/Models/Page/PageIcon/InternalFileInfo.cs new file mode 100644 index 00000000..b1ecfef3 --- /dev/null +++ b/Src/Notion.Client/Models/Page/PageIcon/InternalFileInfo.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class InternalFileInfo + { + [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/Models/Page/PageIcon/PageIconTypes.cs b/Src/Notion.Client/Models/Page/PageIcon/PageIconTypes.cs new file mode 100644 index 00000000..526dc53c --- /dev/null +++ b/Src/Notion.Client/Models/Page/PageIcon/PageIconTypes.cs @@ -0,0 +1,10 @@ +namespace Notion.Client +{ + public static class PageIconTypes + { + public const string Emoji = "emoji"; + public const string CustomEmoji = "custom_emoji"; + public const string File = "file"; + public const string External = "external"; + } +} 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/BlockParent.cs b/Src/Notion.Client/Models/Parents/BlockParent.cs deleted file mode 100644 index e3fd7749..00000000 --- a/Src/Notion.Client/Models/Parents/BlockParent.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class BlockParent : IPageParent, IDatabaseParent, IBlockParent, ICommentParent - { - /// - /// The ID of the block that the element belongs to. - /// - [JsonProperty("block_id")] - public string BlockId { get; set; } - - /// - /// Always has a value "block_id" - /// - public ParentType Type { get; set; } - } -} diff --git a/Src/Notion.Client/Models/Parents/DatabaseParent.cs b/Src/Notion.Client/Models/Parents/DatabaseParent.cs deleted file mode 100644 index 878dbe89..00000000 --- a/Src/Notion.Client/Models/Parents/DatabaseParent.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class DatabaseParent : IPageParent, IBlockParent - { - /// - /// The ID of the database that this page belongs to. - /// - [JsonProperty("database_id")] - public string DatabaseId { get; set; } - - /// - /// Always "database_id" - /// - public ParentType Type { get; set; } - } -} diff --git a/Src/Notion.Client/Models/Parents/IParent.cs b/Src/Notion.Client/Models/Parents/IParent.cs deleted file mode 100644 index ccf3999b..00000000 --- a/Src/Notion.Client/Models/Parents/IParent.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace Notion.Client -{ - [SuppressMessage("ReSharper", "UnusedMemberInSuper.Global")] - public interface IParent - { - [JsonConverter(typeof(StringEnumConverter))] - ParentType Type { get; set; } - } -} diff --git a/Src/Notion.Client/Models/Parents/IParentOfBlock.cs b/Src/Notion.Client/Models/Parents/IParentOfBlock.cs new file mode 100644 index 00000000..61bb1ae8 --- /dev/null +++ b/Src/Notion.Client/Models/Parents/IParentOfBlock.cs @@ -0,0 +1,17 @@ +using JsonSubTypes; +using Newtonsoft.Json; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "type")] + [JsonSubtypes.KnownSubType(typeof(DatabaseParent), ParentTypes.Database)] + [JsonSubtypes.KnownSubType(typeof(DatasourceParent), ParentTypes.Datasource)] + [JsonSubtypes.KnownSubType(typeof(PageParent), ParentTypes.Page)] + [JsonSubtypes.KnownSubType(typeof(BlockParent), ParentTypes.Block)] + [JsonSubtypes.KnownSubType(typeof(WorkspaceParent), ParentTypes.Workspace)] + public interface IParentOfBlock + { + [JsonProperty("type")] + string Type { get; set; } + } +} diff --git a/Src/Notion.Client/Api/Comments/Retrieve/Response/ICommentParent.cs b/Src/Notion.Client/Models/Parents/IParentOfComment.cs similarity index 66% rename from Src/Notion.Client/Api/Comments/Retrieve/Response/ICommentParent.cs rename to Src/Notion.Client/Models/Parents/IParentOfComment.cs index 9e05d019..d68b8a1e 100644 --- a/Src/Notion.Client/Api/Comments/Retrieve/Response/ICommentParent.cs +++ b/Src/Notion.Client/Models/Parents/IParentOfComment.cs @@ -4,9 +4,11 @@ namespace Notion.Client { [JsonConverter(typeof(JsonSubtypes), "type")] - [JsonSubtypes.KnownSubTypeAttribute(typeof(PageParent), ParentType.PageId)] - [JsonSubtypes.KnownSubTypeAttribute(typeof(BlockParent), ParentType.BlockId)] - public interface ICommentParent + [JsonSubtypes.KnownSubTypeAttribute(typeof(PageParent), ParentTypes.Page)] + [JsonSubtypes.KnownSubTypeAttribute(typeof(BlockParent), ParentTypes.Block)] + public interface IParentOfComment { + [JsonProperty("type")] + string Type { get; set; } } } diff --git a/Src/Notion.Client/Models/Parents/IParentOfDatabase.cs b/Src/Notion.Client/Models/Parents/IParentOfDatabase.cs new file mode 100644 index 00000000..a6404dc2 --- /dev/null +++ b/Src/Notion.Client/Models/Parents/IParentOfDatabase.cs @@ -0,0 +1,16 @@ +using JsonSubTypes; +using Newtonsoft.Json; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "type")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(DatabaseParent), "database_id")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(PageParent), "page_id")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(WorkspaceParent), "workspace")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(BlockParent), "block_id")] + public interface IParentOfDatabase + { + [JsonProperty("type")] + string Type { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Parents/IParentOfDatasource.cs b/Src/Notion.Client/Models/Parents/IParentOfDatasource.cs new file mode 100644 index 00000000..b4eb371d --- /dev/null +++ b/Src/Notion.Client/Models/Parents/IParentOfDatasource.cs @@ -0,0 +1,14 @@ +using JsonSubTypes; +using Newtonsoft.Json; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "type")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(DatabaseParent), "database_id")] + [JsonSubtypes.KnownSubTypeAttribute(typeof(DatasourceParent), "data_source_id")] + public interface IParentOfDatasource + { + [JsonProperty("type")] + string Type { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Parents/IParentOfPage.cs b/Src/Notion.Client/Models/Parents/IParentOfPage.cs new file mode 100644 index 00000000..3480b71f --- /dev/null +++ b/Src/Notion.Client/Models/Parents/IParentOfPage.cs @@ -0,0 +1,17 @@ +using JsonSubTypes; +using Newtonsoft.Json; + +namespace Notion.Client +{ + [JsonConverter(typeof(JsonSubtypes), "type")] + [JsonSubtypes.KnownSubType(typeof(DatabaseParent), ParentTypes.Database)] + [JsonSubtypes.KnownSubType(typeof(DatasourceParent), ParentTypes.Datasource)] + [JsonSubtypes.KnownSubType(typeof(PageParent), ParentTypes.Page)] + [JsonSubtypes.KnownSubType(typeof(BlockParent), ParentTypes.Block)] + [JsonSubtypes.KnownSubType(typeof(WorkspaceParent), ParentTypes.Workspace)] + public interface IParentOfPage + { + [JsonProperty("type")] + string Type { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Parents/PageParent.cs b/Src/Notion.Client/Models/Parents/PageParent.cs deleted file mode 100644 index 565f7ccc..00000000 --- a/Src/Notion.Client/Models/Parents/PageParent.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; - -namespace Notion.Client -{ - public class PageParent : IPageParent, IDatabaseParent, IBlockParent, ICommentParent - { - /// - /// The ID of the page that this page belongs to. - /// - [JsonProperty("page_id")] - public string PageId { get; set; } - - /// - /// Always "page_id". - /// - public ParentType Type { get; set; } - } -} diff --git a/Src/Notion.Client/Models/Parents/ParentType.cs b/Src/Notion.Client/Models/Parents/ParentType.cs deleted file mode 100644 index 347414f9..00000000 --- a/Src/Notion.Client/Models/Parents/ParentType.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Runtime.Serialization; - -namespace Notion.Client -{ - [SuppressMessage("ReSharper", "UnusedMember.Global")] - public enum ParentType - { - [EnumMember(Value = null)] - Unknown, - - [EnumMember(Value = "database_id")] - DatabaseId, - - [EnumMember(Value = "page_id")] - PageId, - - [EnumMember(Value = "workspace")] - Workspace, - - [EnumMember(Value = "block_id")] - BlockId - } -} diff --git a/Src/Notion.Client/Models/Parents/ParentTypes.cs b/Src/Notion.Client/Models/Parents/ParentTypes.cs new file mode 100644 index 00000000..801ce6ac --- /dev/null +++ b/Src/Notion.Client/Models/Parents/ParentTypes.cs @@ -0,0 +1,11 @@ +namespace Notion.Client +{ + public static class ParentTypes + { + public const string Database = "database_id"; + public const string Page = "page_id"; + public const string Workspace = "workspace"; + public const string Block = "block_id"; + public const string Datasource = "data_source_id"; + } +} diff --git a/Src/Notion.Client/Models/Parents/WorkspaceParent.cs b/Src/Notion.Client/Models/Parents/WorkspaceParent.cs deleted file mode 100644 index a0b5e1c4..00000000 --- a/Src/Notion.Client/Models/Parents/WorkspaceParent.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Notion.Client -{ - public class WorkspaceParent : IPageParent, IDatabaseParent, IBlockParent - { - /// - /// Always "workspace". - /// - public ParentType Type { get; set; } - } -} diff --git a/Src/Notion.Client/Models/Parents/types/BlockParent.cs b/Src/Notion.Client/Models/Parents/types/BlockParent.cs new file mode 100644 index 00000000..f148a39e --- /dev/null +++ b/Src/Notion.Client/Models/Parents/types/BlockParent.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class BlockParent : IParentOfDatabase, IParentOfBlock, IParentOfPage, IParentOfComment + { + public string Type { get; set; } = ParentTypes.Block; + + [JsonProperty(ParentTypes.Block)] + public string BlockId { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Parents/types/DatabaseParent.cs b/Src/Notion.Client/Models/Parents/types/DatabaseParent.cs new file mode 100644 index 00000000..1fd38f59 --- /dev/null +++ b/Src/Notion.Client/Models/Parents/types/DatabaseParent.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DatabaseParent : IParentOfDatasource, IParentOfDatabase, IParentOfBlock, IParentOfPage + { + public string Type { get; set; } = ParentTypes.Database; + + [JsonProperty(ParentTypes.Database)] + public string DatabaseId { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Parents/types/DatasourceParent.cs b/Src/Notion.Client/Models/Parents/types/DatasourceParent.cs new file mode 100644 index 00000000..32369842 --- /dev/null +++ b/Src/Notion.Client/Models/Parents/types/DatasourceParent.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DatasourceParent : IParentOfDatasource, IParentOfBlock, IParentOfPage + { + public string Type { get; set; } = ParentTypes.Datasource; + + [JsonProperty(ParentTypes.Datasource)] + public string DataSourceId { get; set; } + + [JsonProperty(ParentTypes.Database)] + public string DatabaseId { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Parents/types/PageParent.cs b/Src/Notion.Client/Models/Parents/types/PageParent.cs new file mode 100644 index 00000000..f5914443 --- /dev/null +++ b/Src/Notion.Client/Models/Parents/types/PageParent.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class PageParent : IParentOfDatabase, IParentOfBlock, IParentOfPage, IParentOfComment + { + public string Type { get; set; } = ParentTypes.Page; + + [JsonProperty(ParentTypes.Page)] + public string PageId { get; set; } + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Parents/types/WorkspaceParent.cs b/Src/Notion.Client/Models/Parents/types/WorkspaceParent.cs new file mode 100644 index 00000000..504cf49d --- /dev/null +++ b/Src/Notion.Client/Models/Parents/types/WorkspaceParent.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class WorkspaceParent : IParentOfDatabase, IParentOfBlock, IParentOfPage + { + public string Type { get; set; } = ParentTypes.Workspace; + + [JsonProperty(ParentTypes.Workspace)] + public bool Workspace { get; set; } = true; + + [JsonExtensionData] + public IDictionary AdditionalData { get; set; } + } +} diff --git a/Src/Notion.Client/Models/PropertyValue/ButtonPropertyValue.cs b/Src/Notion.Client/Models/PropertyValue/ButtonPropertyValue.cs index 61ae9fc4..dc3b0e1f 100644 --- a/Src/Notion.Client/Models/PropertyValue/ButtonPropertyValue.cs +++ b/Src/Notion.Client/Models/PropertyValue/ButtonPropertyValue.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Newtonsoft.Json; +using Newtonsoft.Json; namespace Notion.Client { 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/PageCover/ExternalPageCoverRequest.cs b/Src/Notion.Client/Models/Request/PageCover/ExternalPageCoverRequest.cs new file mode 100644 index 00000000..d4fa904c --- /dev/null +++ b/Src/Notion.Client/Models/Request/PageCover/ExternalPageCoverRequest.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class ExternalPageCoverRequest : IPageCoverRequest + { + public string Type { get; set; } = PageCoverRequestTypes.External; + + [JsonProperty("external")] + public Info External { get; set; } + + public class Info + { + /// + /// The URL of the external file. + /// + [JsonProperty("url")] + public string Url { get; set; } + } + } +} diff --git a/Src/Notion.Client/Models/Request/PageCover/FileUploadPageCoverRequest.cs b/Src/Notion.Client/Models/Request/PageCover/FileUploadPageCoverRequest.cs new file mode 100644 index 00000000..89241d64 --- /dev/null +++ b/Src/Notion.Client/Models/Request/PageCover/FileUploadPageCoverRequest.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class FileUploadPageCoverRequest : IPageCoverRequest + { + public string Type { get; set; } = PageCoverRequestTypes.FileUpload; + + [JsonProperty("file")] + public Info File { get; set; } + + public class Info + { + /// + /// The ID of a FileUpload object that has the status `uploaded`. + /// + [JsonProperty("id")] + public string Id { get; set; } + } + } +} diff --git a/Src/Notion.Client/Models/Request/PageCover/IPageCoverRequest.cs b/Src/Notion.Client/Models/Request/PageCover/IPageCoverRequest.cs new file mode 100644 index 00000000..2505f901 --- /dev/null +++ b/Src/Notion.Client/Models/Request/PageCover/IPageCoverRequest.cs @@ -0,0 +1,10 @@ +using Newtonsoft.Json; + +namespace Notion.Client +{ + public interface IPageCoverRequest + { + [JsonProperty("type")] + string Type { get; set; } + } +} diff --git a/Src/Notion.Client/Models/Request/PageCover/PageCoverRequestTypes.cs b/Src/Notion.Client/Models/Request/PageCover/PageCoverRequestTypes.cs new file mode 100644 index 00000000..594da3f9 --- /dev/null +++ b/Src/Notion.Client/Models/Request/PageCover/PageCoverRequestTypes.cs @@ -0,0 +1,8 @@ +namespace Notion.Client +{ + public static class PageCoverRequestTypes + { + public const string External = "external"; + public const string FileUpload = "file_upload"; + } +} diff --git a/Src/Notion.Client/Models/Request/PageIcon/CustomEmojiPageIconRequest.cs b/Src/Notion.Client/Models/Request/PageIcon/CustomEmojiPageIconRequest.cs new file mode 100644 index 00000000..7764f461 --- /dev/null +++ b/Src/Notion.Client/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/Models/Request/PageIcon/CustomEmojiRequest.cs b/Src/Notion.Client/Models/Request/PageIcon/CustomEmojiRequest.cs new file mode 100644 index 00000000..d3840836 --- /dev/null +++ b/Src/Notion.Client/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/Models/Request/PageIcon/EmojiPageIconRequest.cs b/Src/Notion.Client/Models/Request/PageIcon/EmojiPageIconRequest.cs new file mode 100644 index 00000000..b343bbd8 --- /dev/null +++ b/Src/Notion.Client/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/Models/Request/PageIcon/ExternalPageIconRequest.cs b/Src/Notion.Client/Models/Request/PageIcon/ExternalPageIconRequest.cs new file mode 100644 index 00000000..da7ceded --- /dev/null +++ b/Src/Notion.Client/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/Models/Request/PageIcon/FileUploadIconRequest.cs b/Src/Notion.Client/Models/Request/PageIcon/FileUploadIconRequest.cs new file mode 100644 index 00000000..bbfd5f74 --- /dev/null +++ b/Src/Notion.Client/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/Models/Request/PageIcon/IPageIconRequest.cs b/Src/Notion.Client/Models/Request/PageIcon/IPageIconRequest.cs new file mode 100644 index 00000000..5973a09b --- /dev/null +++ b/Src/Notion.Client/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/Models/Request/Parents/DataSourceParentRequest.cs b/Src/Notion.Client/Models/Request/Parents/DataSourceParentRequest.cs new file mode 100644 index 00000000..a4239b68 --- /dev/null +++ b/Src/Notion.Client/Models/Request/Parents/DataSourceParentRequest.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Notion.Client +{ + public class DataSourceParentRequest : IParentOfPageRequest, IParentOfDataSourceRequest + { + [JsonProperty("type")] + public string Type => "data_source_id"; + + [JsonProperty("data_source_id")] + public string DataSourceId { get; set; } + + [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/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/IParentOfDataSourceRequest.cs b/Src/Notion.Client/Models/Request/Parents/IParentOfDataSourceRequest.cs new file mode 100644 index 00000000..48d5378c --- /dev/null +++ b/Src/Notion.Client/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/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..3fbb716b 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() ); } @@ -35,7 +35,7 @@ public async Task AppendChildrenAsync_AppendsBlocksGivenBlocks() BlockId = _page.Id, Children = new List { - new BreadcrumbBlockRequest { Breadcrumb = new BreadcrumbBlockRequest.Data() }, + new BreadcrumbBlockRequest { Parent= new PageParent() {PageId = Guid.NewGuid().ToString()}, Breadcrumb = new BreadcrumbBlockRequest.Data() }, new DividerBlockRequest { Divider = new DividerBlockRequest.Data() }, new TableOfContentsBlockRequest { TableOfContents = new TableOfContentsBlockRequest.Data() }, new CalloutBlockRequest @@ -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..9967b130 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() ); } @@ -28,7 +28,7 @@ public async Task DisposeAsync() public async Task ShouldCreatePageComment() { // Arrange - var parameters = CreateCommentParameters.CreatePageComment( + var parameters = CreateCommentRequest.CreatePageComment( new ParentPageInput { PageId = _page.Id }, new List { new RichTextTextInput { Text = new Text { Content = "This is a comment" } } } ); @@ -56,7 +56,7 @@ public async Task ShouldCreateADiscussionComment() { // Arrange var comment = await Client.Comments.CreateAsync( - CreateCommentParameters.CreatePageComment( + CreateCommentRequest.CreatePageComment( new ParentPageInput { PageId = _page.Id }, new List { @@ -67,7 +67,7 @@ public async Task ShouldCreateADiscussionComment() // Act var response = await Client.Comments.CreateAsync( - CreateCommentParameters.CreateDiscussionComment( + CreateCommentRequest.CreateDiscussionComment( comment.DiscussionId, new List { diff --git a/Test/Notion.IntegrationTests/DataSourcesClientTests.cs b/Test/Notion.IntegrationTests/DataSourcesClientTests.cs new file mode 100644 index 00000000..1dde43be --- /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 TitleDataSourcePropertyConfigRequest { + 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 TitleDataSourcePropertyConfigRequest { + Description = "The name of the data source", + Title = new Dictionary() + } + }, + { + "Status", + new SelectDataSourcePropertyConfigRequest { + Description = "The status of the data source", + Select = new SelectDataSourcePropertyConfigRequest.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 SelectDataSourcePropertyConfigRequest + { + Description = "Updated status of the data source", + Select = new SelectDataSourcePropertyConfigRequest.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 TitleDataSourcePropertyConfigRequest { + 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 RelationDataSourcePropertyConfigRequest + { + Relation = new SinglePropertyRelationInfoRequest + { + DataSourceId = createdSourceDatabase.DataSources.First().DataSourceId, + SingleProperty = new Dictionary() + } + } + } + }, + { + "Dual Relation", + new UpdatePropertyConfigurationRequest + { + Name = "Dual Relation", + PropertyRequest = new RelationDataSourcePropertyConfigRequest + { + Relation = new DualPropertyRelationInfoRequest + { + DataSourceId = createdSourceDatabase.DataSources.First().DataSourceId, + DualProperty = new DualPropertyRelationInfoRequest.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 TitleDataSourcePropertyConfigRequest { 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..88f6e95f 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 TitleDataSourcePropertyConfigRequest { 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 TitleDataSourcePropertyConfigRequest { 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/Notion.IntegrationTests.csproj b/Test/Notion.IntegrationTests/Notion.IntegrationTests.csproj index 65f2c257..6e7e4f5e 100644 --- a/Test/Notion.IntegrationTests/Notion.IntegrationTests.csproj +++ b/Test/Notion.IntegrationTests/Notion.IntegrationTests.csproj @@ -1,7 +1,7 @@ - net6.0 + net10.0 enable false diff --git a/Test/Notion.IntegrationTests/PageClientTests.cs b/Test/Notion.IntegrationTests/PageClientTests.cs index 4938bcfa..d30157ce 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 TitleDataSourcePropertyConfigRequest { Title = new Dictionary() } }, { - Select = new OptionWrapper + "TestSelect", + new SelectDataSourcePropertyConfigRequest { - Options = new List + Select = new SelectDataSourcePropertyConfigRequest.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 NumberDataSourcePropertyConfigRequest { Number = new NumberDataSourcePropertyConfigRequest.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 TitleDataSourcePropertyConfigRequest { Title = new Dictionary() } + } + }, { "Test Date Property", - new DateUpdatePropertySchema { Date = new Dictionary() } + new UpdatePropertyConfigurationRequest + { + Name = DatePropertyName, + PropertyRequest = new DateDataSourcePropertyConfigRequest + { + 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 TitleDataSourcePropertyConfigRequest { Title = new Dictionary() } }, { - Select = new OptionWrapper + "Colors1", + new SelectDataSourcePropertyConfigRequest { - Options = new List + Select = new SelectDataSourcePropertyConfigRequest.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 SelectDataSourcePropertyConfigRequest { - Options = new List + Select = new SelectDataSourcePropertyConfigRequest.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..94e5a894 --- /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 DataSource + { + 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 +} 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/FileUploadsClientTests.cs b/Test/Notion.UnitTests/FileUploadsClientTests.cs index b29f26da..ef91de08 100644 --- a/Test/Notion.UnitTests/FileUploadsClientTests.cs +++ b/Test/Notion.UnitTests/FileUploadsClientTests.cs @@ -41,14 +41,14 @@ public async Task CreateAsync_CallsRestClientPostAsync_WithCorrectParameters() Mode = FileUploadMode.SinglePart, }; - var expectedResponse = new CreateFileUploadResponse + var expectedResponse = new FileUpload { UploadUrl = "https://example.com/upload", Id = Guid.NewGuid().ToString(), }; _restClientMock - .Setup(client => client.PostAsync( + .Setup(client => client.PostAsync( It.Is(url => url == ApiEndpoints.FileUploadsApiUrls.Create()), It.IsAny(), It.IsAny>>(), @@ -114,14 +114,14 @@ public async Task SendAsync_DoesNotThrow_WhenPartNumberIsValid(string partNumber // Arrange var request = SendFileUploadRequest.Create(fileUploadId: "valid-id", file: new FileData { FileName = "testfile.txt", Data = new System.IO.MemoryStream(), ContentType = "text/plain" }, partNumber: partNumber); - var expectedResponse = new SendFileUploadResponse + var expectedResponse = new FileUpload { Id = "valid-id", Status = "uploaded", }; _restClientMock - .Setup(client => client.PostAsync( + .Setup(client => client.PostAsync( It.Is(url => url == ApiEndpoints.FileUploadsApiUrls.Send("valid-id")), It.IsAny(), It.IsAny>>(), @@ -154,14 +154,14 @@ public async Task SendAsync_CallsRestClientPostAsync_WithCorrectParameters() } ); - var expectedResponse = new SendFileUploadResponse + var expectedResponse = new FileUpload { Id = fileUploadId.ToString(), Status = "uploaded", }; _restClientMock - .Setup(client => client.PostAsync( + .Setup(client => client.PostAsync( It.Is(url => url == ApiEndpoints.FileUploadsApiUrls.Send(fileUploadId)), It.IsAny(), It.IsAny>>(), @@ -202,7 +202,7 @@ public async Task ListAsync_CallsRestClientGetAsync_WithCorrectParameters() )) .ReturnsAsync(new ListFileUploadsResponse { - Results = new List + Results = new List { new() { Id = "file1", Status = "completed" }, new() { Id = "file2", Status = "completed" } @@ -248,7 +248,7 @@ public async Task RetrieveAsync_CallsRestClientGetAsync_WithCorrectParameters() FileUploadId = fileUploadId }; - var expectedResponse = new RetrieveFileUploadResponse + var expectedResponse = new FileUpload { Id = fileUploadId, FileName = "testfile.txt", @@ -256,7 +256,7 @@ public async Task RetrieveAsync_CallsRestClientGetAsync_WithCorrectParameters() }; _restClientMock - .Setup(client => client.GetAsync( + .Setup(client => client.GetAsync( It.Is(url => url == ApiEndpoints.FileUploadsApiUrls.Retrieve(request)), It.IsAny>(), null, diff --git a/Test/Notion.UnitTests/HelperAsserts.cs b/Test/Notion.UnitTests/HelperAsserts.cs deleted file mode 100644 index 3b1a29ec..00000000 --- a/Test/Notion.UnitTests/HelperAsserts.cs +++ /dev/null @@ -1,44 +0,0 @@ -using FluentAssertions; -using Notion.Client; - -namespace Notion.UnitTests; - -public static class HelperAsserts -{ - public static void IPageIconAsserts(IPageIcon icon) - { - icon.Should().NotBeNull(); - - switch (icon) - { - case EmojiObject emoji: - emoji.Emoji.Should().NotBeNull(); - - break; - case FileObject fileObject: - FileObjectAsserts(fileObject); - - break; - } - } - - public static void FileObjectAsserts(FileObject fileObject) - { - fileObject.Should().NotBeNull(); - - switch (fileObject) - { - case UploadedFile uploadedFile: - uploadedFile.File.Should().NotBeNull(); - uploadedFile.File.Url.Should().NotBeNull(); - uploadedFile.File.ExpiryTime.Should().NotBeSameDateAs(default); - - break; - case ExternalFile externalFile: - externalFile.External.Should().NotBeNull(); - externalFile.External.Url.Should().NotBeNull(); - - break; - } - } -} diff --git a/Test/Notion.UnitTests/Notion.UnitTests.csproj b/Test/Notion.UnitTests/Notion.UnitTests.csproj index 79529e8c..e6607e52 100644 --- a/Test/Notion.UnitTests/Notion.UnitTests.csproj +++ b/Test/Notion.UnitTests/Notion.UnitTests.csproj @@ -1,7 +1,7 @@ - net6.0 + net10.0 false diff --git a/Test/Notion.UnitTests/PagesClientTests.cs b/Test/Notion.UnitTests/PagesClientTests.cs index 4dc75380..2d4a9734 100644 --- a/Test/Notion.UnitTests/PagesClientTests.cs +++ b/Test/Notion.UnitTests/PagesClientTests.cs @@ -37,7 +37,7 @@ public async Task RetrieveAsync() page.Url.Should().Be("https://www.notion.so/Avocado-251d2b5f268c4de2afe9c71ff92ca95c"); page.Id.Should().Be(pageId); - page.Parent.Type.Should().Be(ParentType.DatabaseId); + page.Parent.Type.Should().Be(ParentTypes.Database); ((DatabaseParent)page.Parent).DatabaseId.Should().Be("48f8fee9-cd79-4180-bc2f-ec0398253067"); page.InTrash.Should().BeFalse(); } @@ -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..50da9d68 --- /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 SelectDataSourcePropertyConfigRequest + { + Description = "Task status", + Select = new SelectDataSourcePropertyConfigRequest.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 TitleDataSourcePropertyConfigRequest + { + 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 SelectDataSourcePropertyConfigRequest + { + Description = "Task status" + } + } + }, + { + "Title", + new UpdatePropertyConfigurationRequest + { + Name = "Task Name", + PropertyRequest = new TitleDataSourcePropertyConfigRequest + { + 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..bea32bd4 --- /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 : DataSourcePropertyConfigRequest + { + // 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 TitleDataSourcePropertyConfigRequest + { + 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 TitleDataSourcePropertyConfigRequest + { + 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 CheckboxDataSourcePropertyConfigRequest + { + 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 TitleDataSourcePropertyConfigRequest + { + 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 UniqueIdDataSourcePropertyConfigRequest + { + Type = "unique_id", + Description = "Unique ID description", + UniqueId = new UniqueIdDataSourcePropertyConfigRequest.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