From 6658ac62a350e539e10adbe761952a58a2274a87 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Tue, 27 Jul 2021 17:16:15 -0500 Subject: [PATCH 01/42] Fix typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4f035d9..31e2a3f 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ See the [ROADMAP](ROADMAP.md) file to see what is coming next. - [Append blocks children](#append-blocks-children) - [Create a page](#create-a-page) - [Errors](#errors) - - [Create page with chidren](#create-page-with-chidren) + - [Create page with children](#create-page-with-children) - [Contributions](#contributions) - [Rules](#rules) - [Tests](#tests) @@ -104,7 +104,7 @@ notion.pages.create(page); # Errors Some errors that I have encounter and still don't know how to solve because are errors that also occur on Postman are: -## Create page with chidren +## Create page with children When the parent is a page the error is: ```json "body failed validation: body.properties.title.type should be an array, instead was `\"array\"`." From 0b443d16203e2078bcf7c13daae65b250fc1a184 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 28 Jul 2021 12:44:53 -0500 Subject: [PATCH 02/42] Add `text` constructor for blocks Constructor for blocks with single `Text` instance in content. Also refactor blocks main constructors to make it shorter. --- lib/notion/blocks/bulleted_list_item.dart | 24 +++++++---- lib/notion/blocks/heading.dart | 49 ++++++++++++++--------- lib/notion/blocks/numbered_list_item.dart | 24 +++++++---- lib/notion/blocks/paragraph.dart | 25 ++++++++---- lib/notion/blocks/todo.dart | 26 ++++++++---- lib/notion/blocks/toggle.dart | 24 +++++++---- test/blocks/bulleted_list_item_test.dart | 28 +++++++++++++ test/blocks/heading_test.dart | 21 ++++++++++ test/blocks/numbered_list_item_test.dart | 28 +++++++++++++ test/blocks/paragraph_test.dart | 28 +++++++++++++ test/blocks/todo_test.dart | 30 ++++++++++++++ test/blocks/toggle_test.dart | 28 +++++++++++++ 12 files changed, 280 insertions(+), 55 deletions(-) diff --git a/lib/notion/blocks/bulleted_list_item.dart b/lib/notion/blocks/bulleted_list_item.dart index 5288aad..87df582 100644 --- a/lib/notion/blocks/bulleted_list_item.dart +++ b/lib/notion/blocks/bulleted_list_item.dart @@ -24,13 +24,23 @@ class BulletedListItem extends Block { Text? text, List texts: const [], List children: const [], - }) { - if (text != null) { - _content.add(text); - } - _content.addAll(texts); - _children.addAll(children); - } + }) : this._content = [ + if (text != null) text, + ...texts, + ], + this._children = children; + + /// BulletedListItem constructor with a single `Text` instance as content. + /// + /// This constructor should receive the [content] as a single String. + /// + /// Can also receive the [annotations] of the single `Text` element and the [children] of this block. + BulletedListItem.text( + String content, { + TextAnnotations? annotations, + List children: const [], + }) : this._content = [Text(content, annotations: annotations)], + this._children = children; /// Add a [text] to the rich text array and returns this instance. Also can receive the [annotations] of the text. BulletedListItem addText(String text, {TextAnnotations? annotations}) { diff --git a/lib/notion/blocks/heading.dart b/lib/notion/blocks/heading.dart index 03fa8dd..b1c7ac3 100644 --- a/lib/notion/blocks/heading.dart +++ b/lib/notion/blocks/heading.dart @@ -20,28 +20,25 @@ class Heading extends Block { /// Also can receive the [type] of the heading as an integer between 1 and 3. Set to 1 by default when no specified or when is out of the range declared before. Heading({ Text? text, - List? texts, + List texts: const [], int type: 1, - }) { - if (text != null) { - _content.add(text); - } - if (texts != null) { - _content.addAll(texts); - } + }) : this._content = [ + if (text != null) text, + ...texts, + ], + this.type = headingTypeFromInt(type); - switch (type) { - case 3: - this.type = BlockTypes.H3; - break; - case 2: - this.type = BlockTypes.H2; - break; - case 1: - default: - this.type = BlockTypes.H1; - } - } + /// Heading constructor with a single `Text` instance as content. + /// + /// This constructor should receive the [content] as a single String. + /// + /// Can also receive the [annotations] of the single `Text` element and the [children] of this block. + Heading.text( + String content, { + TextAnnotations? annotations, + int type: 1, + }) : this._content = [Text(content, annotations: annotations)], + this.type = headingTypeFromInt(type); /// Add a new [text] to the paragraph content and returns this instance. @Deprecated('Use `addText(Block)` instead') @@ -65,4 +62,16 @@ class Heading extends Block { 'text': _content.map((e) => e.toJson()).toList(), }, }; + + static BlockTypes headingTypeFromInt(int type) { + switch (type) { + case 3: + return BlockTypes.H3; + case 2: + return BlockTypes.H2; + case 1: + default: + return BlockTypes.H1; + } + } } diff --git a/lib/notion/blocks/numbered_list_item.dart b/lib/notion/blocks/numbered_list_item.dart index 7dc93c8..650082b 100644 --- a/lib/notion/blocks/numbered_list_item.dart +++ b/lib/notion/blocks/numbered_list_item.dart @@ -24,13 +24,23 @@ class NumberedListItem extends Block { Text? text, List texts: const [], List children: const [], - }) { - if (text != null) { - _content.add(text); - } - _content.addAll(texts); - _children.addAll(children); - } + }) : this._content = [ + if (text != null) text, + ...texts, + ], + this._children = children; + + /// NumberedListItem constructor with a single `Text` instance as content. + /// + /// This constructor should receive the [content] as a single String. + /// + /// Can also receive the [annotations] of the single `Text` element and the [children] of this block. + NumberedListItem.text( + String content, { + TextAnnotations? annotations, + List children: const [], + }) : this._content = [Text(content, annotations: annotations)], + this._children = children; /// Add a [text] to the rich text array and returns this instance. Also can receive the [annotations] of the text. NumberedListItem addText(String text, {TextAnnotations? annotations}) { diff --git a/lib/notion/blocks/paragraph.dart b/lib/notion/blocks/paragraph.dart index a3c0e97..49e1bf7 100644 --- a/lib/notion/blocks/paragraph.dart +++ b/lib/notion/blocks/paragraph.dart @@ -37,13 +37,24 @@ class Paragraph extends Block { List texts: const [], List children: const [], @deprecated this.textSeparator: ' ', - }) { - if (text != null) { - this._content.add(text); - } - this._content.addAll(texts); - this._children.addAll(children); - } + }) : this._content = [ + if (text != null) text, + ...texts, + ], + this._children = children; + + /// Paragraph constructor with a single `Text` instance as content. + /// + /// This constructor should receive the [content] as a single String. + /// + /// Can also receive the [annotations] of the single `Text` element and the [children] of this block. + Paragraph.text( + String content, { + TextAnnotations? annotations, + List children: const [], + }) : this.textSeparator = ' ', + this._content = [Text(content, annotations: annotations)], + this._children = children; /// Add a new [text] to the paragraph content and returns this instance. @Deprecated('Use `addText(Block)` instead') diff --git a/lib/notion/blocks/todo.dart b/lib/notion/blocks/todo.dart index 056696e..cae8a3f 100644 --- a/lib/notion/blocks/todo.dart +++ b/lib/notion/blocks/todo.dart @@ -39,13 +39,25 @@ class ToDo extends Block { List children: const [], this.checked: false, @deprecated this.textSeparator: ' ', - }) { - if (text != null) { - this._content.add(text); - } - this._content.addAll(texts); - this._children.addAll(children); - } + }) : this._content = [ + if (text != null) text, + ...texts, + ], + this._children = children; + + /// ToDo constructor with a single `Text` instance as content. + /// + /// This constructor should receive the [content] as a single String. + /// + /// Can also receive the [annotations] of the single `Text` element and the [children] of this block. + ToDo.text( + String content, { + TextAnnotations? annotations, + List children: const [], + this.checked: false, + }) : this.textSeparator = ' ', + this._content = [Text(content, annotations: annotations)], + this._children = children; // TODO: A function that create an instance of ToDo (or Paragraph or Heading) from a Block. // diff --git a/lib/notion/blocks/toggle.dart b/lib/notion/blocks/toggle.dart index db15fd1..4d1281f 100644 --- a/lib/notion/blocks/toggle.dart +++ b/lib/notion/blocks/toggle.dart @@ -24,13 +24,23 @@ class Toggle extends Block { Text? text, List texts: const [], List children: const [], - }) { - if (text != null) { - _content.add(text); - } - _content.addAll(texts); - _children.addAll(children); - } + }) : this._content = [ + if (text != null) text, + ...texts, + ], + this._children = children; + + /// Toggle constructor with a single `Text` instance as content. + /// + /// This constructor should receive the [content] as a single String. + /// + /// Can also receive the [annotations] of the single `Text` element and the [children] of this block. + Toggle.text( + String content, { + TextAnnotations? annotations, + List children: const [], + }) : this._content = [Text(content, annotations: annotations)], + this._children = children; /// Add a [text] to the rich text array and returns this instance. Also can receive the [annotations] of the text. Toggle addText(String text, {TextAnnotations? annotations}) { diff --git a/test/blocks/bulleted_list_item_test.dart b/test/blocks/bulleted_list_item_test.dart index 30199ea..582b387 100644 --- a/test/blocks/bulleted_list_item_test.dart +++ b/test/blocks/bulleted_list_item_test.dart @@ -19,6 +19,34 @@ void main() { expect(block.type, BlockTypes.BulletedListItem); }); + test('Create an instance with text constructor', () { + BulletedListItem block = BulletedListItem.text( + 'This is a paragraph with a single text', + annotations: TextAnnotations(bold: true), + children: [ + Paragraph.text('This is a children'), + ], + ); + + expect( + block.content, + allOf([ + isList, + isNotEmpty, + hasLength( + 1, + ) + ])); + expect(block.content.first.annotations!.bold, isTrue); + expect( + block.children, + allOf([ + isList, + isNotEmpty, + hasLength(1), + ])); + }); + test('Create an instance with information', () { BulletedListItem block = BulletedListItem(text: Text('A')).addText('B'); diff --git a/test/blocks/heading_test.dart b/test/blocks/heading_test.dart index 5955ce0..652a20f 100644 --- a/test/blocks/heading_test.dart +++ b/test/blocks/heading_test.dart @@ -1,4 +1,5 @@ import 'package:notion_api/notion/blocks/heading.dart'; +import 'package:notion_api/notion/blocks/paragraph.dart'; import 'package:notion_api/notion/general/rich_text.dart'; import 'package:notion_api/notion/general/types/notion_types.dart'; import 'package:notion_api/utils/utils.dart'; @@ -16,6 +17,26 @@ void main() { expect(heading.type, BlockTypes.H1); }); + test('Create an instance with text constructor', () { + Heading heading = Heading.text( + 'This is a paragraph with a single text', + annotations: TextAnnotations(bold: true), + type: 2, + ); + + expect( + heading.content, + allOf([ + isList, + isNotEmpty, + hasLength( + 1, + ) + ])); + expect(heading.content.first.annotations!.bold, isTrue); + expect(heading.type, BlockTypes.H2); + }); + test('Create an instance of every heading type', () { Heading h1 = Heading(type: 1); expect(h1.strType, blockTypeToString(BlockTypes.H1)); diff --git a/test/blocks/numbered_list_item_test.dart b/test/blocks/numbered_list_item_test.dart index 1ce3b57..6fbb85b 100644 --- a/test/blocks/numbered_list_item_test.dart +++ b/test/blocks/numbered_list_item_test.dart @@ -18,6 +18,34 @@ void main() { expect(block.type, BlockTypes.NumberedListItem); }); + test('Create an instance with text constructor', () { + NumberedListItem block = NumberedListItem.text( + 'This is a paragraph with a single text', + annotations: TextAnnotations(bold: true), + children: [ + Paragraph.text('This is a children'), + ], + ); + + expect( + block.content, + allOf([ + isList, + isNotEmpty, + hasLength( + 1, + ) + ])); + expect(block.content.first.annotations!.bold, isTrue); + expect( + block.children, + allOf([ + isList, + isNotEmpty, + hasLength(1), + ])); + }); + test('Create an instance with information', () { NumberedListItem block = NumberedListItem(text: Text('A')).addText('B'); diff --git a/test/blocks/paragraph_test.dart b/test/blocks/paragraph_test.dart index 52e97c4..b5afeda 100644 --- a/test/blocks/paragraph_test.dart +++ b/test/blocks/paragraph_test.dart @@ -17,6 +17,34 @@ void main() { expect(paragraph.type, BlockTypes.Paragraph); }); + test('Create an instance with text constructor', () { + Paragraph paragraph = Paragraph.text( + 'This is a paragraph with a single text', + annotations: TextAnnotations(bold: true), + children: [ + Paragraph.text('This is a children'), + ], + ); + + expect( + paragraph.content, + allOf([ + isList, + isNotEmpty, + hasLength( + 1, + ) + ])); + expect(paragraph.content.first.annotations!.bold, isTrue); + expect( + paragraph.children, + allOf([ + isList, + isNotEmpty, + hasLength(1), + ])); + }); + test('Create an instance with information', () { Paragraph paragraph = Paragraph().addText('A').addText('B'); diff --git a/test/blocks/todo_test.dart b/test/blocks/todo_test.dart index d01765f..54ea198 100644 --- a/test/blocks/todo_test.dart +++ b/test/blocks/todo_test.dart @@ -19,6 +19,36 @@ void main() { expect(todo.type, BlockTypes.ToDo); }); + test('Create an instance with text constructor', () { + ToDo toDo = ToDo.text( + 'This is a ToDo with a single text', + annotations: TextAnnotations(bold: true), + checked: true, + children: [ + Paragraph.text('This is a children'), + ], + ); + + expect( + toDo.content, + allOf([ + isList, + isNotEmpty, + hasLength( + 1, + ) + ])); + expect(toDo.content.first.annotations!.bold, isTrue); + expect(toDo.checked, isTrue); + expect( + toDo.children, + allOf([ + isList, + isNotEmpty, + hasLength(1), + ])); + }); + test('Create an instance with information', () { ToDo todo = ToDo(text: Text('A'), checked: true).addText('B'); diff --git a/test/blocks/toggle_test.dart b/test/blocks/toggle_test.dart index 9cb07a4..33ed81b 100644 --- a/test/blocks/toggle_test.dart +++ b/test/blocks/toggle_test.dart @@ -20,6 +20,34 @@ void main() { expect(block.type, BlockTypes.Toggle); }); + test('Create an instance with text constructor', () { + Toggle block = Toggle.text( + 'This is a paragraph with a single text', + annotations: TextAnnotations(bold: true), + children: [ + Paragraph.text('This is a children'), + ], + ); + + expect( + block.content, + allOf([ + isList, + isNotEmpty, + hasLength( + 1, + ) + ])); + expect(block.content.first.annotations!.bold, isTrue); + expect( + block.children, + allOf([ + isList, + isNotEmpty, + hasLength(1), + ])); + }); + test('Create an instance with information', () { Toggle block = Toggle(text: Text('A')) .addText('B') From c7e1fb7821091ea04957c901320b3500a5456d23 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 28 Jul 2021 13:43:29 -0500 Subject: [PATCH 03/42] Add shortcut constructors for text styles Add `bold`: Set text to bold. Add `italic`: Set text to italic. Add `underline`: Set text to underline. Add `code`: Set text to code style. Add `color`: Set a different color for the text. Add static list method to generate textual lists with `Text` instances. --- lib/notion/general/rich_text.dart | 102 ++++++++++++++++++++++++++++++ test/notion_api_test.dart | 16 ++++- test/rich_text_test.dart | 70 ++++++++++++++++++++ 3 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 test/rich_text_test.dart diff --git a/lib/notion/general/rich_text.dart b/lib/notion/general/rich_text.dart index 47201b9..6aef521 100644 --- a/lib/notion/general/rich_text.dart +++ b/lib/notion/general/rich_text.dart @@ -19,6 +19,108 @@ class Text { /// Required the [text] itself. Also can receive the [annotations] and/or the [url] of the text. Text(this.text, {this.annotations, this.url}); + /// Text constructor with **bold** content by default. + /// + /// Only can receive the [text] itself and the [color]. + Text.bold( + this.text, { + ColorsTypes color: ColorsTypes.Default, + }) : this.annotations = TextAnnotations(bold: true, color: color); + + /// Text constructor with _italic_ content by default. + /// + /// Only can receive the [text] itself and the [color]. + Text.italic( + this.text, { + ColorsTypes color: ColorsTypes.Default, + }) : this.annotations = TextAnnotations(italic: true, color: color); + + /// Text constructor with `code` content by default. + /// + /// Only can receive the [text] itself and the [color]. + Text.code( + this.text, { + ColorsTypes color: ColorsTypes.Default, + }) : this.annotations = TextAnnotations(code: true, color: color); + + /// Text constructor with underline content by default. + /// + /// Only can receive the [text] itself and the [color]. + Text.underline( + this.text, { + ColorsTypes color: ColorsTypes.Default, + }) : this.annotations = TextAnnotations(underline: true, color: color); + + /// Text constructor to change the default color of a text. + /// + /// Only can receive the [text] itself and the [color]. + Text.color( + this.text, { + ColorsTypes color: ColorsTypes.Default, + }) : this.annotations = TextAnnotations(color: color); + + /// Text mapper for lists. + /// + /// Can receive the list of [texts] the [separator] (by default ", ") and the [lastSeparator] (by default " and "). + /// + /// This static method generates a list of "Text" instances in the style of a textual list. + /// + /// Example: + /// ```dart + /// Paragraph( + /// texts: [ + /// Text('Some programming languages are '), + /// ...Text.list(texts: [ + /// Text.color('Java', color: ColorsTypes.Green), + /// Text.color('Javascript', color: ColorsTypes.Blue), + /// Text.color('PHP', color: ColorsTypes.Purple), + /// Text.color('Dart', color: ColorsTypes.Orange), + /// ]), + /// Text('.'), + /// ], + /// ); + /// ``` + /// Should print: _"Java, Javascript, PHP and Dart"_ but each element with his own style. + /// + /// Otherwise the code should be: + /// ```dart + /// Paragraph( + /// texts: [ + /// Text('Some programming languages are '), + /// Text.color('Java', color: ColorsTypes.Green), + /// Text(', '), + /// Text.color('Javascript', color: ColorsTypes.Blue), + /// Text(', '), + /// Text.color('PHP', color: ColorsTypes.Purple), + /// Text(' and '), + /// Text.color('Dart', color: ColorsTypes.Orange), + /// Text('.'), + /// ], + /// ); + /// ``` + static List list({ + required List texts, + String separator: ', ', + String lastSeparator: ' and ', + }) { + List list = []; + texts.asMap().forEach((index, element) { + if (index == texts.length - 1) { + // last element + list.add(element); + } else { + if (index == texts.length - 2) { + // penultimate element + list.addAll([element, Text(lastSeparator)]); + } else { + // any other element + list.addAll([element, Text(separator)]); + } + } + }); + return list; + } + /// Create a new Text instance from json. /// /// Receive a [json] from where the information is extracted. diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index 71999a8..5e3ef69 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -134,10 +134,20 @@ void main() { ), Text('.'), ]), + Paragraph.text( + 'Also, if your paragraph will have the same style you can write all your text directly like this to avoid using a list. This constructor can be found for every block.', + ), Paragraph( - text: Text( - 'Also, if your paragraph will have the same style you can write all your text directly like this to avoid using a list.', - ), + texts: [ + Text('There are a few shortcuts for basic styles like: '), + ...Text.list(texts: [ + Text.bold('all text bold and green', color: ColorsTypes.Green), + Text.code('all text code'), + Text.italic('all text italic'), + Text.underline('all text underline'), + ]), + Text('.'), + ], ), ]), Heading(text: Text('Blocks'), type: 2), diff --git a/test/rich_text_test.dart b/test/rich_text_test.dart new file mode 100644 index 0000000..e02fa12 --- /dev/null +++ b/test/rich_text_test.dart @@ -0,0 +1,70 @@ +import 'package:notion_api/notion/general/rich_text.dart'; +import 'package:notion_api/notion/general/types/notion_types.dart'; +import 'package:test/test.dart'; + +void main() { + group('Rich text tests', () { + test('Create instances of Text with default styles', () { + Text bold = + Text.bold('This text is bold and green', color: ColorsTypes.Green); + Text underline = Text.underline('This text is underline'); + Text code = Text.code('This text is code'); + Text italic = Text.italic('This text is italic'); + + Text green = Text.color('This text is green', color: ColorsTypes.Green); + Text blue = Text.color('This text is blue', color: ColorsTypes.Blue); + + expect(bold.annotations!.bold, isTrue); + expect(bold.annotations!.color, ColorsTypes.Green); + expect(underline.annotations!.underline, isTrue); + expect(code.annotations!.code, isTrue); + expect(italic.annotations!.italic, isTrue); + + expect(green.annotations!.color, ColorsTypes.Green); + expect(blue.annotations!.color, ColorsTypes.Blue); + }); + + test('Create a list of instances of Text', () { + List list = Text.list(texts: [ + Text('A'), + Text('B'), + Text('C'), + ]); + + expect(list.length, 5); + }); + + test('Create a list of instances of Text (one element)', () { + List list = Text.list(texts: [Text('A')]); + + expect(list.length, 1); + }); + + test('Create a list of instances of Text (two element)', () { + List list = Text.list(texts: [Text('A'), Text('B')]); + + expect(list.length, 3); + expect(list[list.length - 2].text, ' and '); + }); + + test('Create a list of instances of Text (three element)', () { + List list = Text.list(texts: [Text('A'), Text('B'), Text('C')]); + + expect(list.length, 5); + expect(list[list.length - 2].text, ' and '); + expect(list[1].text, ', '); + }); + + test('Create a list of instances of Text (custom separators)', () { + List list = Text.list( + texts: [Text('A'), Text('B'), Text('C')], + separator: '; ', + lastSeparator: ' y ', + ); + + expect(list.length, 5); + expect(list[list.length - 2].text, ' y '); + expect(list[1].text, '; '); + }); + }); +} From b9e91df3dacb3e24a9dcca398f36a635f2e332f0 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 28 Jul 2021 13:48:04 -0500 Subject: [PATCH 04/42] Update example --- example/example.md | 41 ++++++++++++++++++--------------------- test/notion_api_test.dart | 25 ++++++------------------ 2 files changed, 25 insertions(+), 41 deletions(-) diff --git a/example/example.md b/example/example.md index 23a0e01..378ef2f 100644 --- a/example/example.md +++ b/example/example.md @@ -447,31 +447,28 @@ Children fullContent = Children.withBlocks([ Text( 'You can also have children for some blocks like ', ), - Text( - 'Paragraph', - annotations: TextAnnotations(code: true), - ), - Text(', '), - Text( - 'ToDo', - annotations: TextAnnotations(code: true), - ), - Text(', '), - Text( - 'BulletedListItems', - annotations: TextAnnotations(code: true), - ), - Text(' or '), - Text( - 'NumberedListItems', - annotations: TextAnnotations(code: true), - ), + ...Text.list(texts: [ + Text.code('Paragraph'), + Text.code('ToDo'), + Text.code('BulletedListItems'), + Text.code('NumberedListItems'), + ], lastSeparator: ' or '), Text('.'), ]), + Paragraph.text( + 'Also, if your paragraph will have the same style you can write all your text directly like this to avoid using a list. This constructor can be found for every block.', + ), Paragraph( - text: Text( - 'Also, if your paragraph will have the same style you can write all your text directly like this to avoid using a list.', - ), + texts: [ + Text('There are a few shortcuts for basic styles like: '), + ...Text.list(texts: [ + Text.bold('all text bold and green', color: ColorsTypes.Green), + Text.code('all text code'), + Text.italic('all text italic'), + Text.underline('all text underline'), + ]), + Text('.'), + ], ), ]), Heading(text: Text('Blocks'), type: 2), diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index 5e3ef69..5a91c2b 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -113,25 +113,12 @@ void main() { Text( 'You can also have children for some blocks like ', ), - Text( - 'Paragraph', - annotations: TextAnnotations(code: true), - ), - Text(', '), - Text( - 'ToDo', - annotations: TextAnnotations(code: true), - ), - Text(', '), - Text( - 'BulletedListItems', - annotations: TextAnnotations(code: true), - ), - Text(' or '), - Text( - 'NumberedListItems', - annotations: TextAnnotations(code: true), - ), + ...Text.list(texts: [ + Text.code('Paragraph'), + Text.code('ToDo'), + Text.code('BulletedListItems'), + Text.code('NumberedListItems'), + ], lastSeparator: ' or '), Text('.'), ]), Paragraph.text( From 114bcde06a1a9980a7b20d29a106371463d950da Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 28 Jul 2021 13:56:36 -0500 Subject: [PATCH 05/42] Add change for next release (1.2.1) --- CHANGELOG.md | 28 +++++++++++++++++++++++++++- README.md | 31 +++++++++---------------------- ROADMAP.md | 18 ++++++++++++------ pubspec.yaml | 2 +- 4 files changed, 49 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48cc9ef..6c01111 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -114,4 +114,30 @@ * Add `Page` support for responses * Add more colors for Text * Add list of endpoints implemented on package -* Improve coverage \ No newline at end of file +* Improve coverage + +## v1.2.1: +> Release date: 02/Aug/2021 +* Add sugestion on issue [#11](https://github.com/jonathangomz/notion_api/issues/11): + * Update exports to improve usage + * Add private folder (`src/`) +* Add constructors with only single text content with default style for: + * `Paragraph.text('some text here...')` + * `ToDo.text('some text here...', checked: true)` + * `Heading.text('some text here...', type: 2)` + * `BulletedListItem.text('some text here...')` + * `NumberedListItem.text('some text here...')` + * `Toggle.text('some text here...', children: [])` +* Add more constructors for `Heading` class: + * `one`: Heading with type 1 by default. + * `two`: Heading with type 2 by default. + * `three`: Heading with type 3 by default. +* Add more constructors for `Text` class: + * `code`: Text with code style by default. + * `italic`: Text with italic style by default. + * `bold`: Text with bold style by default. + * `underline`: Text with underline style by default. + * `color`: Text with different color of default. +* Add `list(List texts, String separator, String lastSeparator)`: + * **A static method** + * Generate a textual list of texts separated by comma (by default). \ No newline at end of file diff --git a/README.md b/README.md index 31e2a3f..aea9d73 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ See the [ROADMAP](ROADMAP.md) file to see what is coming next. - [Tests](#tests) - [Example:](#example) - [Next release](#next-release) - - [v1.2.1:](#v121) + - [v1.3.0](#v130) # API implemented | Endpoint | Avaliable | Notes @@ -147,26 +147,13 @@ TEST_BLOCK_HEADING_ID=c8hac4bb32af48889228bf483d938e34 ``` # Next release -## v1.2.1: -> Release date: 02/Aug/2021 -* Add constructors with only single text content with default style for: - * `Paragraph.text('some text here...')` - * `ToDo.text('some text here...', checked: true)` - * `Heading.text('some text here...', type: 2)` - * `BulletedListItem.text('some text here...')` - * `NumberedListItem.text('some text here...')` - * `Toggle.text('some text here...', children: [])` -* Add more constructors for `Heading` class: - * `one`: Heading with type 1 by default. - * `two`: Heading with type 2 by default. - * `three`: Heading with type 3 by default. -* Add more constructors for `Text` class: - * `code`: Text with code style by default. - * `italic`: Text with italic style by default. - * `bold`: Text with bold style by default. - * [**Opt**] `list`: List of words separated by comma (by default). - * Example: `Text.list()` will receive a list of Text and will be concatenated separated with comma by default. **It may be unnecessary**. Can help to make the code more readable. - * [**Opt**] `sep`: Text separator. - * Example: `Text.sep()`, by default, will insert " " in a list of `Text` instances, but it will be able to do more things that I don't know yet, hehe. **It may be unnecessary**. Can help to make the code more readable. +## v1.3.0 +> Release date: 06/Aug/2021 +* Maybe fix errors creating page with children. I don't know if is an error with Notion API. +* Add `Query a database` endpoint: + * https://developers.notion.com/reference/post-database-query +* Add more properties for pages and databases: + * Page properties: https://developers.notion.com/reference/page#page-property-value + * Database properties: https://developers.notion.com/reference/database#database-property [1]:https://pub.dev/documentation/notion_api/1.0.0-beta1/responses_notion_response/NotionResponse-class.html \ No newline at end of file diff --git a/ROADMAP.md b/ROADMAP.md index 9f48218..a35fc53 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -6,14 +6,17 @@ If you have suggestions feel free to create an Issue or to create a PR with the ## v1.3.0 > Release date: 06/Aug/2021 * Maybe fix errors creating page with children. I don't know if is an error with Notion API. -* Add query a database endpoint: +* Add `Query a database` endpoint: * https://developers.notion.com/reference/post-database-query * Add more properties for pages and databases: * Page properties: https://developers.notion.com/reference/page#page-property-value * Database properties: https://developers.notion.com/reference/database#database-property -## v1.2.1: +## v1.2.1: ✅ > Release date: 02/Aug/2021 +* Add sugestion on issue [#11](https://github.com/jonathangomz/notion_api/issues/11): + * Update exports to improve usage + * Add private folder (`src/`) * Add constructors with only single text content with default style for: * `Paragraph.text('some text here...')` * `ToDo.text('some text here...', checked: true)` @@ -29,10 +32,13 @@ If you have suggestions feel free to create an Issue or to create a PR with the * `code`: Text with code style by default. * `italic`: Text with italic style by default. * `bold`: Text with bold style by default. - * [**Opt**] `list`: List of words separated by comma (by default). - * Example: `Text.list()` will receive a list of Text and will be concatenated separated with comma by default. **It may be unnecessary**. Can help to make the code more readable. - * [**Opt**] `sep`: Text separator. - * Example: `Text.sep()`, by default, will insert " " in a list of `Text` instances, but it will be able to do more things that I don't know yet, hehe. **It may be unnecessary**. Can help to make the code more readable. + * `underline`: Text with underline style by default. + * `color`: Text with different color of default. + * [**CANCELED**] ~~`sep`: Text separator.~~ + * ~~Example: `Text.sep()`, by default, will insert " " in a list of `Text` instances, but it will be able to do more things that I don't know yet, hehe. **It may be unnecessary**. Can help to make the code more readable.~~ +* Add `list(List texts, String separator, String lastSeparator)`: + * **A static method** + * Generate a textual list of texts separated by comma (by default). ## v1.2.0: ✅ > Release date: 27/Jul/2021 diff --git a/pubspec.yaml b/pubspec.yaml index c38c707..bb54fbc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: notion_api description: A wrapper for the public beta Notion API to manage it like a Notion SDK package for dart. -version: 1.2.0 +version: 1.2.1 homepage: https://github.com/jonathangomz/notion_api environment: From 6dec5b0f8e6e94fa95f4d939682fe3d3edc18476 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 30 Jul 2021 10:09:32 -0500 Subject: [PATCH 06/42] Implement suggestions on issue #11 Add `src/` directory Add exports to improve usage Remove base fields class Change from public to private the token, version and dateVersion variables for clients --- lib/base_client.dart | 25 ---------- lib/notion.dart | 18 +++++-- lib/src/notion/exports.dart | 5 ++ lib/src/notion/general/exports.dart | 2 + .../notion/general}/notion_types.dart | 0 lib/{ => src}/notion/general/property.dart | 6 +-- .../notion}/lists/children.dart | 10 ++-- lib/src/notion/lists/exports.dart | 3 ++ .../notion}/lists/pagination.dart | 8 +-- .../notion}/lists/properties.dart | 2 +- .../notion/objects}/base_fields.dart | 4 +- .../blocks => src/notion/objects}/block.dart | 6 +-- .../objects}/blocks/bulleted_list_item.dart | 18 ++++--- lib/src/notion/objects/blocks/exports.dart | 6 +++ .../notion/objects}/blocks/heading.dart | 17 ++++--- .../objects}/blocks/numbered_list_item.dart | 18 ++++--- .../notion/objects}/blocks/paragraph.dart | 18 ++++--- .../notion/objects}/blocks/todo.dart | 18 ++++--- .../notion/objects}/blocks/toggle.dart | 18 ++++--- lib/{ => src}/notion/objects/database.dart | 12 ++--- lib/src/notion/objects/exports.dart | 6 +++ lib/{ => src}/notion/objects/pages.dart | 11 ++-- lib/{ => src}/notion/objects/parent.dart | 4 +- .../general => src/notion}/rich_text.dart | 4 +- lib/{ => src}/notion_blocks.dart | 33 ++++++++---- lib/{ => src}/notion_databases.dart | 39 +++++++++------ lib/{ => src}/notion_pages.dart | 50 ++++++++++++------- lib/{ => src}/responses/notion_response.dart | 8 ++- lib/{ => src}/statics.dart | 0 lib/{ => src}/utils/utils.dart | 2 +- test/blocks/block.dart | 3 +- test/blocks/bulleted_list_item_test.dart | 7 +-- test/blocks/heading_test.dart | 6 +-- test/blocks/numbered_list_item_test.dart | 7 +-- test/blocks/paragraph_test.dart | 6 +-- test/blocks/todo_test.dart | 7 +-- test/blocks/toggle_test.dart | 8 +-- test/general_test.dart | 4 +- test/lists/children_test.dart | 8 +-- test/lists/pagination_test.dart | 5 +- test/lists/properties_test.dart | 2 +- test/notion_api_test.dart | 18 ------- test/objects/database_test.dart | 5 +- test/objects/page_test.dart | 9 +--- test/property_test.dart | 5 +- test/response_test.dart | 11 ---- test/rich_text_test.dart | 3 +- test/utils_test.dart | 3 +- 48 files changed, 225 insertions(+), 263 deletions(-) delete mode 100644 lib/base_client.dart create mode 100644 lib/src/notion/exports.dart create mode 100644 lib/src/notion/general/exports.dart rename lib/{notion/general/types => src/notion/general}/notion_types.dart (100%) rename lib/{ => src}/notion/general/property.dart (97%) rename lib/{notion/general => src/notion}/lists/children.dart (91%) create mode 100644 lib/src/notion/lists/exports.dart rename lib/{notion/general => src/notion}/lists/pagination.dart (95%) rename lib/{notion/general => src/notion}/lists/properties.dart (96%) rename lib/{notion/general => src/notion/objects}/base_fields.dart (92%) rename lib/{notion/blocks => src/notion/objects}/block.dart (94%) rename lib/{notion => src/notion/objects}/blocks/bulleted_list_item.dart (87%) create mode 100644 lib/src/notion/objects/blocks/exports.dart rename lib/{notion => src/notion/objects}/blocks/heading.dart (87%) rename lib/{notion => src/notion/objects}/blocks/numbered_list_item.dart (87%) rename lib/{notion => src/notion/objects}/blocks/paragraph.dart (91%) rename lib/{notion => src/notion/objects}/blocks/todo.dart (92%) rename lib/{notion => src/notion/objects}/blocks/toggle.dart (87%) rename lib/{ => src}/notion/objects/database.dart (91%) create mode 100644 lib/src/notion/objects/exports.dart rename lib/{ => src}/notion/objects/pages.dart (88%) rename lib/{ => src}/notion/objects/parent.dart (93%) rename lib/{notion/general => src/notion}/rich_text.dart (99%) rename lib/{ => src}/notion_blocks.dart (73%) rename lib/{ => src}/notion_databases.dart (70%) rename lib/{ => src}/notion_pages.dart (65%) rename lib/{ => src}/responses/notion_response.dart (90%) rename lib/{ => src}/statics.dart (100%) rename lib/{ => src}/utils/utils.dart (99%) diff --git a/lib/base_client.dart b/lib/base_client.dart deleted file mode 100644 index 4b8afe2..0000000 --- a/lib/base_client.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:notion_api/statics.dart'; - -abstract class BaseClient { - /// The API integration secret token. - String token; - - /// The API version. - String v; - - /// The API date version. - /// - /// It's not the same as the API version. - String dateVersion; - - /// The path of the requests group. - String path = ''; - - BaseClient({ - required String token, - String version: latestVersion, - String dateVersion: latestDateVersion, - }) : this.token = token, - this.v = version, - this.dateVersion = dateVersion; -} diff --git a/lib/notion.dart b/lib/notion.dart index a5b58d9..48c6134 100644 --- a/lib/notion.dart +++ b/lib/notion.dart @@ -6,11 +6,21 @@ /// API Reference here https://developers.notion.com/reference/intro. library notion_api; -import 'package:notion_api/statics.dart'; +import 'package:notion_api/src/statics.dart'; -import 'notion_pages.dart'; -import 'notion_blocks.dart'; -import 'notion_databases.dart'; +import 'package:notion_api/src/notion_pages.dart'; +import 'package:notion_api/src/notion_blocks.dart'; +import 'package:notion_api/src/notion_databases.dart'; + +// export clients +export 'package:notion_api/src/notion_blocks.dart'; +export 'package:notion_api/src/notion_databases.dart'; +export 'package:notion_api/src/notion_pages.dart'; + +// export all other components +export 'package:notion_api/src/notion/exports.dart'; +export 'package:notion_api/src/responses/notion_response.dart'; +export 'package:notion_api/src/utils/utils.dart'; /// A Notion API client. class NotionClient { diff --git a/lib/src/notion/exports.dart b/lib/src/notion/exports.dart new file mode 100644 index 0000000..39b3676 --- /dev/null +++ b/lib/src/notion/exports.dart @@ -0,0 +1,5 @@ +export 'objects/exports.dart'; +export 'general/exports.dart'; +export 'lists/exports.dart'; + +export 'rich_text.dart'; diff --git a/lib/src/notion/general/exports.dart b/lib/src/notion/general/exports.dart new file mode 100644 index 0000000..f1dffe7 --- /dev/null +++ b/lib/src/notion/general/exports.dart @@ -0,0 +1,2 @@ +export 'property.dart'; +export 'notion_types.dart'; diff --git a/lib/notion/general/types/notion_types.dart b/lib/src/notion/general/notion_types.dart similarity index 100% rename from lib/notion/general/types/notion_types.dart rename to lib/src/notion/general/notion_types.dart diff --git a/lib/notion/general/property.dart b/lib/src/notion/general/property.dart similarity index 97% rename from lib/notion/general/property.dart rename to lib/src/notion/general/property.dart index e1cb3f5..c747391 100644 --- a/lib/notion/general/property.dart +++ b/lib/src/notion/general/property.dart @@ -1,6 +1,6 @@ -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/utils/utils.dart'; +import '../../utils/utils.dart'; +import '../rich_text.dart'; +import 'notion_types.dart'; /// A representation of a single property for any Notion object. class Property { diff --git a/lib/notion/general/lists/children.dart b/lib/src/notion/lists/children.dart similarity index 91% rename from lib/notion/general/lists/children.dart rename to lib/src/notion/lists/children.dart index d8417bb..bd15951 100644 --- a/lib/notion/general/lists/children.dart +++ b/lib/src/notion/lists/children.dart @@ -1,8 +1,8 @@ -import 'package:notion_api/notion/blocks/block.dart'; -import 'package:notion_api/notion/blocks/heading.dart'; -import 'package:notion_api/notion/blocks/paragraph.dart'; -import 'package:notion_api/notion/blocks/todo.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; +import '../general/notion_types.dart'; +import '../objects/block.dart'; +import '../objects/blocks/heading.dart'; +import '../objects/blocks/paragraph.dart'; +import '../objects/blocks/todo.dart'; /// A representation of the children Notion object. Also list of blocks. class Children { diff --git a/lib/src/notion/lists/exports.dart b/lib/src/notion/lists/exports.dart new file mode 100644 index 0000000..715d876 --- /dev/null +++ b/lib/src/notion/lists/exports.dart @@ -0,0 +1,3 @@ +export 'children.dart'; +export 'pagination.dart'; +export 'properties.dart'; diff --git a/lib/notion/general/lists/pagination.dart b/lib/src/notion/lists/pagination.dart similarity index 95% rename from lib/notion/general/lists/pagination.dart rename to lib/src/notion/lists/pagination.dart index 0e6a9e3..b4c193b 100644 --- a/lib/notion/general/lists/pagination.dart +++ b/lib/src/notion/lists/pagination.dart @@ -1,7 +1,7 @@ -import 'package:notion_api/notion/blocks/block.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/objects/database.dart'; -import 'package:notion_api/utils/utils.dart'; +import '../../utils/utils.dart'; +import '../general/notion_types.dart'; +import '../objects/block.dart'; +import '../objects/database.dart'; /// A representation of the pagination response from the Notion API. Also list of objects. class Pagination { diff --git a/lib/notion/general/lists/properties.dart b/lib/src/notion/lists/properties.dart similarity index 96% rename from lib/notion/general/lists/properties.dart rename to lib/src/notion/lists/properties.dart index c636383..654a2b4 100644 --- a/lib/notion/general/lists/properties.dart +++ b/lib/src/notion/lists/properties.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion/general/property.dart'; +import '../general/property.dart'; /// A representation of the properties for any Notion object. class Properties { diff --git a/lib/notion/general/base_fields.dart b/lib/src/notion/objects/base_fields.dart similarity index 92% rename from lib/notion/general/base_fields.dart rename to lib/src/notion/objects/base_fields.dart index 24fed83..fff2b89 100644 --- a/lib/notion/general/base_fields.dart +++ b/lib/src/notion/objects/base_fields.dart @@ -1,5 +1,5 @@ -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/utils/utils.dart'; +import '../../utils/utils.dart'; +import '../general/notion_types.dart'; /// A base representation of the base properties of almost any Notion object. class BaseFields { diff --git a/lib/notion/blocks/block.dart b/lib/src/notion/objects/block.dart similarity index 94% rename from lib/notion/blocks/block.dart rename to lib/src/notion/objects/block.dart index 152f90f..f418a46 100644 --- a/lib/notion/blocks/block.dart +++ b/lib/src/notion/objects/block.dart @@ -1,6 +1,6 @@ -import 'package:notion_api/notion/general/base_fields.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/utils/utils.dart'; +import '../../utils/utils.dart'; +import '../general/notion_types.dart'; +import 'base_fields.dart'; /// A base representation of any Notion block object. class Block extends BaseFields { diff --git a/lib/notion/blocks/bulleted_list_item.dart b/lib/src/notion/objects/blocks/bulleted_list_item.dart similarity index 87% rename from lib/notion/blocks/bulleted_list_item.dart rename to lib/src/notion/objects/blocks/bulleted_list_item.dart index 87df582..91e85c9 100644 --- a/lib/notion/blocks/bulleted_list_item.dart +++ b/lib/src/notion/objects/blocks/bulleted_list_item.dart @@ -1,6 +1,6 @@ -import 'package:notion_api/notion/blocks/block.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; +import '../../general/notion_types.dart'; +import '../../rich_text.dart'; +import '../block.dart'; /// A representation of the Bulleted List Item Notion block object; class BulletedListItem extends Block { @@ -24,11 +24,13 @@ class BulletedListItem extends Block { Text? text, List texts: const [], List children: const [], - }) : this._content = [ - if (text != null) text, - ...texts, - ], - this._children = children; + }) { + this._content.addAll([ + if (text != null) text, + ...texts, + ]); + this._children.addAll(children); + } /// BulletedListItem constructor with a single `Text` instance as content. /// diff --git a/lib/src/notion/objects/blocks/exports.dart b/lib/src/notion/objects/blocks/exports.dart new file mode 100644 index 0000000..5f57599 --- /dev/null +++ b/lib/src/notion/objects/blocks/exports.dart @@ -0,0 +1,6 @@ +export 'bulleted_list_item.dart'; +export 'heading.dart'; +export 'numbered_list_item.dart'; +export 'paragraph.dart'; +export 'todo.dart'; +export 'toggle.dart'; diff --git a/lib/notion/blocks/heading.dart b/lib/src/notion/objects/blocks/heading.dart similarity index 87% rename from lib/notion/blocks/heading.dart rename to lib/src/notion/objects/blocks/heading.dart index b1c7ac3..fca5fea 100644 --- a/lib/notion/blocks/heading.dart +++ b/lib/src/notion/objects/blocks/heading.dart @@ -1,6 +1,6 @@ -import 'package:notion_api/notion/blocks/block.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; +import '../../general/notion_types.dart'; +import '../../rich_text.dart'; +import '../block.dart'; /// A representation of the Heading Notion block object. class Heading extends Block { @@ -22,11 +22,12 @@ class Heading extends Block { Text? text, List texts: const [], int type: 1, - }) : this._content = [ - if (text != null) text, - ...texts, - ], - this.type = headingTypeFromInt(type); + }) : this.type = headingTypeFromInt(type) { + this._content.addAll([ + if (text != null) text, + ...texts, + ]); + } /// Heading constructor with a single `Text` instance as content. /// diff --git a/lib/notion/blocks/numbered_list_item.dart b/lib/src/notion/objects/blocks/numbered_list_item.dart similarity index 87% rename from lib/notion/blocks/numbered_list_item.dart rename to lib/src/notion/objects/blocks/numbered_list_item.dart index 650082b..240c7a0 100644 --- a/lib/notion/blocks/numbered_list_item.dart +++ b/lib/src/notion/objects/blocks/numbered_list_item.dart @@ -1,6 +1,6 @@ -import 'package:notion_api/notion/blocks/block.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; +import '../../general/notion_types.dart'; +import '../../rich_text.dart'; +import '../block.dart'; /// A representation of the Bulleted List Item Notion block object; class NumberedListItem extends Block { @@ -24,11 +24,13 @@ class NumberedListItem extends Block { Text? text, List texts: const [], List children: const [], - }) : this._content = [ - if (text != null) text, - ...texts, - ], - this._children = children; + }) { + this._content.addAll([ + if (text != null) text, + ...texts, + ]); + this._children.addAll(children); + } /// NumberedListItem constructor with a single `Text` instance as content. /// diff --git a/lib/notion/blocks/paragraph.dart b/lib/src/notion/objects/blocks/paragraph.dart similarity index 91% rename from lib/notion/blocks/paragraph.dart rename to lib/src/notion/objects/blocks/paragraph.dart index 49e1bf7..3680a82 100644 --- a/lib/notion/blocks/paragraph.dart +++ b/lib/src/notion/objects/blocks/paragraph.dart @@ -1,6 +1,6 @@ -import 'package:notion_api/notion/blocks/block.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; +import '../../general/notion_types.dart'; +import '../../rich_text.dart'; +import '../block.dart'; /// A representation of the Paragraph Notion block object. class Paragraph extends Block { @@ -37,11 +37,13 @@ class Paragraph extends Block { List texts: const [], List children: const [], @deprecated this.textSeparator: ' ', - }) : this._content = [ - if (text != null) text, - ...texts, - ], - this._children = children; + }) { + this._content.addAll([ + if (text != null) text, + ...texts, + ]); + this._children.addAll(children); + } /// Paragraph constructor with a single `Text` instance as content. /// diff --git a/lib/notion/blocks/todo.dart b/lib/src/notion/objects/blocks/todo.dart similarity index 92% rename from lib/notion/blocks/todo.dart rename to lib/src/notion/objects/blocks/todo.dart index cae8a3f..6917fea 100644 --- a/lib/notion/blocks/todo.dart +++ b/lib/src/notion/objects/blocks/todo.dart @@ -1,6 +1,6 @@ -import 'package:notion_api/notion/blocks/block.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; +import '../../general/notion_types.dart'; +import '../../rich_text.dart'; +import '../block.dart'; /// A representation of the Paragraph Notion block object. class ToDo extends Block { @@ -39,11 +39,13 @@ class ToDo extends Block { List children: const [], this.checked: false, @deprecated this.textSeparator: ' ', - }) : this._content = [ - if (text != null) text, - ...texts, - ], - this._children = children; + }) { + this._content.addAll([ + if (text != null) text, + ...texts, + ]); + this._children.addAll(children); + } /// ToDo constructor with a single `Text` instance as content. /// diff --git a/lib/notion/blocks/toggle.dart b/lib/src/notion/objects/blocks/toggle.dart similarity index 87% rename from lib/notion/blocks/toggle.dart rename to lib/src/notion/objects/blocks/toggle.dart index 4d1281f..8e8e810 100644 --- a/lib/notion/blocks/toggle.dart +++ b/lib/src/notion/objects/blocks/toggle.dart @@ -1,6 +1,6 @@ -import 'package:notion_api/notion/blocks/block.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; +import '../../general/notion_types.dart'; +import '../../rich_text.dart'; +import '../block.dart'; /// A representation of the Bulleted List Item Notion block object; class Toggle extends Block { @@ -24,11 +24,13 @@ class Toggle extends Block { Text? text, List texts: const [], List children: const [], - }) : this._content = [ - if (text != null) text, - ...texts, - ], - this._children = children; + }) { + this._content.addAll([ + if (text != null) text, + ...texts, + ]); + this._children.addAll(children); + } /// Toggle constructor with a single `Text` instance as content. /// diff --git a/lib/notion/objects/database.dart b/lib/src/notion/objects/database.dart similarity index 91% rename from lib/notion/objects/database.dart rename to lib/src/notion/objects/database.dart index f28a25f..73f010b 100644 --- a/lib/notion/objects/database.dart +++ b/lib/src/notion/objects/database.dart @@ -1,10 +1,8 @@ -import 'package:notion_api/notion/general/base_fields.dart'; -import 'package:notion_api/notion/general/lists/properties.dart'; -import 'package:notion_api/notion/general/property.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/utils/utils.dart'; - +import '../../utils/utils.dart'; +import '../general/exports.dart'; +import '../lists/properties.dart'; +import '../rich_text.dart'; +import 'base_fields.dart'; import 'parent.dart'; /// A representation of the Databse Notion object. diff --git a/lib/src/notion/objects/exports.dart b/lib/src/notion/objects/exports.dart new file mode 100644 index 0000000..09cc3a3 --- /dev/null +++ b/lib/src/notion/objects/exports.dart @@ -0,0 +1,6 @@ +export 'database.dart'; +export 'pages.dart'; +export 'parent.dart'; +export 'block.dart'; + +export 'blocks/exports.dart'; diff --git a/lib/notion/objects/pages.dart b/lib/src/notion/objects/pages.dart similarity index 88% rename from lib/notion/objects/pages.dart rename to lib/src/notion/objects/pages.dart index 2f967f3..8b2c985 100644 --- a/lib/notion/objects/pages.dart +++ b/lib/src/notion/objects/pages.dart @@ -1,10 +1,7 @@ -import 'package:notion_api/notion/general/base_fields.dart'; -import 'package:notion_api/notion/general/lists/properties.dart'; -import 'package:notion_api/notion/general/property.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/lists/children.dart'; - +import '../general/exports.dart'; +import '../lists/exports.dart'; +import '../rich_text.dart'; +import 'base_fields.dart'; import 'parent.dart'; /// A representation of the Page Notion object. diff --git a/lib/notion/objects/parent.dart b/lib/src/notion/objects/parent.dart similarity index 93% rename from lib/notion/objects/parent.dart rename to lib/src/notion/objects/parent.dart index 562b09c..ca3e516 100644 --- a/lib/notion/objects/parent.dart +++ b/lib/src/notion/objects/parent.dart @@ -1,5 +1,5 @@ -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/utils/utils.dart'; +import '../../utils/utils.dart'; +import '../general/notion_types.dart'; /// A representation of the parent json field for the Notion API. class Parent { diff --git a/lib/notion/general/rich_text.dart b/lib/src/notion/rich_text.dart similarity index 99% rename from lib/notion/general/rich_text.dart rename to lib/src/notion/rich_text.dart index 6aef521..234b78d 100644 --- a/lib/notion/general/rich_text.dart +++ b/lib/src/notion/rich_text.dart @@ -1,5 +1,5 @@ -import 'types/notion_types.dart'; -import '../../utils/utils.dart'; +import 'general/notion_types.dart'; +import '../utils/utils.dart'; /// A representation of the Rich Text Notion. class Text { diff --git a/lib/notion_blocks.dart b/lib/src/notion_blocks.dart similarity index 73% rename from lib/notion_blocks.dart rename to lib/src/notion_blocks.dart index 3848792..e1b9dfc 100644 --- a/lib/notion_blocks.dart +++ b/lib/src/notion_blocks.dart @@ -1,16 +1,25 @@ import 'dart:convert'; import 'package:http/http.dart' as http; -import 'package:notion_api/base_client.dart'; -import 'notion/general/lists/children.dart'; +import 'notion/exports.dart'; import 'responses/notion_response.dart'; import 'statics.dart'; /// A client for Notion API block children requests. -class NotionBlockClient extends BaseClient { +class NotionBlockClient { + /// The API integration secret token. + String _token; + + /// The API version. + String _v; + + /// The API date version. + /// + /// It's not the same as the API version. + String _dateVersion; + /// The path of the requests group. - @override final String path = 'blocks'; /// Main Notion block client constructor. @@ -20,7 +29,9 @@ class NotionBlockClient extends BaseClient { required String token, String version: latestVersion, String dateVersion: latestDateVersion, - }) : super(token: token, version: version, dateVersion: dateVersion); + }) : this._token = token, + this._v = version, + this._dateVersion = dateVersion; /// Retrieve the block children from block with [id]. /// @@ -42,9 +53,9 @@ class NotionBlockClient extends BaseClient { } http.Response response = await http - .get(Uri.https(host, '/$v/$path/$id/children', query), headers: { - 'Authorization': 'Bearer $token', - 'Notion-Version': dateVersion, + .get(Uri.https(host, '/$_v/$path/$id/children', query), headers: { + 'Authorization': 'Bearer $_token', + 'Notion-Version': _dateVersion, }); return NotionResponse.fromResponse(response); @@ -58,12 +69,12 @@ class NotionBlockClient extends BaseClient { required Children children, }) async { http.Response res = await http.patch( - Uri.https(host, '/$v/$path/$to/children'), + Uri.https(host, '/$_v/$path/$to/children'), body: jsonEncode(children.toJson()), headers: { - 'Authorization': 'Bearer $token', + 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json; charset=UTF-8', - 'Notion-Version': dateVersion, + 'Notion-Version': _dateVersion, }); return NotionResponse.fromResponse(res); diff --git a/lib/notion_databases.dart b/lib/src/notion_databases.dart similarity index 70% rename from lib/notion_databases.dart rename to lib/src/notion_databases.dart index 8763765..ef2ac37 100644 --- a/lib/notion_databases.dart +++ b/lib/src/notion_databases.dart @@ -1,16 +1,25 @@ import 'dart:convert'; import 'package:http/http.dart' as http; -import 'package:notion_api/base_client.dart'; -import 'package:notion_api/notion/objects/database.dart'; +import 'notion/exports.dart'; import 'responses/notion_response.dart'; import 'statics.dart'; /// A client for Notion API databases requests. -class NotionDatabasesClient extends BaseClient { +class NotionDatabasesClient { + /// The API integration secret token. + String _token; + + /// The API version. + String _v; + + /// The API date version. + /// + /// It's not the same as the API version. + String _dateVersion; + /// The path of the requests group. - @override final String path = 'databases'; /// Main Notion database client constructor. @@ -20,16 +29,18 @@ class NotionDatabasesClient extends BaseClient { required String token, String version: latestVersion, String dateVersion: latestDateVersion, - }) : super(token: token, version: version, dateVersion: dateVersion); + }) : this._token = token, + this._v = version, + this._dateVersion = dateVersion; /// Retrieve the database with [id]. /// /// _See more at https://developers.notion.com/reference/get-database_ Future fetch(String id) async { http.Response res = - await http.get(Uri.https(host, '/$v/$path/$id'), headers: { - 'Authorization': 'Bearer $token', - 'Notion-Version': dateVersion, + await http.get(Uri.https(host, '/$_v/$path/$id'), headers: { + 'Authorization': 'Bearer $_token', + 'Notion-Version': _dateVersion, }); return NotionResponse.fromResponse(res); @@ -51,9 +62,9 @@ class NotionDatabasesClient extends BaseClient { } http.Response res = - await http.get(Uri.https(host, '/$v/$path', query), headers: { - 'Authorization': 'Bearer $token', - 'Notion-Version': dateVersion, + await http.get(Uri.https(host, '/$_v/$path', query), headers: { + 'Authorization': 'Bearer $_token', + 'Notion-Version': _dateVersion, }); return NotionResponse.fromResponse(res); @@ -64,11 +75,11 @@ class NotionDatabasesClient extends BaseClient { /// _See more at https://developers.notion.com/reference/create-a-database_ Future create(Database database) async { http.Response res = await http.post( - Uri.https(host, '/$v/$path'), + Uri.https(host, '/$_v/$path'), body: jsonEncode(database.toJson()), headers: { - 'Authorization': 'Bearer $token', - 'Notion-Version': dateVersion, + 'Authorization': 'Bearer $_token', + 'Notion-Version': _dateVersion, 'Content-Type': 'application/json', }, ); diff --git a/lib/notion_pages.dart b/lib/src/notion_pages.dart similarity index 65% rename from lib/notion_pages.dart rename to lib/src/notion_pages.dart index b14d597..6522e7d 100644 --- a/lib/notion_pages.dart +++ b/lib/src/notion_pages.dart @@ -1,17 +1,25 @@ import 'dart:convert'; import 'package:http/http.dart' as http; -import 'package:notion_api/base_client.dart'; -import 'package:notion_api/notion/general/lists/properties.dart'; -import 'notion/objects/pages.dart'; +import 'notion/exports.dart'; import 'responses/notion_response.dart'; import 'statics.dart'; /// A client for Notion API pages requests. -class NotionPagesClient extends BaseClient { +class NotionPagesClient { + /// The API integration secret token. + String _token; + + /// The API version. + String _v; + + /// The API date version. + /// + /// It's not the same as the API version. + String _dateVersion; + /// The path of the requests group. - @override final String path = 'pages'; /// Main Notion page client constructor. @@ -21,16 +29,18 @@ class NotionPagesClient extends BaseClient { required String token, String version: latestVersion, String dateVersion: latestDateVersion, - }) : super(token: token, version: version, dateVersion: dateVersion); + }) : this._token = token, + this._v = version, + this._dateVersion = dateVersion; /// Retrieve the page with [id]. /// /// _See more at https://developers.notion.com/reference/get-page_ Future fetch(String id) async { http.Response res = - await http.get(Uri.https(host, '/$v/$path/$id'), headers: { - 'Authorization': 'Bearer $token', - 'Notion-Version': dateVersion, + await http.get(Uri.https(host, '/$_v/$path/$id'), headers: { + 'Authorization': 'Bearer $_token', + 'Notion-Version': _dateVersion, }); return NotionResponse.fromResponse(res); @@ -40,13 +50,15 @@ class NotionPagesClient extends BaseClient { /// /// _See more at https://developers.notion.com/reference/post-page_ Future create(Page page) async { - http.Response res = await http.post(Uri.https(host, '/$v/$path'), - body: jsonEncode(page.toJson()), - headers: { - 'Authorization': 'Bearer $token', - 'Content-Type': 'application/json; charset=UTF-8', - 'Notion-Version': dateVersion, - }); + http.Response res = await http.post( + Uri.https(host, '/$_v/$path'), + body: jsonEncode(page.toJson()), + headers: { + 'Authorization': 'Bearer $_token', + 'Content-Type': 'application/json; charset=UTF-8', + 'Notion-Version': _dateVersion, + }, + ); return NotionResponse.fromResponse(res); } @@ -64,15 +76,15 @@ class NotionPagesClient extends BaseClient { bool? archived, }) async { Properties _properties = properties ?? Properties.empty(); - http.Response res = await http.patch(Uri.https(host, '/$v/$path/$id'), + http.Response res = await http.patch(Uri.https(host, '/$_v/$path/$id'), body: jsonEncode({ 'properties': _properties.toJson(), if (archived != null) 'archived': archived, }), headers: { - 'Authorization': 'Bearer $token', + 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', - 'Notion-Version': dateVersion, + 'Notion-Version': _dateVersion, }); return NotionResponse.fromResponse(res); diff --git a/lib/responses/notion_response.dart b/lib/src/responses/notion_response.dart similarity index 90% rename from lib/responses/notion_response.dart rename to lib/src/responses/notion_response.dart index 6f697d9..311ac7d 100644 --- a/lib/responses/notion_response.dart +++ b/lib/src/responses/notion_response.dart @@ -1,11 +1,9 @@ import 'dart:convert'; import 'package:http/http.dart' show Response; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/objects/database.dart'; -import 'package:notion_api/notion/general/lists/pagination.dart'; -import 'package:notion_api/notion/objects/pages.dart'; -import 'package:notion_api/utils/utils.dart'; + +import '../notion/exports.dart'; +import '../utils/utils.dart'; /// A representation of the Response from the Notion API. class NotionResponse { diff --git a/lib/statics.dart b/lib/src/statics.dart similarity index 100% rename from lib/statics.dart rename to lib/src/statics.dart diff --git a/lib/utils/utils.dart b/lib/src/utils/utils.dart similarity index 99% rename from lib/utils/utils.dart rename to lib/src/utils/utils.dart index 26346d9..06259f0 100644 --- a/lib/utils/utils.dart +++ b/lib/src/utils/utils.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion/general/types/notion_types.dart'; +import '../notion/exports.dart'; // Lists of types const List objects = ObjectTypes.values; diff --git a/test/blocks/block.dart b/test/blocks/block.dart index 4f0fff8..b36207f 100644 --- a/test/blocks/block.dart +++ b/test/blocks/block.dart @@ -1,5 +1,4 @@ -import 'package:notion_api/notion/blocks/block.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/blocks/bulleted_list_item_test.dart b/test/blocks/bulleted_list_item_test.dart index 582b387..5cf1e5a 100644 --- a/test/blocks/bulleted_list_item_test.dart +++ b/test/blocks/bulleted_list_item_test.dart @@ -1,9 +1,4 @@ -import 'package:notion_api/notion/blocks/bulleted_list_item.dart'; -import 'package:notion_api/notion/blocks/heading.dart'; -import 'package:notion_api/notion/blocks/paragraph.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/utils/utils.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/blocks/heading_test.dart b/test/blocks/heading_test.dart index 652a20f..c91e0a8 100644 --- a/test/blocks/heading_test.dart +++ b/test/blocks/heading_test.dart @@ -1,8 +1,4 @@ -import 'package:notion_api/notion/blocks/heading.dart'; -import 'package:notion_api/notion/blocks/paragraph.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/utils/utils.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/blocks/numbered_list_item_test.dart b/test/blocks/numbered_list_item_test.dart index 6fbb85b..5d2053e 100644 --- a/test/blocks/numbered_list_item_test.dart +++ b/test/blocks/numbered_list_item_test.dart @@ -1,9 +1,4 @@ -import 'package:notion_api/notion/blocks/heading.dart'; -import 'package:notion_api/notion/blocks/numbered_list_item.dart'; -import 'package:notion_api/notion/blocks/paragraph.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/utils/utils.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/blocks/paragraph_test.dart b/test/blocks/paragraph_test.dart index b5afeda..f2d2a36 100644 --- a/test/blocks/paragraph_test.dart +++ b/test/blocks/paragraph_test.dart @@ -1,8 +1,4 @@ -import 'package:notion_api/notion/blocks/heading.dart'; -import 'package:notion_api/notion/blocks/paragraph.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/utils/utils.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/blocks/todo_test.dart b/test/blocks/todo_test.dart index 54ea198..3e828cb 100644 --- a/test/blocks/todo_test.dart +++ b/test/blocks/todo_test.dart @@ -1,9 +1,4 @@ -import 'package:notion_api/notion/blocks/heading.dart'; -import 'package:notion_api/notion/blocks/paragraph.dart'; -import 'package:notion_api/notion/blocks/todo.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/utils/utils.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/blocks/toggle_test.dart b/test/blocks/toggle_test.dart index 33ed81b..ed42759 100644 --- a/test/blocks/toggle_test.dart +++ b/test/blocks/toggle_test.dart @@ -1,10 +1,4 @@ -import 'package:notion_api/notion/blocks/bulleted_list_item.dart'; -import 'package:notion_api/notion/blocks/numbered_list_item.dart'; -import 'package:notion_api/notion/blocks/paragraph.dart'; -import 'package:notion_api/notion/blocks/toggle.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/utils/utils.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/general_test.dart b/test/general_test.dart index 236db4a..5d3b03f 100644 --- a/test/general_test.dart +++ b/test/general_test.dart @@ -1,5 +1,5 @@ -import 'package:notion_api/notion/general/base_fields.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; +import 'package:notion_api/notion.dart'; +import 'package:notion_api/src/notion/objects/base_fields.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/lists/children_test.dart b/test/lists/children_test.dart index a1f7b79..cfda491 100644 --- a/test/lists/children_test.dart +++ b/test/lists/children_test.dart @@ -1,10 +1,4 @@ -import 'package:notion_api/notion/blocks/block.dart'; -import 'package:notion_api/notion/blocks/heading.dart'; -import 'package:notion_api/notion/blocks/paragraph.dart'; -import 'package:notion_api/notion/blocks/todo.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/lists/children.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; import '../long_data.dart'; diff --git a/test/lists/pagination_test.dart b/test/lists/pagination_test.dart index 71a8054..3ca27f9 100644 --- a/test/lists/pagination_test.dart +++ b/test/lists/pagination_test.dart @@ -1,7 +1,4 @@ -import 'package:notion_api/notion/blocks/block.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/general/lists/pagination.dart'; -import 'package:notion_api/notion/objects/database.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; import '../long_data.dart'; diff --git a/test/lists/properties_test.dart b/test/lists/properties_test.dart index efb2e72..5c431bd 100644 --- a/test/lists/properties_test.dart +++ b/test/lists/properties_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion/general/lists/properties.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index 5a91c2b..59d7815 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -1,25 +1,7 @@ import 'dart:io' show Platform; import 'package:dotenv/dotenv.dart' show load, env, clean; -import 'package:notion_api/notion/blocks/bulleted_list_item.dart'; -import 'package:notion_api/notion/blocks/heading.dart'; -import 'package:notion_api/notion/blocks/numbered_list_item.dart'; -import 'package:notion_api/notion/blocks/paragraph.dart'; -import 'package:notion_api/notion/blocks/todo.dart'; -import 'package:notion_api/notion/blocks/toggle.dart'; -import 'package:notion_api/notion/general/lists/properties.dart'; -import 'package:notion_api/notion/general/property.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/general/lists/children.dart'; -import 'package:notion_api/notion/objects/database.dart'; -import 'package:notion_api/notion/objects/pages.dart'; import 'package:notion_api/notion.dart'; -import 'package:notion_api/notion/objects/parent.dart'; -import 'package:notion_api/notion_blocks.dart'; -import 'package:notion_api/notion_databases.dart'; -import 'package:notion_api/notion_pages.dart'; -import 'package:notion_api/responses/notion_response.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/objects/database_test.dart b/test/objects/database_test.dart index 36d74f1..b2e3612 100644 --- a/test/objects/database_test.dart +++ b/test/objects/database_test.dart @@ -1,7 +1,4 @@ -import 'package:notion_api/notion/general/property.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/objects/database.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/objects/page_test.dart b/test/objects/page_test.dart index 3ccfa65..54e2237 100644 --- a/test/objects/page_test.dart +++ b/test/objects/page_test.dart @@ -1,11 +1,4 @@ -import 'package:notion_api/notion/blocks/heading.dart'; -import 'package:notion_api/notion/general/lists/children.dart'; -import 'package:notion_api/notion/general/property.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/objects/pages.dart'; -import 'package:notion_api/notion/objects/parent.dart'; -import 'package:notion_api/utils/utils.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/property_test.dart b/test/property_test.dart index e69b69e..baf5700 100644 --- a/test/property_test.dart +++ b/test/property_test.dart @@ -1,7 +1,4 @@ -import 'package:notion_api/notion/general/property.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/utils/utils.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/response_test.dart b/test/response_test.dart index 30606cf..3c57e9c 100644 --- a/test/response_test.dart +++ b/test/response_test.dart @@ -2,17 +2,6 @@ import 'dart:io' show Platform; import 'package:dotenv/dotenv.dart' show load, env, clean; import 'package:notion_api/notion.dart'; -import 'package:notion_api/notion/blocks/paragraph.dart'; -import 'package:notion_api/notion/general/lists/children.dart'; -import 'package:notion_api/notion/general/property.dart'; -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/notion/objects/pages.dart'; -import 'package:notion_api/notion/objects/parent.dart'; -import 'package:notion_api/notion_blocks.dart'; -import 'package:notion_api/notion_databases.dart'; -import 'package:notion_api/notion_pages.dart'; -import 'package:notion_api/responses/notion_response.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/rich_text_test.dart b/test/rich_text_test.dart index e02fa12..dbcc834 100644 --- a/test/rich_text_test.dart +++ b/test/rich_text_test.dart @@ -1,5 +1,4 @@ -import 'package:notion_api/notion/general/rich_text.dart'; -import 'package:notion_api/notion/general/types/notion_types.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/utils_test.dart b/test/utils_test.dart index c227db2..71c1dd4 100644 --- a/test/utils_test.dart +++ b/test/utils_test.dart @@ -1,5 +1,4 @@ -import 'package:notion_api/notion/general/types/notion_types.dart'; -import 'package:notion_api/utils/utils.dart'; +import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { From 6959bb785d7522179671fc2f15b8fb8993cd55b2 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 30 Jul 2021 10:29:56 -0500 Subject: [PATCH 07/42] Remove deprecated code --- example/example.md | 71 +++++++------------- lib/src/notion/lists/children.dart | 23 +------ lib/src/notion/objects/blocks/heading.dart | 7 -- lib/src/notion/objects/blocks/paragraph.dart | 27 +------- lib/src/notion/objects/blocks/todo.dart | 23 +------ lib/src/notion/objects/database.dart | 43 ++++-------- lib/src/notion/rich_text.dart | 33 +-------- test/blocks/paragraph_test.dart | 15 ----- test/lists/children_test.dart | 32 ++++----- test/notion_api_test.dart | 14 ++-- test/objects/database_test.dart | 41 +++++------ 11 files changed, 87 insertions(+), 242 deletions(-) diff --git a/example/example.md b/example/example.md index 378ef2f..1c70317 100644 --- a/example/example.md +++ b/example/example.md @@ -165,26 +165,7 @@ _Parameters:_ ### Heading & Paragraph **Code** ```dart -// Create children instance: -// * Deprecated way -// Children oldWay = Children( -// heading: Heading('Test'), -// paragraph: Paragraph( -// content: [ -// Text('Lorem ipsum (A)'), -// Text( -// 'Lorem ipsum (B)', -// annotations: TextAnnotations( -// bold: true, -// underline: true, -// color: ColorsTypes.orange, -// ), -// ), -// ], -// ), -//); -// -// * New way using `addAll()` +// Option A: using `addAll(List)` Children childrenA = Children().addAll([ Heading(text: Text('Test')), Paragraph(texts: [ @@ -202,7 +183,7 @@ Children childrenA = Children().addAll([ ]), ]); -// * New way using single `add()` +// Option B: using `add(Block)` Children childrenB = Children().add(Heading(text: Text('Test'))).add(Paragraph(texts: [ Text('Lorem ipsum (A)'), @@ -218,7 +199,7 @@ Children childrenB = ], )); -// * New way using `withBlocks()` constructor +// Option C: using `withBlocks(List)` constructor Children childrenC = Children.withBlocks([ Heading(text: Text('Test')), Paragraph(texts: [ @@ -236,10 +217,28 @@ Children childrenC = Children.withBlocks([ ]), ]); +// Option D (Recommended): using main constructor +Children childrenD = Children(blocks: [ + Heading(text: Text('Test')), + Paragraph(texts: [ + Text('Lorem ipsum (A)'), + Text( + 'Lorem ipsum (B)', + annotations: TextAnnotations( + bold: true, + underline: true, + color: ColorsTypes.Orange, + ), + ), + ], children: [ + Heading(text: Text('Subtitle'), type: 3), + ]), +]); + // Send the instance to Notion notion.blocks.append( to: 'YOUR_BLOCK_ID', - children: childrenA, // or `childrenB` or `childrenC`, any of these will produce the same result. + children: childrenA, // or `childrenB`, `childrenC` or `childrenD`, any of these will produce the same result. ); ``` @@ -250,27 +249,8 @@ notion.blocks.append( ### To do **Code** ```dart -// Create children instance: -// * Deprecated way -// Children children = -// Children( -// toDo: [ -// ToDo(text: Text('This is a todo item A')), -// ToDo( -// texts: [ -// Text('This is a todo item'), -// Text( -// 'B', -// annotations: TextAnnotations(bold: true), -// ), -// ], -// ), -// ], -// ); -// -// * New way Children children = - Children.withBlocks([ + Children(blocks: [ ToDo(text: Text('This is a todo item A')), ToDo( texts: [ @@ -433,11 +413,8 @@ Children fullContent = Children.withBlocks([ ), ), Text( - 'Then you can continue writing all your content. See that if you separate the paragraph to stylized some parts you have to take in count the spaces because the ', + 'Then you can continue writing all your content. See that if you separate the paragraph to stylized some parts you have to take in count the spaces.', ), - Text('textSeparator', annotations: TextAnnotations(code: true)), - Text( - ' will be deprecated. Maybe you will see this with extra spaces because the separator but soon will be remove.') ], children: [ Heading( text: Text('This is a subtitle for the paragraph'), diff --git a/lib/src/notion/lists/children.dart b/lib/src/notion/lists/children.dart index bd15951..1b9918e 100644 --- a/lib/src/notion/lists/children.dart +++ b/lib/src/notion/lists/children.dart @@ -1,8 +1,5 @@ import '../general/notion_types.dart'; import '../objects/block.dart'; -import '../objects/blocks/heading.dart'; -import '../objects/blocks/paragraph.dart'; -import '../objects/blocks/todo.dart'; /// A representation of the children Notion object. Also list of blocks. class Children { @@ -19,23 +16,9 @@ class Children { /// Main children constructor. /// - /// _Parameters deprecated:_ Do not use the parameters, soon will be removed. - /// - /// Can receive a single [heading], a single [paragraph], and a list of [toDo] blocks. If all three are included then the three fields are added to the blocks list adding first the [heading] field, then the [paragraph], and the list of [toDo] at the end. - Children({ - @deprecated Heading? heading, - @deprecated Paragraph? paragraph, - @deprecated List? toDo, - }) { - if (heading != null) { - _blocks.add(heading); - } - if (paragraph != null) { - _blocks.add(paragraph); - } - if (toDo != null) { - _blocks.addAll(toDo.toList()); - } + /// Can receive a list of [blocks]. + Children({List blocks: const []}) { + this._blocks.addAll(blocks); } /// Constructor that initialize a Children instance with a list of blocks. diff --git a/lib/src/notion/objects/blocks/heading.dart b/lib/src/notion/objects/blocks/heading.dart index fca5fea..ac66bbb 100644 --- a/lib/src/notion/objects/blocks/heading.dart +++ b/lib/src/notion/objects/blocks/heading.dart @@ -41,13 +41,6 @@ class Heading extends Block { }) : this._content = [Text(content, annotations: annotations)], this.type = headingTypeFromInt(type); - /// Add a new [text] to the paragraph content and returns this instance. - @Deprecated('Use `addText(Block)` instead') - Heading add(Text text) { - this._content.add(text); - return this; - } - /// Add a [text] to the rich text array and returns this instance. Also can receive the [annotations] of the text. Heading addText(String text, {TextAnnotations? annotations}) { this._content.add(Text(text, annotations: annotations)); diff --git a/lib/src/notion/objects/blocks/paragraph.dart b/lib/src/notion/objects/blocks/paragraph.dart index 3680a82..96a3e62 100644 --- a/lib/src/notion/objects/blocks/paragraph.dart +++ b/lib/src/notion/objects/blocks/paragraph.dart @@ -11,14 +11,6 @@ class Paragraph extends Block { List _content = []; List _children = []; - /// The separator for the Text objects. - @Deprecated('Text separation will be by your own') - String textSeparator; - - /// The content of this block. - @Deprecated('Instead use `content`') - List get texts => _content.toList(); - /// The content of this block. List get content => _content.toList(); @@ -28,15 +20,10 @@ class Paragraph extends Block { /// Main paragraph constructor. /// /// Can receive a single [text] or a list of [texts]. If both are included also both fields are added to the heading content adding first the [text] field. Also can receive the [children] of the block. - /// - /// _Deprecated:_ [textSeparator] will be removed and the separation will be by your own. This because that's the same way that `Text` & `RichText` works on Flutter. In this way you can add annotations for a part of a word instead of only full words or phrases. - /// - /// Also a [textSeparator] can be anexed to separate the texts on the json generated using the `toJson()` function. The separator is used because when the text is displayed is all together without any kind of separation and adding the separator that behavior is avoided. By default the [textSeparator] is an space (" "). Paragraph({ Text? text, List texts: const [], List children: const [], - @deprecated this.textSeparator: ' ', }) { this._content.addAll([ if (text != null) text, @@ -54,17 +41,9 @@ class Paragraph extends Block { String content, { TextAnnotations? annotations, List children: const [], - }) : this.textSeparator = ' ', - this._content = [Text(content, annotations: annotations)], + }) : this._content = [Text(content, annotations: annotations)], this._children = children; - /// Add a new [text] to the paragraph content and returns this instance. - @Deprecated('Use `addText(Block)` instead') - Paragraph add(Text text) { - this._content.add(text); - return this; - } - /// Add a [text] to the rich text array and returns this instance. Also can receive the [annotations] of the text. Paragraph addText(String text, {TextAnnotations? annotations}) { this._content.add(Text(text, annotations: annotations)); @@ -89,9 +68,7 @@ class Paragraph extends Block { 'object': strObject, 'type': strType, strType: { - 'text': _content - .map((e) => e.toJson(textSeparator: textSeparator)) - .toList(), + 'text': _content.map((e) => e.toJson()).toList(), 'children': _children.map((e) => e.toJson()).toList(), } }; diff --git a/lib/src/notion/objects/blocks/todo.dart b/lib/src/notion/objects/blocks/todo.dart index 6917fea..c783656 100644 --- a/lib/src/notion/objects/blocks/todo.dart +++ b/lib/src/notion/objects/blocks/todo.dart @@ -11,10 +11,6 @@ class ToDo extends Block { List _content = []; List _children = []; - /// The separator for the Text objects. - @Deprecated('Text separation will be by your own') - String textSeparator; - /// The checked value. bool checked; @@ -29,16 +25,11 @@ class ToDo extends Block { /// Can receive a single [text] or a list of [texts]. If both are included also both fields are added to the heading content adding first the [text] field. Also can receive the [children] of the block. /// /// The [checked] field define if the To do option is marked as done. By default is false. - /// - /// _Deprecated:_ [textSeparator] will be removed and the separation will be by your own. This because that's the same way that `Text` & `RichText` works on Flutter. In this way you can add annotations for a part of a word instead of only full words or phrases. - /// - /// Also a [textSeparator] can be anexed to separate the texts on the json generated using the `toJson()` function. The separator is used because when the text is displayed is all together without any kind of separation and adding the separator that behavior is avoided. By default the [textSeparator] is an space (" "). ToDo({ Text? text, List texts: const [], List children: const [], this.checked: false, - @deprecated this.textSeparator: ' ', }) { this._content.addAll([ if (text != null) text, @@ -57,8 +48,7 @@ class ToDo extends Block { TextAnnotations? annotations, List children: const [], this.checked: false, - }) : this.textSeparator = ' ', - this._content = [Text(content, annotations: annotations)], + }) : this._content = [Text(content, annotations: annotations)], this._children = children; // TODO: A function that create an instance of ToDo (or Paragraph or Heading) from a Block. @@ -70,13 +60,6 @@ class ToDo extends Block { // return todo; // } - /// Add a new [text] to the paragraph content and returns this instance. - @Deprecated('Use `addText(Block)` instead') - ToDo add(Text text) { - this._content.add(text); - return this; - } - /// Add a [text] to the rich text array and returns this instance. Also can receive the [annotations] of the text. ToDo addText(String text, {TextAnnotations? annotations}) { this._content.add(Text(text, annotations: annotations)); @@ -101,9 +84,7 @@ class ToDo extends Block { 'object': strObject, 'type': strType, strType: { - 'text': _content - .map((e) => e.toJson(textSeparator: textSeparator)) - .toList(), + 'text': _content.map((e) => e.toJson()).toList(), 'children': _children.map((e) => e.toJson()).toList(), 'checked': checked, } diff --git a/lib/src/notion/objects/database.dart b/lib/src/notion/objects/database.dart index 73f010b..d085926 100644 --- a/lib/src/notion/objects/database.dart +++ b/lib/src/notion/objects/database.dart @@ -22,16 +22,18 @@ class Database extends BaseFields { /// Main database constructor. /// - /// **Important:** This main constructor will become like the `newDatabase`. If you need to create an instance with this parameters then use `withDefaults` constructor. - /// - /// Can receive the [title], the [createdTime], the [lastEditedTime] and the database [id]. + /// Can receive the [parent] (required), the [title] (empty), the [pagesColumnName] ("Name") and the [properties] (null). /// + /// The [pagesColumnName] is the value of the page column header. Database({ + required this.parent, this.title: const [], - @deprecated String createdTime: '', - @deprecated String lastEditedTime: '', - @deprecated String id: '', - }) { + String pagesColumnName: 'Name', + Properties? properties, + }) : this.properties = Properties(map: { + pagesColumnName: TitleProp(), + if (properties != null) ...properties.entries, + }) { this.id = id; this.setBaseProperties( createdTime: createdTime, @@ -39,6 +41,9 @@ class Database extends BaseFields { ); } + /// Constructor for empty database. + Database.empty(); + /// Database constructor with defaults parameters. /// /// Can receive the [parent] (none parent), [title] (empty), the [createdTime] (""), the [lastEditedTime] ("") and the database [id] ("") but every parameter is optional. @@ -56,30 +61,6 @@ class Database extends BaseFields { ); } - /// Database constructor with properties for new Database. - /// - /// **Important:** This is a temporary solution. In a future this constructor will be remove and the main constructor will be update to work like this one. - /// - /// Can receive the [parent] (required), the [title] (empty) and the [pagesColumnName] ("Name"). - /// - /// The [pagesColumnName] is the value of the page column header. - /// - Database.newDatabase({ - required this.parent, - this.title: const [], - String pagesColumnName: 'Name', - Properties? properties, - }) : this.properties = Properties(map: { - pagesColumnName: TitleProp(), - if (properties != null) ...properties.entries, - }) { - this.id = id; - this.setBaseProperties( - createdTime: createdTime, - lastEditedTime: lastEditedTime, - ); - } - /// Map a new database instance from a [json] map. factory Database.fromJson(Map json) => Database.withDefaults( id: json['id'] ?? '', diff --git a/lib/src/notion/rich_text.dart b/lib/src/notion/rich_text.dart index 234b78d..6a972f6 100644 --- a/lib/src/notion/rich_text.dart +++ b/lib/src/notion/rich_text.dart @@ -130,41 +130,12 @@ class Text { this.url = json['href'] != null ? Uri.parse(json['href']) : null; /// Convert this to a json representation valid for the Notion API. - /// - ///_Deprecated:_ [textSeparator] will be removed and the separation will be by your own. This because that's the same way that `Text` & `RichText` works on Flutter. In this way you can add annotations for a part of a word instead of only full words or phrases. - /// - /// If a [textSeparator] is given, then it's value (by default a space) is append - /// at the end of the string to allow be at the same level of other Text objects without - /// being all together. For example: - /// - /// ```dart - /// // using default (space) - /// blocks.append( - /// to: 'some_block_id', - /// children: Children( - /// paragraph: Paragraph([ - /// Text('A'), - /// Text('B',) - /// ]))); - /// // append => "A B " - /// - /// // using custom - /// blocks.append( - /// to: 'some_block_id', - /// children: Children( - /// paragraph: Paragraph([ - /// Text('A'), - /// Text('B',) - /// ], - /// textSeparator: '-'))); - /// // append => "A-B-" /// ``` - Map toJson( - {@Deprecated('Will not have replacement') String textSeparator: ''}) { + Map toJson() { Map json = { 'type': _type, 'text': { - 'content': '$text$textSeparator', + 'content': '$text', }, }; diff --git a/test/blocks/paragraph_test.dart b/test/blocks/paragraph_test.dart index f2d2a36..abe80d0 100644 --- a/test/blocks/paragraph_test.dart +++ b/test/blocks/paragraph_test.dart @@ -124,20 +124,5 @@ void main() { expect(json[blockTypeToString(BlockTypes.Paragraph)]['children'], allOf([isList, isEmpty])); }); - - test('Create json with separator', () { - String char = 'A'; - String separator = '-'; - - Map json = - Paragraph(textSeparator: separator).addText(char).toJson(); - - List jsonTexts = json[blockTypeToString(BlockTypes.Paragraph)]['text']; - - List texts = Text.fromListJson(jsonTexts); - - expect(texts, isList); - expect(texts.first.text, char + separator); - }); }); } diff --git a/test/lists/children_test.dart b/test/lists/children_test.dart index cfda491..ddff836 100644 --- a/test/lists/children_test.dart +++ b/test/lists/children_test.dart @@ -80,21 +80,23 @@ void main() { }); test('Add blocks in distinct ways', () { - Children deprecated = Children( - heading: Heading(text: Text('Test')), - paragraph: Paragraph( - texts: [ - Text('Lorem ipsum (A)'), - Text( - 'Lorem ipsum (B)', - annotations: TextAnnotations( - bold: true, - underline: true, - color: ColorsTypes.Orange, + Children children = Children( + blocks: [ + Heading(text: Text('Test')), + Paragraph( + texts: [ + Text('Lorem ipsum (A)'), + Text( + 'Lorem ipsum (B)', + annotations: TextAnnotations( + bold: true, + underline: true, + color: ColorsTypes.Orange, + ), ), - ), - ], - ), + ], + ), + ], ); Children children1 = Children.withBlocks([ @@ -138,7 +140,7 @@ void main() { ]) ]); - var json0 = deprecated.toJson(); + var json0 = children.toJson(); var json1 = children1.toJson(); var json2 = children2.toJson(); var json3 = children3.toJson(); diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index 59d7815..5fa399d 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -81,11 +81,8 @@ void main() { ), ), Text( - 'Then you can continue writing all your content. See that if you separate the paragraph to stylized some parts you have to take in count the spaces because the ', + 'Then you can continue writing all your content. See that if you separate the paragraph to stylized some parts you have to take in count the spaces.', ), - Text('textSeparator', annotations: TextAnnotations(code: true)), - Text( - ' will be deprecated. Maybe you will see this with extra spaces because the separator but soon will be remove.') ], children: [ Heading( text: Text('This is a subtitle for the paragraph'), @@ -240,7 +237,7 @@ void main() { final NotionDatabasesClient databases = NotionDatabasesClient(token: token ?? ''); - NotionResponse res = await databases.create(Database.newDatabase( + NotionResponse res = await databases.create(Database( parent: Parent.page(id: testPageId ?? ''), title: [ Text('Database from test'), @@ -262,7 +259,7 @@ void main() { final NotionDatabasesClient databases = NotionDatabasesClient(token: token ?? ''); - NotionResponse res = await databases.create(Database.newDatabase( + NotionResponse res = await databases.create(Database( parent: Parent.page(id: testPageId ?? ''), )); @@ -325,11 +322,8 @@ void main() { ), ), Text( - 'Then you can continue writing all your content. See that if you separate the paragraph to stylized some parts you have to take in count the spaces because the ', + 'Then you can continue writing all your content. See that if you separate the paragraph to stylized some parts you have to take in count the spaces.', ), - Text('textSeparator', annotations: TextAnnotations(code: true)), - Text( - ' will be deprecated. Maybe you will see this with extra spaces because the separator but soon will be remove.') ], children: [ Heading( text: Text('This is a subtitle for the paragraph'), diff --git a/test/objects/database_test.dart b/test/objects/database_test.dart index b2e3612..8da0150 100644 --- a/test/objects/database_test.dart +++ b/test/objects/database_test.dart @@ -4,7 +4,7 @@ import 'package:test/test.dart'; void main() { group('Database Instance =>', () { test('Create new empty instance', () { - Database database = Database(); + Database database = Database.empty(); expect(database, isNotNull); expect(database.title, isEmpty); @@ -13,7 +13,7 @@ void main() { }); test('Create new instance with data', () { - Database database = Database(title: [Text('Title')]) + Database database = Database.withDefaults(title: [Text('Title')]) .addProperty( name: 'Tags', property: MultiSelectProp(options: [ @@ -39,23 +39,24 @@ void main() { }); test('Create json from instance', () { - Map database = Database(title: [Text('Title')]) - .addProperty( - name: 'Tags', - property: MultiSelectProp(options: [ - MultiSelectOption(name: 'Option A'), - MultiSelectOption(name: 'Option B'), - ])) - .addProperty( - name: 'Details', - property: RichTextProp(content: [ - Text('Detail A'), - Text('Detail B'), - ])) - .addProperty( - name: 'Name', - property: TitleProp(content: [Text('Something here...')])) - .toJson(); + Map database = + Database.withDefaults(title: [Text('Title')]) + .addProperty( + name: 'Tags', + property: MultiSelectProp(options: [ + MultiSelectOption(name: 'Option A'), + MultiSelectOption(name: 'Option B'), + ])) + .addProperty( + name: 'Details', + property: RichTextProp(content: [ + Text('Detail A'), + Text('Detail B'), + ])) + .addProperty( + name: 'Name', + property: TitleProp(content: [Text('Something here...')])) + .toJson(); expect(database, isNotNull); expect(database['object'], 'database'); @@ -117,7 +118,7 @@ void main() { }); test('Add properties from json', () { - Database database = Database().addPropertiesFromJson({ + Database database = Database.empty().addPropertiesFromJson({ "Tags": { "id": ">cp;", "type": "multi_select", From d9f8c11e2c38f9b8a4b155ce11cc25ac9314a7f0 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 30 Jul 2021 10:37:24 -0500 Subject: [PATCH 08/42] Add test for new database constructor --- test/objects/database_test.dart | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/objects/database_test.dart b/test/objects/database_test.dart index 8da0150..d514de9 100644 --- a/test/objects/database_test.dart +++ b/test/objects/database_test.dart @@ -12,6 +12,22 @@ void main() { expect(database.object, ObjectTypes.Database); }); + test('Create new database instance', () { + Database database = Database( + parent: Parent.page(id: 'some_id'), + title: [Text('Database title')], + pagesColumnName: 'CustomColumName', + properties: Properties(map: { + 'Description': RichTextProp(), + }), + ); + + expect(database.parent.type, ParentType.Page); + expect(database.title.length, 1); + expect(database.properties.entries.length, + 2); // pages column name and 'Description' + }); + test('Create new instance with data', () { Database database = Database.withDefaults(title: [Text('Title')]) .addProperty( From 0e7a2cd8500da0f97fdc0a772b1cad9b5f1809cd Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 30 Jul 2021 10:54:24 -0500 Subject: [PATCH 09/42] Add tests to improve coverage --- test/lists/pagination_test.dart | 12 ++++++++++-- test/rich_text_test.dart | 21 ++++++++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/test/lists/pagination_test.dart b/test/lists/pagination_test.dart index 3ca27f9..65d667b 100644 --- a/test/lists/pagination_test.dart +++ b/test/lists/pagination_test.dart @@ -157,9 +157,17 @@ void main() { test('Blocks list with filter', () async { Pagination pag = Pagination.fromJson(longBlocksJsonList); - List filtered = pag.filterBlocks(onlyLeft: BlockTypes.H1); + List exclude = pag.filterBlocks(exclude: [BlockTypes.H1]); + List onlyLeft = pag.filterBlocks(onlyLeft: BlockTypes.H1); + List include = pag.filterBlocks(include: [BlockTypes.H1]); + List single = + pag.filterBlocks(id: '71fa679a-f072-4e70-bf52-6b1e770f5c3c'); - expect(filtered.length, lessThan(pag.list.length)); + expect(exclude.length, lessThan(pag.list.length)); + expect(onlyLeft.length, lessThan(pag.list.length)); + expect(onlyLeft, include); + expect(single.length, 1); + expect(single.first.type, BlockTypes.Paragraph); }); test('Wrong json', () { diff --git a/test/rich_text_test.dart b/test/rich_text_test.dart index dbcc834..dc65c27 100644 --- a/test/rich_text_test.dart +++ b/test/rich_text_test.dart @@ -2,7 +2,24 @@ import 'package:notion_api/notion.dart'; import 'package:test/test.dart'; void main() { - group('Rich text tests', () { + group('Rich text tests =>', () { + test('Create a json from stylized instance', () { + Map json = Text( + '', + annotations: TextAnnotations( + bold: true, + strikethrough: true, + ), + ).toJson(); + + expect(json.containsKey('annotations'), true); + expect(json['annotations'].containsKey('italic'), false); + expect(json['annotations'].containsKey('strikethrough'), true); + expect(json['annotations'].containsKey('bold'), true); + expect(json['annotations']['strikethrough'], true); + expect(json['annotations']['bold'], true); + }); + test('Create instances of Text with default styles', () { Text bold = Text.bold('This text is bold and green', color: ColorsTypes.Green); @@ -22,7 +39,9 @@ void main() { expect(green.annotations!.color, ColorsTypes.Green); expect(blue.annotations!.color, ColorsTypes.Blue); }); + }); + group('Rich text list test =>', () { test('Create a list of instances of Text', () { List list = Text.list(texts: [ Text('A'), From ec056809cfc9fbef41cb1bd8aaaf6c0eca250943 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 30 Jul 2021 12:01:50 -0500 Subject: [PATCH 10/42] Update information for next release (2.0.0) Update example --- CHANGELOG.md | 44 ++++--- README.md | 15 +-- ROADMAP.md | 48 ++++--- example/example.md | 174 +++++++++++++------------- pubspec.yaml | 2 +- test/notion_api_test.dart | 255 +++++++++++++------------------------- 6 files changed, 234 insertions(+), 304 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c01111..0372da1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -106,38 +106,36 @@ * Remove named parameters for `Children` class * Update documentation -## v1.2.0: -> Release date: 27/Jul/2021 -* Implement new endpoints - * Update page: https://developers.notion.com/reference/patch-page#archive-delete-a-page - * Create database: https://developers.notion.com/reference/create-a-database -* Add `Page` support for responses -* Add more colors for Text -* Add list of endpoints implemented on package -* Improve coverage - -## v1.2.1: -> Release date: 02/Aug/2021 -* Add sugestion on issue [#11](https://github.com/jonathangomz/notion_api/issues/11): +## v2.0.0-beta1 +> Release date: 30/Aug/2021 +* 🐣 Add constructor for empty `Database`. +* 🐣 Add parameter `blocks` for `Children` constructor. +* 🍗 Remove deprecated code: + * `textSeparation` + * Parameter constructors for `Children`: + * `heading` + * `paragraph` + * `toDo` +* 🐣 Add suggestions on issue [#11](https://github.com/jonathangomz/notion_api/issues/11): * Update exports to improve usage * Add private folder (`src/`) -* Add constructors with only single text content with default style for: - * `Paragraph.text('some text here...')` - * `ToDo.text('some text here...', checked: true)` - * `Heading.text('some text here...', type: 2)` - * `BulletedListItem.text('some text here...')` - * `NumberedListItem.text('some text here...')` - * `Toggle.text('some text here...', children: [])` -* Add more constructors for `Heading` class: +* 🐣 Add constructors with only single text content with default style for: + * `Paragraph`: `Paragraph.text('some text here...')` + * `ToDo`: `ToDo.text('some text here...', checked: true)` + * `Heading`: `Heading.text('some text here...', type: 2)` + * `BulletedListItem`: `BulletedListItem.text('some text here...')` + * `NumberedListItem`: `NumberedListItem.text('some text here...')` + * `Toggle`: `Toggle.text('some text here...', children: [])` +* 🐣 Add more constructors for `Heading` class: * `one`: Heading with type 1 by default. * `two`: Heading with type 2 by default. * `three`: Heading with type 3 by default. -* Add more constructors for `Text` class: +* 🐣 Add more constructors for `Text` class: * `code`: Text with code style by default. * `italic`: Text with italic style by default. * `bold`: Text with bold style by default. * `underline`: Text with underline style by default. * `color`: Text with different color of default. -* Add `list(List texts, String separator, String lastSeparator)`: +* 🐣 Add `list(List texts, String separator, String lastSeparator)`: * **A static method** * Generate a textual list of texts separated by comma (by default). \ No newline at end of file diff --git a/README.md b/README.md index aea9d73..0139a91 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ See the [ROADMAP](ROADMAP.md) file to see what is coming next. - [Tests](#tests) - [Example:](#example) - [Next release](#next-release) - - [v1.3.0](#v130) + - [v2.0.0](#v200) # API implemented | Endpoint | Avaliable | Notes @@ -70,7 +70,7 @@ _To see code to create the page above or see more examples [go here](https://git ### Append blocks children ```dart // Create children instance: -Children children = Children.withBlocks([ +Children children = Children(blocks: [ Heading(text: Text('Test')), Paragraph(texts: [ Text('Lorem ipsum (A)'), @@ -147,13 +147,8 @@ TEST_BLOCK_HEADING_ID=c8hac4bb32af48889228bf483d938e34 ``` # Next release -## v1.3.0 -> Release date: 06/Aug/2021 -* Maybe fix errors creating page with children. I don't know if is an error with Notion API. -* Add `Query a database` endpoint: - * https://developers.notion.com/reference/post-database-query -* Add more properties for pages and databases: - * Page properties: https://developers.notion.com/reference/page#page-property-value - * Database properties: https://developers.notion.com/reference/database#database-property +## v2.0.0 +> Release date: 04/Aug/2021 +* 🔧 Fix any error on beta [1]:https://pub.dev/documentation/notion_api/1.0.0-beta1/responses_notion_response/NotionResponse-class.html \ No newline at end of file diff --git a/ROADMAP.md b/ROADMAP.md index a35fc53..9f05210 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -3,32 +3,44 @@ ## More coming soon... If you have suggestions feel free to create an Issue or to create a PR with the feature. -## v1.3.0 -> Release date: 06/Aug/2021 -* Maybe fix errors creating page with children. I don't know if is an error with Notion API. -* Add `Query a database` endpoint: +## v2.0.1 +> Release date: 09/Aug/2021 +* 🔧 Maybe fix errors creating page with children. I don't know if is an error with Notion API. +* 🐣 Add `Query a database` endpoint: * https://developers.notion.com/reference/post-database-query -* Add more properties for pages and databases: +* 🐣 Add more properties for pages and databases: * Page properties: https://developers.notion.com/reference/page#page-property-value * Database properties: https://developers.notion.com/reference/database#database-property -## v1.2.1: ✅ -> Release date: 02/Aug/2021 -* Add sugestion on issue [#11](https://github.com/jonathangomz/notion_api/issues/11): +## v2.0.0 +> Release date: 04/Aug/2021 +* 🔧 Fix any error on beta + +## v2.0.0-beta1 ✅ +> Release date: 30/Aug/2021 +* 🐣 Add constructor for empty `Database`. +* 🐣 Add parameter `blocks` for `Children` constructor. +* 🍗 Remove deprecated code: + * `textSeparation` + * Parameter constructors for `Children`: + * `heading` + * `paragraph` + * `toDo` +* 🐣 Add suggestions on issue [#11](https://github.com/jonathangomz/notion_api/issues/11): * Update exports to improve usage * Add private folder (`src/`) -* Add constructors with only single text content with default style for: - * `Paragraph.text('some text here...')` - * `ToDo.text('some text here...', checked: true)` - * `Heading.text('some text here...', type: 2)` - * `BulletedListItem.text('some text here...')` - * `NumberedListItem.text('some text here...')` - * `Toggle.text('some text here...', children: [])` -* Add more constructors for `Heading` class: +* 🐣 Add constructors with only single text content with default style for: + * `Paragraph`: `Paragraph.text('some text here...')` + * `ToDo`: `ToDo.text('some text here...', checked: true)` + * `Heading`: `Heading.text('some text here...', type: 2)` + * `BulletedListItem`: `BulletedListItem.text('some text here...')` + * `NumberedListItem`: `NumberedListItem.text('some text here...')` + * `Toggle`: `Toggle.text('some text here...', children: [])` +* 🐣 Add more constructors for `Heading` class: * `one`: Heading with type 1 by default. * `two`: Heading with type 2 by default. * `three`: Heading with type 3 by default. -* Add more constructors for `Text` class: +* 🐣 Add more constructors for `Text` class: * `code`: Text with code style by default. * `italic`: Text with italic style by default. * `bold`: Text with bold style by default. @@ -36,7 +48,7 @@ If you have suggestions feel free to create an Issue or to create a PR with the * `color`: Text with different color of default. * [**CANCELED**] ~~`sep`: Text separator.~~ * ~~Example: `Text.sep()`, by default, will insert " " in a list of `Text` instances, but it will be able to do more things that I don't know yet, hehe. **It may be unnecessary**. Can help to make the code more readable.~~ -* Add `list(List texts, String separator, String lastSeparator)`: +* 🐣 Add `list(List texts, String separator, String lastSeparator)`: * **A static method** * Generate a textual list of texts separated by comma (by default). diff --git a/example/example.md b/example/example.md index 1c70317..1a774ce 100644 --- a/example/example.md +++ b/example/example.md @@ -106,13 +106,9 @@ _See more at https://developers.notion.com/reference/get-page_ You have to define the parent of the page. It can be: - `page` - `workspace` - -There is a constructor for each one (_see example below_) but the main constructor can be used as well but the `ParentType` will be required. - -**Note:** The `newDatabase` constructor is a temporary solution while the main constructor is deprecating their fields until it became the sustitute for this constructor. ```dart // With page parent -Page page = Database.newDatabase( +Page page = Database( parent: Parent.page(id: 'YOUR_PAGE_ID'), title: [ Text('Database from examples'), @@ -283,7 +279,7 @@ notion.blocks.append( **Code** ```dart Children children = - Children.withBlocks([ + Children(blocks: [ Toggle( text: Text('This is a toggle block'), children: [ @@ -316,7 +312,7 @@ notion.blocks.append( **Code** ```dart Children children = - Children.withBlocks([ + Children(blocks: [ BulletedListItem(text: Text('This is a bulleted list item A')), BulletedListItem(text: Text('This is a bulleted list item B')), BulletedListItem( @@ -347,7 +343,7 @@ notion.blocks.append( **Code** ```dart Children children = - Children.withBlocks([ + Children(blocks: [ NumberedListItem(text: Text('This is a numbered list item A')), NumberedListItem(text: Text('This is a numbered list item B')), NumberedListItem( @@ -379,7 +375,7 @@ _See more at https://developers.notion.com/reference/patch-block-children_ [1]: https://developers.notion.com/reference/get-databases # Full example -Go to see the result https://jonathangomz.notion.site/notion_api-example-0893dd2cb38a413d90165cb810b3c019 +Go to see the result https://jonathangomz.notion.site/notion_api-example-81cb020a620b4db19f8cf85e82be3d53 ```dart // Initialize the main Notion client @@ -398,87 +394,99 @@ var newPage = await notion.pages.create(page); String newPageId = newPage.page!.id; // Create the instance of the content of the page -Children fullContent = Children.withBlocks([ - Heading(text: Text('This the title')), - Paragraph(texts: [ - Text( - 'Here you can write all the content of the paragraph but if you want to have another style for a single word you will have to do ', - ), - Text( - 'this. ', - annotations: TextAnnotations( - color: ColorsTypes.Green, - bold: true, - italic: true, - ), - ), - Text( - 'Then you can continue writing all your content. See that if you separate the paragraph to stylized some parts you have to take in count the spaces.', - ), - ], children: [ - Heading( - text: Text('This is a subtitle for the paragraph'), - type: 2, - ), +Children fullContent = Children( + blocks: [ + Heading(text: Text('Examples')), Paragraph(texts: [ Text( - 'You can also have children for some blocks like ', + 'Here you can write all the content of the paragraph but if you want to have another style for a single word you will have to do ', ), - ...Text.list(texts: [ - Text.code('Paragraph'), - Text.code('ToDo'), - Text.code('BulletedListItems'), - Text.code('NumberedListItems'), - ], lastSeparator: ' or '), - Text('.'), - ]), - Paragraph.text( - 'Also, if your paragraph will have the same style you can write all your text directly like this to avoid using a list. This constructor can be found for every block.', - ), - Paragraph( - texts: [ - Text('There are a few shortcuts for basic styles like: '), + Text( + 'this. ', + annotations: TextAnnotations( + color: ColorsTypes.Green, + bold: true, + italic: true, + ), + ), + Text( + 'Then you can continue writing all your content. See that if you separate the paragraph to stylized some parts you have to take in count the spaces.', + ), + ], children: [ + Heading.text('Children subtitle', type: 2), + Paragraph(texts: [ + Text( + 'You can also have children for some blocks like ', + ), ...Text.list(texts: [ - Text.bold('all text bold and green', color: ColorsTypes.Green), - Text.code('all text code'), - Text.italic('all text italic'), - Text.underline('all text underline'), - ]), + Text.code('Paragraph'), + Text.code('ToDo'), + Text.code('BulletedListItems'), + Text.code('NumberedListItems'), + ], lastSeparator: ' or '), Text('.'), - ], - ), - ]), - Heading(text: Text('Blocks'), type: 2), - Heading(text: Text('ToDo'), type: 3), - ToDo(text: Text('Daily meeting'), checked: true), - ToDo(text: Text('Clean the house')), - ToDo(text: Text('Do the laundry')), - ToDo(text: Text('Call mom'), children: [ - Paragraph(texts: [ - Text('Note: ', annotations: TextAnnotations(bold: true)), - Text('Remember to call her before 20:00'), - ]), - ]), - Heading(text: Text('Lists'), type: 3), - BulletedListItem(text: Text('Milk')), - BulletedListItem(text: Text('Cereal')), - BulletedListItem(text: Text('Eggs')), - BulletedListItem(text: Text('Tortillas of course')), - Paragraph( - text: Text('The numbered list are ordered by default by notion.'), - ), - NumberedListItem(text: Text('Notion')), - NumberedListItem(text: Text('Keep by Google')), - NumberedListItem(text: Text('Evernote')), - Heading(text: Text('Toggle'), type: 3), - Toggle(text: Text('Toogle items'), children: [ - Paragraph( - text: Text( - 'Toogle items are blocks that can show or hide their children, and their children can be any other block.', + ]), + Paragraph.text( + 'Also, if your paragraph will have the same style you can write all your text directly like this to avoid using a list.', + ), + Paragraph( + texts: [ + Text('You can use styles for texts like: '), + ...Text.list(texts: [ + Text.color('green text', color: ColorsTypes.Green), + Text.color('blue text', color: ColorsTypes.Blue), + Text.color('red text', color: ColorsTypes.Red), + Text.color('purple text', color: ColorsTypes.Purple), + Text.underline('underline text'), + Text.code('code format text'), + Text.italic('italic text'), + Text('strikethrough text', + annotations: TextAnnotations(strikethrough: true)), + Text( + 'mix styles', + annotations: TextAnnotations( + bold: true, + italic: true, + underline: true, + color: ColorsTypes.Orange, + ), + ), + ], lastSeparator: ' or '), + Text('!') + ], ), + ]), + Heading.text('Blocks', type: 2), + Heading.text('ToDo', type: 3), + ToDo.text('Daily meeting', checked: true), + ToDo.text('Clean the house'), + ToDo.text('Do the laundry'), + ToDo.text('Call mom', children: [ + Paragraph(texts: [ + Text.bold('Note: '), + Text('Remember to call her before 20:00'), + ]), + ]), + Heading.text('Lists', type: 3), + BulletedListItem.text('Milk'), + BulletedListItem.text('Cereal'), + BulletedListItem.text('Eggs'), + BulletedListItem.text('Tortillas of course'), + Paragraph.text('The numbered list are ordered by default by notion.'), + NumberedListItem.text('Notion'), + NumberedListItem.text('Keep by Google'), + NumberedListItem.text('Evernote'), + Heading.text('Toggle', type: 3), + Toggle.text( + 'Toogle items', + children: [ + Paragraph.text( + 'Toogle items are blocks that can show or hide their children, and their children can be any other block.', + ), + ], ), - ]) -]); + ], +); // Append the content to the page var res = await notion.blocks.append( diff --git a/pubspec.yaml b/pubspec.yaml index bb54fbc..5e199c4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: notion_api description: A wrapper for the public beta Notion API to manage it like a Notion SDK package for dart. -version: 1.2.1 +version: 2.0.0-beta1 homepage: https://github.com/jonathangomz/notion_api environment: diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index 5fa399d..345dc11 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -66,87 +66,99 @@ void main() { }); test('Create a page with full example', () async { - Children fullContent = Children.withBlocks([ - Heading(text: Text('This the title')), - Paragraph(texts: [ - Text( - 'Here you can write all the content of the paragraph but if you want to have another style for a single word you will have to do ', - ), - Text( - 'this. ', - annotations: TextAnnotations( - color: ColorsTypes.Green, - bold: true, - italic: true, - ), - ), - Text( - 'Then you can continue writing all your content. See that if you separate the paragraph to stylized some parts you have to take in count the spaces.', - ), - ], children: [ - Heading( - text: Text('This is a subtitle for the paragraph'), - type: 2, - ), + Children fullContent = Children( + blocks: [ + Heading(text: Text('Examples')), Paragraph(texts: [ Text( - 'You can also have children for some blocks like ', + 'Here you can write all the content of the paragraph but if you want to have another style for a single word you will have to do ', ), - ...Text.list(texts: [ - Text.code('Paragraph'), - Text.code('ToDo'), - Text.code('BulletedListItems'), - Text.code('NumberedListItems'), - ], lastSeparator: ' or '), - Text('.'), - ]), - Paragraph.text( - 'Also, if your paragraph will have the same style you can write all your text directly like this to avoid using a list. This constructor can be found for every block.', - ), - Paragraph( - texts: [ - Text('There are a few shortcuts for basic styles like: '), + Text( + 'this. ', + annotations: TextAnnotations( + color: ColorsTypes.Green, + bold: true, + italic: true, + ), + ), + Text( + 'Then you can continue writing all your content. See that if you separate the paragraph to stylized some parts you have to take in count the spaces.', + ), + ], children: [ + Heading.text('Children subtitle', type: 2), + Paragraph(texts: [ + Text( + 'You can also have children for some blocks like ', + ), ...Text.list(texts: [ - Text.bold('all text bold and green', color: ColorsTypes.Green), - Text.code('all text code'), - Text.italic('all text italic'), - Text.underline('all text underline'), - ]), + Text.code('Paragraph'), + Text.code('ToDo'), + Text.code('BulletedListItems'), + Text.code('NumberedListItems'), + ], lastSeparator: ' or '), Text('.'), - ], - ), - ]), - Heading(text: Text('Blocks'), type: 2), - Heading(text: Text('ToDo'), type: 3), - ToDo(text: Text('Daily meeting'), checked: true), - ToDo(text: Text('Clean the house')), - ToDo(text: Text('Do the laundry')), - ToDo(text: Text('Call mom'), children: [ - Paragraph(texts: [ - Text('Note: ', annotations: TextAnnotations(bold: true)), - Text('Remember to call her before 20:00'), - ]), - ]), - Heading(text: Text('Lists'), type: 3), - BulletedListItem(text: Text('Milk')), - BulletedListItem(text: Text('Cereal')), - BulletedListItem(text: Text('Eggs')), - BulletedListItem(text: Text('Tortillas of course')), - Paragraph( - text: Text('The numbered list are ordered by default by notion.'), - ), - NumberedListItem(text: Text('Notion')), - NumberedListItem(text: Text('Keep by Google')), - NumberedListItem(text: Text('Evernote')), - Heading(text: Text('Toggle'), type: 3), - Toggle(text: Text('Toogle items'), children: [ - Paragraph( - text: Text( - 'Toogle items are blocks that can show or hide their children, and their children can be any other block.', + ]), + Paragraph.text( + 'Also, if your paragraph will have the same style you can write all your text directly like this to avoid using a list.', ), + Paragraph( + texts: [ + Text('You can use styles for texts like: '), + ...Text.list(texts: [ + Text.color('green text', color: ColorsTypes.Green), + Text.color('blue text', color: ColorsTypes.Blue), + Text.color('red text', color: ColorsTypes.Red), + Text.color('purple text', color: ColorsTypes.Purple), + Text.underline('underline text'), + Text.code('code format text'), + Text.italic('italic text'), + Text('strikethrough text', + annotations: TextAnnotations(strikethrough: true)), + Text( + 'mix styles', + annotations: TextAnnotations( + bold: true, + italic: true, + underline: true, + color: ColorsTypes.Orange, + ), + ), + ], lastSeparator: ' or '), + Text('!') + ], + ), + ]), + Heading.text('Blocks', type: 2), + Heading.text('ToDo', type: 3), + ToDo.text('Daily meeting', checked: true), + ToDo.text('Clean the house'), + ToDo.text('Do the laundry'), + ToDo.text('Call mom', children: [ + Paragraph(texts: [ + Text.bold('Note: '), + Text('Remember to call her before 20:00'), + ]), + ]), + Heading.text('Lists', type: 3), + BulletedListItem.text('Milk'), + BulletedListItem.text('Cereal'), + BulletedListItem.text('Eggs'), + BulletedListItem.text('Tortillas of course'), + Paragraph.text('The numbered list are ordered by default by notion.'), + NumberedListItem.text('Notion'), + NumberedListItem.text('Keep by Google'), + NumberedListItem.text('Evernote'), + Heading.text('Toggle', type: 3), + Toggle.text( + 'Toogle items', + children: [ + Paragraph.text( + 'Toogle items are blocks that can show or hide their children, and their children can be any other block.', + ), + ], ), - ]) - ]); + ], + ); final NotionClient notion = NotionClient(token: token ?? ''); @@ -302,101 +314,6 @@ void main() { expect(res.content.length, lessThanOrEqualTo(limit)); }); - test('Append complex stuff', () async { - final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); - - NotionResponse res = await blocks.append( - to: testBlockId as String, - children: Children.withBlocks([ - Heading(text: Text('This the title')), - Paragraph(texts: [ - Text( - 'Here you can write all the content of the paragraph but if you want to have another style for a single word you will have to do ', - ), - Text( - 'this. ', - annotations: TextAnnotations( - color: ColorsTypes.Green, - bold: true, - italic: true, - ), - ), - Text( - 'Then you can continue writing all your content. See that if you separate the paragraph to stylized some parts you have to take in count the spaces.', - ), - ], children: [ - Heading( - text: Text('This is a subtitle for the paragraph'), - type: 2, - ), - Paragraph(texts: [ - Text( - 'You can also have children for some blocks like ', - ), - Text( - 'Paragraph', - annotations: TextAnnotations(code: true), - ), - Text(', '), - Text( - 'ToDo', - annotations: TextAnnotations(code: true), - ), - Text(', '), - Text( - 'BulletedListItems', - annotations: TextAnnotations(code: true), - ), - Text(' or '), - Text( - 'NumberedListItems', - annotations: TextAnnotations(code: true), - ), - Text('.'), - ]), - Paragraph( - text: Text( - 'Also, if your paragraph will have the same style you can write all your text directly like this to avoid using a list.', - ), - ), - ]), - Heading(text: Text('Blocks'), type: 2), - Heading(text: Text('ToDo'), type: 3), - ToDo(text: Text('Daily meeting'), checked: true), - ToDo(text: Text('Clean the house')), - ToDo(text: Text('Do the laundry')), - ToDo(text: Text('Call mom'), children: [ - Paragraph(texts: [ - Text('Note: ', annotations: TextAnnotations(bold: true)), - Text('Remember to call her before 20:00'), - ]), - ]), - Heading(text: Text('Lists'), type: 3), - BulletedListItem(text: Text('Milk')), - BulletedListItem(text: Text('Cereal')), - BulletedListItem(text: Text('Eggs')), - BulletedListItem(text: Text('Tortillas of course')), - Paragraph( - text: Text('The numbered list are ordered by default by notion.'), - ), - NumberedListItem(text: Text('Notion')), - NumberedListItem(text: Text('Keep by Google')), - NumberedListItem(text: Text('Evernote')), - Heading(text: Text('Toggle'), type: 3), - Toggle(text: Text('Toogle items'), children: [ - Paragraph( - text: Text( - 'Toogle items are blocks that can show or hide their children, and their children can be any other block.', - ), - ), - ]) - ]), - ); - - expect(res.status, 200); - expect(res.isOk, true); - }); - test('Append heading & text', () async { final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); From ba9a01795711ca5c6fda7172487f9408903fe8e2 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 30 Jul 2021 12:38:47 -0500 Subject: [PATCH 11/42] Rename package entry point to match package name --- lib/{notion.dart => notion_api.dart} | 0 test/blocks/block.dart | 2 +- test/blocks/bulleted_list_item_test.dart | 2 +- test/blocks/heading_test.dart | 2 +- test/blocks/numbered_list_item_test.dart | 2 +- test/blocks/paragraph_test.dart | 2 +- test/blocks/todo_test.dart | 2 +- test/blocks/toggle_test.dart | 2 +- test/general_test.dart | 2 +- test/lists/children_test.dart | 2 +- test/lists/pagination_test.dart | 2 +- test/lists/properties_test.dart | 2 +- test/notion_api_test.dart | 2 +- test/objects/database_test.dart | 2 +- test/objects/page_test.dart | 2 +- test/property_test.dart | 2 +- test/response_test.dart | 2 +- test/rich_text_test.dart | 2 +- test/utils_test.dart | 2 +- 19 files changed, 18 insertions(+), 18 deletions(-) rename lib/{notion.dart => notion_api.dart} (100%) diff --git a/lib/notion.dart b/lib/notion_api.dart similarity index 100% rename from lib/notion.dart rename to lib/notion_api.dart diff --git a/test/blocks/block.dart b/test/blocks/block.dart index b36207f..3580ad0 100644 --- a/test/blocks/block.dart +++ b/test/blocks/block.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/blocks/bulleted_list_item_test.dart b/test/blocks/bulleted_list_item_test.dart index 5cf1e5a..7b1acb5 100644 --- a/test/blocks/bulleted_list_item_test.dart +++ b/test/blocks/bulleted_list_item_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/blocks/heading_test.dart b/test/blocks/heading_test.dart index c91e0a8..6a77e67 100644 --- a/test/blocks/heading_test.dart +++ b/test/blocks/heading_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/blocks/numbered_list_item_test.dart b/test/blocks/numbered_list_item_test.dart index 5d2053e..e0ecc79 100644 --- a/test/blocks/numbered_list_item_test.dart +++ b/test/blocks/numbered_list_item_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/blocks/paragraph_test.dart b/test/blocks/paragraph_test.dart index abe80d0..c34d673 100644 --- a/test/blocks/paragraph_test.dart +++ b/test/blocks/paragraph_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/blocks/todo_test.dart b/test/blocks/todo_test.dart index 3e828cb..5dca746 100644 --- a/test/blocks/todo_test.dart +++ b/test/blocks/todo_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/blocks/toggle_test.dart b/test/blocks/toggle_test.dart index ed42759..4c1955d 100644 --- a/test/blocks/toggle_test.dart +++ b/test/blocks/toggle_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/general_test.dart b/test/general_test.dart index 5d3b03f..2e359a1 100644 --- a/test/general_test.dart +++ b/test/general_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:notion_api/src/notion/objects/base_fields.dart'; import 'package:test/test.dart'; diff --git a/test/lists/children_test.dart b/test/lists/children_test.dart index ddff836..8ad09e2 100644 --- a/test/lists/children_test.dart +++ b/test/lists/children_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; import '../long_data.dart'; diff --git a/test/lists/pagination_test.dart b/test/lists/pagination_test.dart index 65d667b..57576c3 100644 --- a/test/lists/pagination_test.dart +++ b/test/lists/pagination_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; import '../long_data.dart'; diff --git a/test/lists/properties_test.dart b/test/lists/properties_test.dart index 5c431bd..5a232ab 100644 --- a/test/lists/properties_test.dart +++ b/test/lists/properties_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index 345dc11..61acf0e 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -1,7 +1,7 @@ import 'dart:io' show Platform; import 'package:dotenv/dotenv.dart' show load, env, clean; -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/objects/database_test.dart b/test/objects/database_test.dart index d514de9..655c6b9 100644 --- a/test/objects/database_test.dart +++ b/test/objects/database_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/objects/page_test.dart b/test/objects/page_test.dart index 54e2237..2101cc3 100644 --- a/test/objects/page_test.dart +++ b/test/objects/page_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/property_test.dart b/test/property_test.dart index baf5700..c7ea7a9 100644 --- a/test/property_test.dart +++ b/test/property_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/response_test.dart b/test/response_test.dart index 3c57e9c..6a06e03 100644 --- a/test/response_test.dart +++ b/test/response_test.dart @@ -1,7 +1,7 @@ import 'dart:io' show Platform; import 'package:dotenv/dotenv.dart' show load, env, clean; -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/rich_text_test.dart b/test/rich_text_test.dart index dc65c27..c576fa0 100644 --- a/test/rich_text_test.dart +++ b/test/rich_text_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { diff --git a/test/utils_test.dart b/test/utils_test.dart index 71c1dd4..d996237 100644 --- a/test/utils_test.dart +++ b/test/utils_test.dart @@ -1,4 +1,4 @@ -import 'package:notion_api/notion.dart'; +import 'package:notion_api/notion_api.dart'; import 'package:test/test.dart'; void main() { From 44c51d3250925f562c69d11d8b4032a5866c9925 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 30 Jul 2021 12:40:53 -0500 Subject: [PATCH 12/42] Fix typo --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0139a91..759dbc8 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,10 @@ See the [ROADMAP](ROADMAP.md) file to see what is coming next. | Retrieve a database | ✅ | | Query a database | 🏗 | Working on it | List databases | ✅ | -| Create a database | ✅ | Workin on more properties +| Create a database | ✅ | Working on more properties | Retrieve a page | ✅ | -| Create a page | ✅ | Workin on more properties -| Update a page | ✅ | Workin on more properties +| Create a page | ✅ | Working on more properties +| Update a page | ✅ | Working on more properties | Retrieve block children | ✅ | | Append block children | ✅ | | Retrieve a user | | From b1c828cbc1e899088e29b9fd36f194bfaf6002ec Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 6 Aug 2021 12:31:34 -0500 Subject: [PATCH 13/42] Refactor to look like oficial Notion SDK with Javascript --- lib/notion_api.dart | 14 +-- lib/src/notion_blocks.dart | 20 ++--- lib/src/notion_databases.dart | 16 ++-- lib/src/notion_pages.dart | 20 ++--- test/notion_api_test.dart | 163 ++++++++++++++++++---------------- test/response_test.dart | 33 +++---- 6 files changed, 136 insertions(+), 130 deletions(-) diff --git a/lib/notion_api.dart b/lib/notion_api.dart index 48c6134..26364b7 100644 --- a/lib/notion_api.dart +++ b/lib/notion_api.dart @@ -23,7 +23,7 @@ export 'package:notion_api/src/responses/notion_response.dart'; export 'package:notion_api/src/utils/utils.dart'; /// A Notion API client. -class NotionClient { +class Client { /// The Notion API client for pages requests. NotionPagesClient pages; @@ -35,17 +35,17 @@ class NotionClient { /// Main Notion client constructor. /// - /// Require the [token] to authenticate the requests. Also can receive the API [version] where to make the calls, which is the latests by default (v1); and the [dateVersion] which is by default "2021-05-13" (the latest at 04/07/2021). + /// Require the [auth] to authenticate the requests. Also can receive the API [version] where to make the calls, which is the latests by default (v1); and the [dateVersion] which is by default "2021-05-13" (the latest at 04/07/2021). /// /// This class is used as the main entry point for all clients. From the instances of this class any other client can be used. - NotionClient({ - required String token, + Client({ + required String auth, String version: latestVersion, String dateVersion: latestDateVersion, }) : this.pages = NotionPagesClient( - token: token, version: version, dateVersion: dateVersion), + auth: auth, version: version, dateVersion: dateVersion), this.databases = NotionDatabasesClient( - token: token, version: version, dateVersion: dateVersion), + auth: auth, version: version, dateVersion: dateVersion), this.blocks = NotionBlockClient( - token: token, version: version, dateVersion: dateVersion); + auth: auth, version: version, dateVersion: dateVersion); } diff --git a/lib/src/notion_blocks.dart b/lib/src/notion_blocks.dart index e1b9dfc..b8362f0 100644 --- a/lib/src/notion_blocks.dart +++ b/lib/src/notion_blocks.dart @@ -24,23 +24,23 @@ class NotionBlockClient { /// Main Notion block client constructor. /// - /// Require the [token] to authenticate the requests, and the API [version] where to make the calls, which is the latests by default (v1). + /// Require the [auth] token to authenticate the requests, and the API [version] where to make the calls, which is the latests by default (v1). Also can receive the [dateVersion], which is by default "2021-05-13". NotionBlockClient({ - required String token, + required String auth, String version: latestVersion, String dateVersion: latestDateVersion, - }) : this._token = token, + }) : this._token = auth, this._v = version, this._dateVersion = dateVersion; - /// Retrieve the block children from block with [id]. + /// Retrieve the block children from block specified by the [block_id]. /// /// A [startCursor] can be defined to specify the page where to start. /// Also a [pageSize] can be defined to limit the result. The max value is 100. /// /// _See more at https://developers.notion.com/reference/get-block-children_ - Future fetch( - String id, { + Future list({ + required String block_id, String? startCursor, int? pageSize, }) async { @@ -53,7 +53,7 @@ class NotionBlockClient { } http.Response response = await http - .get(Uri.https(host, '/$_v/$path/$id/children', query), headers: { + .get(Uri.https(host, '/$_v/$path/$block_id/children', query), headers: { 'Authorization': 'Bearer $_token', 'Notion-Version': _dateVersion, }); @@ -61,15 +61,15 @@ class NotionBlockClient { return NotionResponse.fromResponse(response); } - /// Append a block [children] [to] a specific block. + /// Append [children] to a block specified by the [block_id]. /// /// _See more at https://developers.notion.com/reference/patch-block-children_ Future append({ - required String to, + required String block_id, required Children children, }) async { http.Response res = await http.patch( - Uri.https(host, '/$_v/$path/$to/children'), + Uri.https(host, '/$_v/$path/$block_id/children'), body: jsonEncode(children.toJson()), headers: { 'Authorization': 'Bearer $_token', diff --git a/lib/src/notion_databases.dart b/lib/src/notion_databases.dart index ef2ac37..0d5fd35 100644 --- a/lib/src/notion_databases.dart +++ b/lib/src/notion_databases.dart @@ -24,21 +24,21 @@ class NotionDatabasesClient { /// Main Notion database client constructor. /// - /// Require the [token] to authenticate the requests, and the API [version] where to make the calls, which is the latests by default (v1). + /// Require the [auth] token to authenticate the requests, and the API [version] where to make the calls, which is the latests by default (v1). Also can receive the [dateVersion], which is by default "2021-05-13". NotionDatabasesClient({ - required String token, + required String auth, String version: latestVersion, String dateVersion: latestDateVersion, - }) : this._token = token, + }) : this._token = auth, this._v = version, this._dateVersion = dateVersion; - /// Retrieve the database with [id]. + /// Retrieve the database specified by the [database_id]. /// /// _See more at https://developers.notion.com/reference/get-database_ - Future fetch(String id) async { + Future retrieve({required String database_id}) async { http.Response res = - await http.get(Uri.https(host, '/$_v/$path/$id'), headers: { + await http.get(Uri.https(host, '/$_v/$path/$database_id'), headers: { 'Authorization': 'Bearer $_token', 'Notion-Version': _dateVersion, }); @@ -52,7 +52,7 @@ class NotionDatabasesClient { /// Also a [pageSize] can be defined to limit the result. The max value is 100. /// /// _See more at https://developers.notion.com/reference/get-databases_ - Future fetchAll({String? startCursor, int? pageSize}) async { + Future list({String? startCursor, int? pageSize}) async { Map query = {}; if (startCursor != null) { query['start_cursor'] = startCursor; @@ -70,7 +70,7 @@ class NotionDatabasesClient { return NotionResponse.fromResponse(res); } - /// Create a database. + /// Create a [database]. /// /// _See more at https://developers.notion.com/reference/create-a-database_ Future create(Database database) async { diff --git a/lib/src/notion_pages.dart b/lib/src/notion_pages.dart index 6522e7d..a4fdf43 100644 --- a/lib/src/notion_pages.dart +++ b/lib/src/notion_pages.dart @@ -24,21 +24,21 @@ class NotionPagesClient { /// Main Notion page client constructor. /// - /// Require the [token] to authenticate the requests, and the API [version] where to make the calls, which is the latests by default (v1). + /// Require the [auth] token to authenticate the requests, and the API [version] where to make the calls, which is the latests by default (v1). Also can receive the [dateVersion], which is by default "2021-05-13". NotionPagesClient({ - required String token, + required String auth, String version: latestVersion, String dateVersion: latestDateVersion, - }) : this._token = token, + }) : this._token = auth, this._v = version, this._dateVersion = dateVersion; - /// Retrieve the page with [id]. + /// Retrieve the page specified by the [page_id]. /// /// _See more at https://developers.notion.com/reference/get-page_ - Future fetch(String id) async { + Future retrieve({required String page_id}) async { http.Response res = - await http.get(Uri.https(host, '/$_v/$path/$id'), headers: { + await http.get(Uri.https(host, '/$_v/$path/$page_id'), headers: { 'Authorization': 'Bearer $_token', 'Notion-Version': _dateVersion, }); @@ -63,20 +63,20 @@ class NotionPagesClient { return NotionResponse.fromResponse(res); } - /// Update the [properties] of the page with an specified [id]. Can also mark the page as [archived]. + /// Update the [properties] of the page specified by the [page_id]. Can also mark the page as [archived]. /// /// The page should contain the property to update. /// /// Archive a page is the equivalent to delete it according to API reference. /// /// _See more at https://developers.notion.com/reference/patch-page_ - Future update( - String id, { + Future update({ + required String page_id, Properties? properties, bool? archived, }) async { Properties _properties = properties ?? Properties.empty(); - http.Response res = await http.patch(Uri.https(host, '/$_v/$path/$id'), + http.Response res = await http.patch(Uri.https(host, '/$_v/$path/$page_id'), body: jsonEncode({ 'properties': _properties.toJson(), if (archived != null) 'archived': archived, diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index 61acf0e..9767991 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -28,8 +28,9 @@ void main() { group('Notion Client', () { test('Retrieve a page', () async { - final NotionClient notion = NotionClient(token: token ?? ''); - NotionResponse res = await notion.pages.fetch(testPageId ?? ''); + final Client notion = Client(auth: token ?? ''); + NotionResponse res = + await notion.pages.retrieve(page_id: testPageId ?? ''); expect(res.status, 200); expect(res.isPage, true); @@ -41,7 +42,7 @@ void main() { group('Notion Pages Client =>', () { test('Create a page', () async { - final NotionPagesClient pages = NotionPagesClient(token: token ?? ''); + final NotionPagesClient pages = NotionPagesClient(auth: token ?? ''); final Page page = Page( parent: Parent.database(id: testDatabaseId ?? ''), @@ -54,7 +55,7 @@ void main() { }); test('Create a page with default title', () async { - final NotionPagesClient pages = NotionPagesClient(token: token ?? ''); + final NotionPagesClient pages = NotionPagesClient(auth: token ?? ''); final Page page = Page( parent: Parent.database(id: testDatabaseId ?? ''), @@ -160,7 +161,7 @@ void main() { ], ); - final NotionClient notion = NotionClient(token: token ?? ''); + final Client notion = Client(auth: token ?? ''); final Page page = Page( parent: Parent.database(id: testDatabaseId ?? ''), @@ -172,7 +173,7 @@ void main() { String newPageId = newPage.page!.id; var res = await notion.blocks.append( - to: newPageId, + block_id: newPageId, children: fullContent, ); @@ -180,9 +181,10 @@ void main() { }); test('Update a page (properties)', () async { - final NotionPagesClient pages = NotionPagesClient(token: token ?? ''); + final NotionPagesClient pages = NotionPagesClient(auth: token ?? ''); - var res = await pages.update('15db928d5d2a43ada59e3136663d41f6', + var res = await pages.update( + page_id: '15db928d5d2a43ada59e3136663d41f6', properties: Properties(map: { 'Property': RichTextProp(content: [Text('A')]) })); @@ -191,10 +193,10 @@ void main() { }); test('Update a page (archived)', () async { - final NotionPagesClient pages = NotionPagesClient(token: token ?? ''); + final NotionPagesClient pages = NotionPagesClient(auth: token ?? ''); - var res = await pages.update('15db928d5d2a43ada59e3136663d41f6', - archived: false); + var res = await pages.update( + page_id: '15db928d5d2a43ada59e3136663d41f6', archived: false); expect(res.status, 200); }); @@ -203,9 +205,10 @@ void main() { group('Notion Databases Client =>', () { test('Retrieve a database', () async { final NotionDatabasesClient databases = - NotionDatabasesClient(token: token ?? ''); + NotionDatabasesClient(auth: token ?? ''); - NotionResponse res = await databases.fetch(testDatabaseId ?? ''); + NotionResponse res = + await databases.retrieve(database_id: testDatabaseId ?? ''); expect(res.status, 200); expect(res.isOk, true); @@ -213,9 +216,9 @@ void main() { test('Retrieve all databases', () async { final NotionDatabasesClient databases = - NotionDatabasesClient(token: token ?? ''); + NotionDatabasesClient(auth: token ?? ''); - NotionResponse res = await databases.fetchAll(); + NotionResponse res = await databases.list(); expect(res.status, 200); expect(res.isOk, true); @@ -223,9 +226,9 @@ void main() { test('Retrieve all databases with wrong query', () async { final NotionDatabasesClient databases = - NotionDatabasesClient(token: token ?? ''); + NotionDatabasesClient(auth: token ?? ''); - NotionResponse res = await databases.fetchAll(startCursor: ''); + NotionResponse res = await databases.list(startCursor: ''); expect(res.status, 400); expect(res.code, 'validation_error'); @@ -235,10 +238,10 @@ void main() { test('Retrieve all databases with query', () async { final NotionDatabasesClient databases = - NotionDatabasesClient(token: token ?? ''); + NotionDatabasesClient(auth: token ?? ''); const int limit = 2; - NotionResponse res = await databases.fetchAll(pageSize: limit); + NotionResponse res = await databases.list(pageSize: limit); expect(res.isOk, true); expect(res.isList, true); @@ -247,7 +250,7 @@ void main() { test('Create a database', () async { final NotionDatabasesClient databases = - NotionDatabasesClient(token: token ?? ''); + NotionDatabasesClient(auth: token ?? ''); NotionResponse res = await databases.create(Database( parent: Parent.page(id: testPageId ?? ''), @@ -269,7 +272,7 @@ void main() { test('Create a database with default', () async { final NotionDatabasesClient databases = - NotionDatabasesClient(token: token ?? ''); + NotionDatabasesClient(auth: token ?? ''); NotionResponse res = await databases.create(Database( parent: Parent.page(id: testPageId ?? ''), @@ -282,19 +285,19 @@ void main() { group('Notion Block Client =>', () { test('Retrieve block children', () async { - final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); + final NotionBlockClient blocks = NotionBlockClient(auth: token ?? ''); - NotionResponse res = await blocks.fetch(testBlockId ?? ''); + NotionResponse res = await blocks.list(block_id: testBlockId ?? ''); expect(res.status, 200); expect(res.isOk, true); }); test('Retrieve block children with wrong query', () async { - final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); + final NotionBlockClient blocks = NotionBlockClient(auth: token ?? ''); NotionResponse res = - await blocks.fetch(testBlockId ?? '', startCursor: ''); + await blocks.list(block_id: testBlockId ?? '', startCursor: ''); expect(res.status, 400); expect(res.code, 'validation_error'); @@ -303,11 +306,11 @@ void main() { }); test('Retrieve block children with query', () async { - final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); + final NotionBlockClient blocks = NotionBlockClient(auth: token ?? ''); const int limit = 2; NotionResponse res = - await blocks.fetch(testBlockId ?? '', pageSize: limit); + await blocks.list(block_id: testBlockId ?? '', pageSize: limit); expect(res.isOk, true); expect(res.isList, true); @@ -315,10 +318,10 @@ void main() { }); test('Append heading & text', () async { - final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); + final NotionBlockClient blocks = NotionBlockClient(auth: token ?? ''); NotionResponse res = await blocks.append( - to: testBlockId as String, + block_id: testBlockId as String, children: Children.withBlocks([ Heading(text: Text('Test')), Paragraph(texts: [ @@ -342,10 +345,10 @@ void main() { }); test('Append todo block', () async { - final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); + final NotionBlockClient blocks = NotionBlockClient(auth: token ?? ''); NotionResponse res = await blocks.append( - to: testBlockId as String, + block_id: testBlockId as String, children: Children.withBlocks([ ToDo(text: Text('This is a todo item A')), ToDo( @@ -369,10 +372,10 @@ void main() { }); test('Append bulleted list item block', () async { - final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); + final NotionBlockClient blocks = NotionBlockClient(auth: token ?? ''); NotionResponse res = await blocks.append( - to: testBlockId as String, + block_id: testBlockId as String, children: Children.withBlocks( [ BulletedListItem(text: Text('This is a bulleted list item A')), @@ -396,53 +399,55 @@ void main() { }); test('Colors', () async { - final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); + final NotionBlockClient blocks = NotionBlockClient(auth: token ?? ''); NotionResponse res = await blocks.append( - to: testBlockId as String, + block_id: testBlockId as String, children: Children.withBlocks( [ Paragraph( texts: [ - Text( - 'gray', - annotations: TextAnnotations(color: ColorsTypes.Gray), - ), - Text( - 'brown', - annotations: TextAnnotations(color: ColorsTypes.Brown), - ), - Text( - 'orange', - annotations: TextAnnotations(color: ColorsTypes.Orange), - ), - Text( - 'yellow', - annotations: TextAnnotations(color: ColorsTypes.Yellow), - ), - Text( - 'green', - annotations: TextAnnotations(color: ColorsTypes.Green), - ), - Text( - 'blue', - annotations: TextAnnotations(color: ColorsTypes.Blue), - ), - Text( - 'purple', - annotations: TextAnnotations(color: ColorsTypes.Purple), - ), - Text( - 'pink', - annotations: TextAnnotations(color: ColorsTypes.Pink), - ), - Text( - 'red', - annotations: TextAnnotations(color: ColorsTypes.Red), - ), - Text( - 'default', - annotations: TextAnnotations(color: ColorsTypes.Default), - ), + ...Text.list(texts: [ + Text( + 'gray', + annotations: TextAnnotations(color: ColorsTypes.Gray), + ), + Text( + 'brown', + annotations: TextAnnotations(color: ColorsTypes.Brown), + ), + Text( + 'orange', + annotations: TextAnnotations(color: ColorsTypes.Orange), + ), + Text( + 'yellow', + annotations: TextAnnotations(color: ColorsTypes.Yellow), + ), + Text( + 'green', + annotations: TextAnnotations(color: ColorsTypes.Green), + ), + Text( + 'blue', + annotations: TextAnnotations(color: ColorsTypes.Blue), + ), + Text( + 'purple', + annotations: TextAnnotations(color: ColorsTypes.Purple), + ), + Text( + 'pink', + annotations: TextAnnotations(color: ColorsTypes.Pink), + ), + Text( + 'red', + annotations: TextAnnotations(color: ColorsTypes.Red), + ), + Text( + 'default', + annotations: TextAnnotations(color: ColorsTypes.Default), + ), + ]), ], ), ], @@ -454,10 +459,10 @@ void main() { }); test('Append numbered list item block', () async { - final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); + final NotionBlockClient blocks = NotionBlockClient(auth: token ?? ''); NotionResponse res = await blocks.append( - to: testBlockId as String, + block_id: testBlockId as String, children: Children.withBlocks( [ NumberedListItem(text: Text('This is a numbered list item A')), @@ -486,10 +491,10 @@ void main() { }); test('Append toggle block', () async { - final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); + final NotionBlockClient blocks = NotionBlockClient(auth: token ?? ''); NotionResponse res = await blocks.append( - to: testBlockId as String, + block_id: testBlockId as String, children: Children.withBlocks( [ Toggle( diff --git a/test/response_test.dart b/test/response_test.dart index 6a06e03..91ca6e2 100644 --- a/test/response_test.dart +++ b/test/response_test.dart @@ -42,8 +42,7 @@ void main() { }); test('Create an instance from auth error response', () async { - final NotionResponse res = - await NotionClient(token: '').databases.fetchAll(); + final NotionResponse res = await Client(auth: '').databases.list(); expect(res.hasError, true); expect(res.isError, true); @@ -52,11 +51,11 @@ void main() { }); test('Invalid field (children) for block', () async { - final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); + final NotionBlockClient blocks = NotionBlockClient(auth: token ?? ''); // Heading block do not support children var res = await blocks.append( - to: testBlockHeadingId ?? '', + block_id: testBlockHeadingId ?? '', children: Children.withBlocks( [ Paragraph( @@ -75,7 +74,7 @@ void main() { }); test('Invalid property', () async { - final NotionPagesClient pages = NotionPagesClient(token: token ?? ''); + final NotionPagesClient pages = NotionPagesClient(auth: token ?? ''); final Page page = Page( parent: Parent.database(id: testDatabaseId ?? ''), @@ -92,10 +91,11 @@ void main() { }); test('Wrong uuid for block children', () async { - final NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); + final NotionBlockClient blocks = NotionBlockClient(auth: token ?? ''); - NotionResponse res = await blocks.fetch( - testBlockId != null ? testBlockId!.replaceFirst('d', 'b') : ''); + NotionResponse res = await blocks.list( + block_id: + testBlockId != null ? testBlockId!.replaceFirst('d', 'b') : ''); expect(res.status, 404); expect(res.isOk, false); @@ -108,9 +108,9 @@ void main() { group('Response lists tests =>', () { test('Fetch a list', () async { NotionDatabasesClient databases = - NotionDatabasesClient(token: token ?? ''); + NotionDatabasesClient(auth: token ?? ''); - NotionResponse res = await databases.fetchAll(); + NotionResponse res = await databases.list(); expect(res.status, 200); expect(res.hasError, false); @@ -122,18 +122,18 @@ void main() { test('Fetch databases list', () async { NotionDatabasesClient databases = - NotionDatabasesClient(token: token ?? ''); + NotionDatabasesClient(auth: token ?? ''); - NotionResponse res = await databases.fetchAll(); + NotionResponse res = await databases.list(); expect(res.content.isEmpty, true); expect(res.content.list, isEmpty); }); test('Fetch blocks children', () async { - NotionBlockClient blocks = NotionBlockClient(token: token ?? ''); + NotionBlockClient blocks = NotionBlockClient(auth: token ?? ''); - NotionResponse res = await blocks.fetch(testBlockId ?? ''); + NotionResponse res = await blocks.list(block_id: testBlockId ?? ''); expect(res.content.isEmpty, false); expect(res.content.isBlocksList, true); @@ -145,9 +145,10 @@ void main() { group('Database response test =>', () { test('Instance from response', () async { - NotionDatabasesClient db = NotionDatabasesClient(token: token ?? ''); + NotionDatabasesClient db = NotionDatabasesClient(auth: token ?? ''); - NotionResponse response = await db.fetch(testDatabaseId ?? ''); + NotionResponse response = + await db.retrieve(database_id: testDatabaseId ?? ''); expect(response.isDatabase, true); expect(response.content.title, allOf([isList, isNotEmpty, hasLength(1)])); From b55b5a5185c7e12c4845b41b2a4e823f3fec12d3 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 6 Aug 2021 13:14:16 -0500 Subject: [PATCH 14/42] Update version changes for next release (2.0.0-beta2) --- CHANGELOG.md | 7 ++++++- README.md | 20 +++++++++++++++----- ROADMAP.md | 32 ++++++++++++++++++++++---------- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0372da1..49a0d0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,4 +138,9 @@ * `color`: Text with different color of default. * 🐣 Add `list(List texts, String separator, String lastSeparator)`: * **A static method** - * Generate a textual list of texts separated by comma (by default). \ No newline at end of file + * Generate a textual list of texts separated by comma (by default). + +## v2.0.0-beta2 +> Release date: 06/Aug/2021 +* 🍗 Add more suggestions on issue [#11](https://github.com/jonathangomz/notion_api/issues/11): + * Copy some terminologies from [`notion-sdk-js`](https://github.com/makenotion/notion-sdk-js) \ No newline at end of file diff --git a/README.md b/README.md index 759dbc8..a414a35 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,11 @@ See the [ROADMAP](ROADMAP.md) file to see what is coming next. - [Rules](#rules) - [Tests](#tests) - [Example:](#example) -- [Next release](#next-release) - - [v2.0.0](#v200) +- [Releases](#releases) + - [Next](#next) + - [v2.0.0](#v200) + - [Last](#last) + - [v2.0.0-beta2](#v200-beta2) # API implemented | Endpoint | Avaliable | Notes @@ -146,9 +149,16 @@ TEST_BLOCK_ID=c8hac4bb32af48889228bf483d938e34 TEST_BLOCK_HEADING_ID=c8hac4bb32af48889228bf483d938e34 ``` -# Next release -## v2.0.0 -> Release date: 04/Aug/2021 +# Releases +## Next +### v2.0.0 +> Release date: 13/Aug/2021 * 🔧 Fix any error on beta +## Last +### v2.0.0-beta2 +> Release date: 06/Aug/2021 +* 🍗 Add more suggestions on issue [#11](https://github.com/jonathangomz/notion_api/issues/11): + * Copy some terminologies from [`notion-sdk-js`](https://github.com/makenotion/notion-sdk-js) + [1]:https://pub.dev/documentation/notion_api/1.0.0-beta1/responses_notion_response/NotionResponse-class.html \ No newline at end of file diff --git a/ROADMAP.md b/ROADMAP.md index 9f05210..4cb42c3 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -3,21 +3,33 @@ ## More coming soon... If you have suggestions feel free to create an Issue or to create a PR with the feature. -## v2.0.1 -> Release date: 09/Aug/2021 -* 🔧 Maybe fix errors creating page with children. I don't know if is an error with Notion API. +## 2.1.0 +> Release date: 27/Aug/2021 +* 🐣 Add `Retrieve a block` endpoint: + * https://developers.notion.com/reference/retrieve-a-block +* 🐣 Add `Update a block` endpoint: + * https://developers.notion.com/reference/update-a-block * 🐣 Add `Query a database` endpoint: * https://developers.notion.com/reference/post-database-query + +## v2.0.1 +> Release date: 20/Aug/2021 +* 🔧 Maybe fix errors creating page with children. I don't know if is an error with Notion API. * 🐣 Add more properties for pages and databases: * Page properties: https://developers.notion.com/reference/page#page-property-value * Database properties: https://developers.notion.com/reference/database#database-property ## v2.0.0 -> Release date: 04/Aug/2021 +> Release date: 13/Aug/2021 * 🔧 Fix any error on beta +## v2.0.0-beta2 ✅ +> Release date: 06/Aug/2021 +* 🍗 Add more suggestions on issue [#11](https://github.com/jonathangomz/notion_api/issues/11): + * Copy some terminologies from [`notion-sdk-js`](https://github.com/makenotion/notion-sdk-js) + ## v2.0.0-beta1 ✅ -> Release date: 30/Aug/2021 +> Release date: 30/Jun/2021 * 🐣 Add constructor for empty `Database`. * 🐣 Add parameter `blocks` for `Children` constructor. * 🍗 Remove deprecated code: @@ -26,7 +38,7 @@ If you have suggestions feel free to create an Issue or to create a PR with the * `heading` * `paragraph` * `toDo` -* 🐣 Add suggestions on issue [#11](https://github.com/jonathangomz/notion_api/issues/11): +* 🍗 Add suggestions on issue [#11](https://github.com/jonathangomz/notion_api/issues/11): * Update exports to improve usage * Add private folder (`src/`) * 🐣 Add constructors with only single text content with default style for: @@ -36,10 +48,10 @@ If you have suggestions feel free to create an Issue or to create a PR with the * `BulletedListItem`: `BulletedListItem.text('some text here...')` * `NumberedListItem`: `NumberedListItem.text('some text here...')` * `Toggle`: `Toggle.text('some text here...', children: [])` -* 🐣 Add more constructors for `Heading` class: - * `one`: Heading with type 1 by default. - * `two`: Heading with type 2 by default. - * `three`: Heading with type 3 by default. +* (**CANCELED**) ~~🐣 Add more constructors for `Heading` class:~~ + * ~~`one`: Heading with type 1 by default.~~ + * ~~`two`: Heading with type 2 by default.~~ + * ~~`three`: Heading with type 3 by default.~~ * 🐣 Add more constructors for `Text` class: * `code`: Text with code style by default. * `italic`: Text with italic style by default. From a3113ff92296182d7d46706738e77af2c7d335ba Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 6 Aug 2021 13:14:28 -0500 Subject: [PATCH 15/42] Update examples --- example/example.md | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/example/example.md b/example/example.md index 1a774ce..e747dfe 100644 --- a/example/example.md +++ b/example/example.md @@ -25,7 +25,7 @@ ## Full instance You only have to create a new instance of the `NotionClient` class and all the API requests will be available as class properties methods. ```dart -NotionClient notion = NotionClient(token: 'YOUR SECRET TOKEN FROM INTEGRATIONS PAGE'); +NotionClient notion = NotionClient(auth: 'YOUR SECRET TOKEN FROM INTEGRATIONS PAGE'); ``` ## Individual classes @@ -34,12 +34,12 @@ You can also use individual request group class like `NotionPagesClient` or `Not **Example** ```dart // With main class -NotionClient notion = NotionClient(token: 'YOUR_TOKEN'); -notion.databases.fetchAll(); +NotionClient notion = NotionClient(auth: 'YOUR_TOKEN'); +notion.databases.list(); // With individual class -NotionDatabasesClient databases = NotionDatabasesClient(token: 'YOUR_TOKEN'); -databases.fetchAll(); +NotionDatabasesClient databases = NotionDatabasesClient(auth: 'YOUR_TOKEN'); +databases.list(); ``` # Pages @@ -74,7 +74,8 @@ If you want to update the content of the page itself the use the block children **Note:** If the parent is a database, the new property values in the properties parameter must conform to the parent database's property schema. ```dart -notion.pages.update('YOUR_PAGE_ID', +notion.pages.update( + page_id: 'YOUR_PAGE_ID', properties: Properties(map: { 'Description': RichTextProp(content: [ Text('New value for Description property'), @@ -89,7 +90,8 @@ Archive or delete a page is a subaction of update it according to the API refere You can archive or un-archive the page just by toggling the boolean value of the `archived` parameter. ```dart -notion.pages.update('YOUR_PAGE_ID', +notion.pages.update( + page_id: 'YOUR_PAGE_ID', archived: true, ); ``` @@ -97,7 +99,7 @@ _See more at https://developers.notion.com/reference/patch-page#archive-delete-a ## Retrieve a page ```dart -notion.pages.fetch('YOUR_PAGE_ID'); +notion.pages.retrieve(page_id: 'YOUR_PAGE_ID'); ``` _See more at https://developers.notion.com/reference/get-page_ @@ -108,7 +110,7 @@ You have to define the parent of the page. It can be: - `workspace` ```dart // With page parent -Page page = Database( +Database database = Database( parent: Parent.page(id: 'YOUR_PAGE_ID'), title: [ Text('Database from examples'), @@ -122,13 +124,13 @@ Page page = Database( }), ); -notion.databases.create(page); +notion.databases.create(database); ``` _See more at https://developers.notion.com/reference/create-a-database_ ## Retrieve a database ```dart -notion.databases.fetch('YOUR_DATABASE_ID'); +notion.databases.retrieve(database_id: 'YOUR_DATABASE_ID'); ``` _See more at https://developers.notion.com/reference/get-database_ @@ -139,14 +141,14 @@ _Parameters:_ - _startCursor: 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._ - _pageSize: The number of items from the full list desired in the response. Maximum: 100, otherwise will be ignored._ ```dart -notion.databases.fetchAll(); +notion.databases.list(); ``` _See more at https://developers.notion.com/reference/get-databases_ # Block children ## Retrieve block children ```dart -notion.blocks.fetch('YOUR_BLOCK_ID'); +notion.blocks.list(block_id: 'YOUR_BLOCK_ID'); ``` _See more at https://developers.notion.com/reference/get-block-children_ @@ -233,7 +235,7 @@ Children childrenD = Children(blocks: [ // Send the instance to Notion notion.blocks.append( - to: 'YOUR_BLOCK_ID', + block_id: 'YOUR_BLOCK_ID', children: childrenA, // or `childrenB`, `childrenC` or `childrenD`, any of these will produce the same result. ); ``` @@ -266,7 +268,7 @@ Children children = // Send the instance to Notion notion.blocks.append( - to: 'YOUR_BLOCK_ID', + block_id: 'YOUR_BLOCK_ID', children: children, ); ``` @@ -299,7 +301,7 @@ Children children = // Send the instance to Notion notion.blocks.append( - to: 'YOUR_BLOCK_ID', + block_id: 'YOUR_BLOCK_ID', children: children, ); ``` @@ -330,7 +332,7 @@ Children children = // Send the instance to Notion notion.blocks.append( - to: 'YOUR_BLOCK_ID', + block_id: 'YOUR_BLOCK_ID', children: children, ); ``` @@ -361,7 +363,7 @@ Children children = // Send the instance to Notion notion.blocks.append( - to: 'YOUR_BLOCK_ID', + block_id: 'YOUR_BLOCK_ID', children: children, ); ``` @@ -379,7 +381,7 @@ Go to see the result https://jonathangomz.notion.site/notion_api-example-81cb020 ```dart // Initialize the main Notion client -final NotionClient notion = NotionClient(token: 'YOUR_SECRET'); +final NotionClient notion = NotionClient(auth: 'YOUR_SECRET'); // Create the instance of the page final Page page = Page( @@ -490,7 +492,7 @@ Children fullContent = Children( // Append the content to the page var res = await notion.blocks.append( - to: newPageId, + block_id: newPageId, children: fullContent, ); ``` \ No newline at end of file From c05fff276375071151fac64cd4c0cb5ad588af83 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 6 Aug 2021 13:17:37 -0500 Subject: [PATCH 16/42] Update beta version --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 5e199c4..da79f3d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: notion_api description: A wrapper for the public beta Notion API to manage it like a Notion SDK package for dart. -version: 2.0.0-beta1 +version: 2.0.0-beta2 homepage: https://github.com/jonathangomz/notion_api environment: From b1cfb6bff4c01cafb460e72c7133a2ffd9d87379 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 6 Aug 2021 13:22:57 -0500 Subject: [PATCH 17/42] Fix examples with wrong class name for client --- README.md | 16 ++++++++-------- example/example.md | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index a414a35..ece170b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ See the [ROADMAP](ROADMAP.md) file to see what is coming next. - [API implemented](#api-implemented) - [Usage](#usage) - - [`NotionClient` class](#notionclient-class) + - [`Client` class](#client-class) - [Individual classes](#individual-classes) - [A few examples](#a-few-examples) - [Append blocks children](#append-blocks-children) @@ -44,10 +44,10 @@ See the [ROADMAP](ROADMAP.md) file to see what is coming next. # Usage **Important**: The methods return a `NotionResponse`. You can find how to use it in its [documentation][1]. -## `NotionClient` class -You only have to create a new instance of the `NotionClient` class and all the API requests will be available as class methods. +## `Client` class +You only have to create a new instance of the `Client` class and all the API requests will be available as class methods. ```dart -NotionClient notion = NotionClient(token: 'YOUR SECRET TOKEN FROM INTEGRATIONS PAGE'); +Client notion = Client(token: 'YOUR SECRET TOKEN FROM INTEGRATIONS PAGE'); ``` ## Individual classes @@ -56,12 +56,12 @@ You can also use individual request group class like `NotionPagesClient` or `Not **Example** ```dart // With main class -NotionClient notion = NotionClient(token: 'YOUR_TOKEN'); -notion.databases.fetchAll(); +Client notion = Client(token: 'YOUR_TOKEN'); +notion.databases.list(); // With individual class NotionDatabasesClient databases = NotionDatabasesClient(token: 'YOUR_TOKEN'); -databases.fetchAll(); +databases.list(); ``` ## A few examples @@ -88,7 +88,7 @@ Children children = Children(blocks: [ // Send the instance to Notion notion.blocks.append( - to: 'YOUR_BLOCK_ID', + block_id: 'YOUR_BLOCK_ID', children: children, ); ``` diff --git a/example/example.md b/example/example.md index e747dfe..b569fad 100644 --- a/example/example.md +++ b/example/example.md @@ -23,9 +23,9 @@ # Initialization ## Full instance -You only have to create a new instance of the `NotionClient` class and all the API requests will be available as class properties methods. +You only have to create a new instance of the `Client` class and all the API requests will be available as class properties methods. ```dart -NotionClient notion = NotionClient(auth: 'YOUR SECRET TOKEN FROM INTEGRATIONS PAGE'); +Client notion = Client(auth: 'YOUR SECRET TOKEN FROM INTEGRATIONS PAGE'); ``` ## Individual classes @@ -34,7 +34,7 @@ You can also use individual request group class like `NotionPagesClient` or `Not **Example** ```dart // With main class -NotionClient notion = NotionClient(auth: 'YOUR_TOKEN'); +Client notion = Client(auth: 'YOUR_TOKEN'); notion.databases.list(); // With individual class @@ -381,7 +381,7 @@ Go to see the result https://jonathangomz.notion.site/notion_api-example-81cb020 ```dart // Initialize the main Notion client -final NotionClient notion = NotionClient(auth: 'YOUR_SECRET'); +final Client notion = Client(auth: 'YOUR_SECRET'); // Create the instance of the page final Page page = Page( From 0e495d271e5ce9ec31bda8de16eaf4535a573bce Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 23 Feb 2022 20:39:34 -0600 Subject: [PATCH 18/42] Updates ROADMAP --- ROADMAP.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 4cb42c3..2b9703a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -3,8 +3,11 @@ ## More coming soon... If you have suggestions feel free to create an Issue or to create a PR with the feature. -## 2.1.0 -> Release date: 27/Aug/2021 +## v2.1.0 +||| +|:---------------|:------------| +| Release date | ? | +| Notion-Version | 2021-08-16 | * 🐣 Add `Retrieve a block` endpoint: * https://developers.notion.com/reference/retrieve-a-block * 🐣 Add `Update a block` endpoint: @@ -13,15 +16,21 @@ If you have suggestions feel free to create an Issue or to create a PR with the * https://developers.notion.com/reference/post-database-query ## v2.0.1 -> Release date: 20/Aug/2021 +||| +|:---------------|:------------| +| Release date | ? | +| Notion-Version | 2021-08-16 | * 🔧 Maybe fix errors creating page with children. I don't know if is an error with Notion API. * 🐣 Add more properties for pages and databases: * Page properties: https://developers.notion.com/reference/page#page-property-value - * Database properties: https://developers.notion.com/reference/database#database-property + * Database properties: https://develop ers.notion.com/reference/database#database-property ## v2.0.0 -> Release date: 13/Aug/2021 -* 🔧 Fix any error on beta +||| +|:---------------|:------------| +| Release date | 15/Mar/2022 | +| Notion-Version | 2021-08-16 | +* **Full refactorization to all the project** ## v2.0.0-beta2 ✅ > Release date: 06/Aug/2021 From 50fa37a5fc6c23dce3fec71fd11a1fc9d7b0b6a4 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 23 Feb 2022 20:39:47 -0600 Subject: [PATCH 19/42] Updates latest date version --- lib/src/statics.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/statics.dart b/lib/src/statics.dart index 038a287..36ac349 100644 --- a/lib/src/statics.dart +++ b/lib/src/statics.dart @@ -9,4 +9,4 @@ const String latestVersion = 'v1'; /// The latest date version of Notion API /// /// See [Notion versioning](https://developers.notion.com/reference/versioning) for more information. -const String latestDateVersion = '2021-05-13'; +const String latestDateVersion = '2021-08-16'; From d3f7434c9e44ddf1a2a05f334f3e170bc0ab5ffa Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 23 Feb 2022 22:04:34 -0600 Subject: [PATCH 20/42] Create RiohText class as a Text copy --- lib/src/notion/rich_text.dart | 234 ++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) diff --git a/lib/src/notion/rich_text.dart b/lib/src/notion/rich_text.dart index 6a972f6..4bbfea4 100644 --- a/lib/src/notion/rich_text.dart +++ b/lib/src/notion/rich_text.dart @@ -235,3 +235,237 @@ class TextAnnotations { return json; } } + +class RichText { + String _type = 'text'; + + /// The text intself. + String text; + + /// The annotations of the text. + TextAnnotations? annotations = TextAnnotations(); + + /// The url of the text when the text is a link. + Uri? url; + + /// Main rich text constructor. + /// + /// Required the [text] itself. Also can receive the [annotations] and/or the [url] of the text. + RichText(this.text, {this.annotations, this.url}); + + /// Text constructor with **bold** content by default. + /// + /// Only can receive the [text] itself and the [color]. + RichText.bold( + this.text, { + ColorsTypes color: ColorsTypes.Default, + }) : this.annotations = TextAnnotations(bold: true, color: color); + + /// Text constructor with _italic_ content by default. + /// + /// Only can receive the [text] itself and the [color]. + RichText.italic( + this.text, { + ColorsTypes color: ColorsTypes.Default, + }) : this.annotations = TextAnnotations(italic: true, color: color); + + /// Text constructor with `code` content by default. + /// + /// Only can receive the [text] itself and the [color]. + RichText.code( + this.text, { + ColorsTypes color: ColorsTypes.Default, + }) : this.annotations = TextAnnotations(code: true, color: color); + + /// Text constructor with underline content by default. + /// + /// Only can receive the [text] itself and the [color]. + RichText.underline( + this.text, { + ColorsTypes color: ColorsTypes.Default, + }) : this.annotations = TextAnnotations(underline: true, color: color); + + /// Text constructor to change the default color of a text. + /// + /// Only can receive the [text] itself and the [color]. + RichText.color( + this.text, { + ColorsTypes color: ColorsTypes.Default, + }) : this.annotations = TextAnnotations(color: color); + + /// Text mapper for lists. + /// + /// Can receive the list of [texts] the [separator] (by default ", ") and the [lastSeparator] (by default " and "). + /// + /// This static method generates a list of "Text" instances in the style of a textual list. + /// + /// Example: + /// ```dart + /// Paragraph( + /// texts: [ + /// Text('Some programming languages are '), + /// ...Text.list(texts: [ + /// Text.color('Java', color: ColorsTypes.Green), + /// Text.color('Javascript', color: ColorsTypes.Blue), + /// Text.color('PHP', color: ColorsTypes.Purple), + /// Text.color('Dart', color: ColorsTypes.Orange), + /// ]), + /// Text('.'), + /// ], + /// ); + /// ``` + /// Should print: _"Java, Javascript, PHP and Dart"_ but each element with his own style. + /// + /// Otherwise the code should be: + /// ```dart + /// Paragraph( + /// texts: [ + /// Text('Some programming languages are '), + /// Text.color('Java', color: ColorsTypes.Green), + /// Text(', '), + /// Text.color('Javascript', color: ColorsTypes.Blue), + /// Text(', '), + /// Text.color('PHP', color: ColorsTypes.Purple), + /// Text(' and '), + /// Text.color('Dart', color: ColorsTypes.Orange), + /// Text('.'), + /// ], + /// ); + /// ``` + static List list({ + required List texts, + String separator: ', ', + String lastSeparator: ' and ', + }) { + List list = []; + texts.asMap().forEach((index, element) { + if (index == texts.length - 1) { + // last element + list.add(element); + } else { + if (index == texts.length - 2) { + // penultimate element + list.addAll([element, RichText(lastSeparator)]); + } else { + // any other element + list.addAll([element, RichText(separator)]); + } + } + }); + return list; + } + + /// Create a new Text instance from json. + /// + /// Receive a [json] from where the information is extracted. + RichText.fromJson(Map json) + : this.text = json['text']['content'] ?? '', + this.annotations = TextAnnotations.fromJson(json['annotations'] ?? {}), + this.url = json['href'] != null ? Uri.parse(json['href']) : null; + + /// Convert this to a json representation valid for the Notion API. + /// ``` + Map toJson() { + Map json = { + 'type': _type, + 'text': { + 'content': '$text', + }, + }; + + // Null values on fields can break the API call. + if (annotations != null) { + json['annotations'] = annotations?.toJson(); + } + + if (url != null) { + json['link'] = { + 'url': url.toString(), + }; + } + + return json; + } + + /// Map a list of texts from a [json] list with dynamics. + static List fromListJson(List json) { + List texts = []; + json.forEach((e) => texts.add(RichText.fromJson(e))); + return texts; + } +} + +/// The text style. +class RichTextAnnotations { + /// A marker for bold text. + bool bold; + + /// A marker for italic text. + bool italic; + + /// A marker for strikethrough text. + bool strikethrough; + + /// A marker for underline text. + bool underline; + + /// A marker for code text. + bool code; + + /// The color of the text. Default by... by default hehe. + ColorsTypes color; + + /// The string value of the color type. + String get strColor => colorTypeToString(color); + + /// Main rich text annotations constructor. + /// + /// Can receive if the text will be [bold], [italic], [strikethrough], [underline] and/or [code]. Also the [color] of the text. + /// + /// Valid colors are defined by the Colors enum. By default the color type is... Default dah. + RichTextAnnotations({ + this.bold: false, + this.italic: false, + this.strikethrough: false, + this.underline: false, + this.code: false, + this.color: ColorsTypes.Default, + }); + + /// Create a new text annotation instance from json. + /// + /// Receive a [json] from where the information is extracted. + RichTextAnnotations.fromJson(Map json) + : this.bold = json['bold'] ?? false, + this.italic = json['italic'] ?? false, + this.strikethrough = json['strikethrough'] ?? false, + this.underline = json['underline'] ?? false, + this.code = json['code'] ?? false, + this.color = stringToColorType(json['color'] ?? ''); + + /// Convert this to a json representation valid for the Notion API. + Map toJson() { + Map json = { + 'color': strColor, + }; + + // Null & false values on fields can break the API call. + if (bold) { + json['bold'] = bold; + } + if (italic) { + json['italic'] = italic; + } + if (strikethrough) { + json['strikethrough'] = strikethrough; + } + if (underline) { + json['underline'] = underline; + } + if (code) { + json['code'] = code; + } + + return json; + } +} From d9d8338a17fb5a6aaae1207e36ce97d377f0cc1c Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 23 Feb 2022 22:07:46 -0600 Subject: [PATCH 21/42] Add properties `forDatabase` constructor For mandatory database properties --- lib/src/notion/lists/properties.dart | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/src/notion/lists/properties.dart b/lib/src/notion/lists/properties.dart index 654a2b4..1ae781a 100644 --- a/lib/src/notion/lists/properties.dart +++ b/lib/src/notion/lists/properties.dart @@ -17,6 +17,17 @@ class Properties { this._map.addAll(map); } + /// Main properties constructor. + /// + /// Can receive a properties [map]. + Properties.forDatabase({ + required String title, + Map map: const {}, + }) { + _map[title] = TitleProp(); + _map.addAll(map); + } + /// Constructor for an empty instance. Properties.empty(); From 1b8d388c00344f97e742afe4c4aecea47b78e26f Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 23 Feb 2022 22:08:46 -0600 Subject: [PATCH 22/42] Renames BaseFields to Object --- .../objects/{base_fields.dart => object.dart} | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) rename lib/src/notion/objects/{base_fields.dart => object.dart} (83%) diff --git a/lib/src/notion/objects/base_fields.dart b/lib/src/notion/objects/object.dart similarity index 83% rename from lib/src/notion/objects/base_fields.dart rename to lib/src/notion/objects/object.dart index fff2b89..16e559a 100644 --- a/lib/src/notion/objects/base_fields.dart +++ b/lib/src/notion/objects/object.dart @@ -2,7 +2,7 @@ import '../../utils/utils.dart'; import '../general/notion_types.dart'; /// A base representation of the base properties of almost any Notion object. -class BaseFields { +class Object { /// The object type. ObjectTypes object; @@ -10,10 +10,10 @@ class BaseFields { String id; /// The creation time of the object. - String createdTime; + DateTime? createdTime; /// The last edited time of the object. - String lastEditedTime; + DateTime? lastEditedTime; /// The string value of the object type. String get strObject => objectTypeToString(object); @@ -23,15 +23,15 @@ class BaseFields { /// Can receive the [object], the [id], the [createdTime] and the [lastEditedTime] of the object. /// /// **Note:** This class is mainly (if no only) used by extending it. - BaseFields({ + Object({ this.object: ObjectTypes.Object, this.id: '', - this.createdTime: '', - this.lastEditedTime: '', + DateTime? this.createdTime, + DateTime? this.lastEditedTime, }); /// Map the properties from a [json] map. - BaseFields.fromJson(Map json) + Object.fromJson(Map json) : this.object = stringToObjectType(json['object']), this.id = json['id'] ?? '', this.createdTime = json['created_time'] ?? '', @@ -41,8 +41,8 @@ class BaseFields { /// /// This function is used to set the base properties from the constructor of the class in which it is inherited. void setBaseProperties({ - required String createdTime, - required String lastEditedTime, + DateTime? createdTime, + DateTime? lastEditedTime, }) { this.createdTime = createdTime; this.lastEditedTime = lastEditedTime; From 552540dc1b279708326a442fc8ef4fe2e379b461 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 23 Feb 2022 22:11:31 -0600 Subject: [PATCH 23/42] Rename BaseFields to Object --- lib/src/notion/objects/block.dart | 8 ++++---- lib/src/notion/objects/pages.dart | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/src/notion/objects/block.dart b/lib/src/notion/objects/block.dart index f418a46..5b08d33 100644 --- a/lib/src/notion/objects/block.dart +++ b/lib/src/notion/objects/block.dart @@ -1,9 +1,9 @@ import '../../utils/utils.dart'; import '../general/notion_types.dart'; -import 'base_fields.dart'; +import 'object.dart'; /// A base representation of any Notion block object. -class Block extends BaseFields { +class Block extends Object { /// The type of object. Always Block for this. @override final ObjectTypes object = ObjectTypes.Block; @@ -61,8 +61,8 @@ class Block extends BaseFields { this.hasChildren: false, this.jsonContent: const {}, this.type: BlockTypes.None, - String createdTime: '', - String lastEditedTime: '', + DateTime? createdTime, + DateTime? lastEditedTime, }) { this.setBaseProperties( createdTime: createdTime, diff --git a/lib/src/notion/objects/pages.dart b/lib/src/notion/objects/pages.dart index 8b2c985..82475ad 100644 --- a/lib/src/notion/objects/pages.dart +++ b/lib/src/notion/objects/pages.dart @@ -1,11 +1,11 @@ import '../general/exports.dart'; import '../lists/exports.dart'; import '../rich_text.dart'; -import 'base_fields.dart'; +import 'object.dart'; import 'parent.dart'; /// A representation of the Page Notion object. -class Page extends BaseFields { +class Page extends Object { /// The type of this object. Always Page for this. @override final ObjectTypes object = ObjectTypes.Page; From 4fe8f452db27241f2b9b5fd95e9a9d45e6009b82 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 23 Feb 2022 22:13:15 -0600 Subject: [PATCH 24/42] Adds throw exception method to utils Throws `FormatException` if any property is null inside the json given --- lib/src/utils/utils.dart | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/src/utils/utils.dart b/lib/src/utils/utils.dart index 06259f0..1891684 100644 --- a/lib/src/utils/utils.dart +++ b/lib/src/utils/utils.dart @@ -327,3 +327,12 @@ PropertiesTypes extractPropertyType(Map json) { /// Find if a json [field] is a List bool fieldIsList(dynamic field) => field is List; + +/// Find is a list of properties are not null +void throwIfAnyNull(dynamic json, List properties) { + bool anyNull = properties.any((property) => json[property] == null); + + if (anyNull) + throw FormatException( + 'Any required field is null. Required fields are ${properties}'); +} From 5c0298ca94e73abc1a0ec1fbd81ace65d5cc4708 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 23 Feb 2022 22:13:34 -0600 Subject: [PATCH 25/42] Renames BaseFields to Object --- test/general_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/general_test.dart b/test/general_test.dart index 2e359a1..1d7704a 100644 --- a/test/general_test.dart +++ b/test/general_test.dart @@ -1,11 +1,11 @@ import 'package:notion_api/notion_api.dart'; -import 'package:notion_api/src/notion/objects/base_fields.dart'; +import 'package:notion_api/src/notion/objects/object.dart'; import 'package:test/test.dart'; void main() { group('Base fields tests =>', () { test('Create an instance from json', () { - BaseFields base = BaseFields.fromJson({ + Object base = Object.fromJson({ "object": "database", "id": "386da3c6-46bb-4581-8807-1fdb2fbbf447", "created_time": "2021-05-19T20:21:11.420Z", From 3db05e1201b5274568bfa7a691b02a094010e591 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 23 Feb 2022 22:13:52 -0600 Subject: [PATCH 26/42] Improves database class --- lib/src/notion/objects/database.dart | 112 +++++++++++++++++---------- lib/src/notion_databases.dart | 2 +- test/notion_api_test.dart | 15 ++-- test/objects/database_test.dart | 23 +++--- 4 files changed, 93 insertions(+), 59 deletions(-) diff --git a/lib/src/notion/objects/database.dart b/lib/src/notion/objects/database.dart index d085926..2e66f3f 100644 --- a/lib/src/notion/objects/database.dart +++ b/lib/src/notion/objects/database.dart @@ -2,73 +2,93 @@ import '../../utils/utils.dart'; import '../general/exports.dart'; import '../lists/properties.dart'; import '../rich_text.dart'; -import 'base_fields.dart'; +import 'object.dart'; import 'parent.dart'; /// A representation of the Databse Notion object. -class Database extends BaseFields { +class Database extends Object { /// The type of this object. Always Database for this. @override final ObjectTypes object = ObjectTypes.Database; - /// The information of the page parent. - Parent parent = Parent.none(); - /// The title of this database. - List title = []; + List title = []; /// The properties of this database. Properties properties = Properties(); + /// The information of the page parent. + Parent parent; + + /// The URL of the Notion datanase. + String url; + + /// Map a new database instance for a new request. + Database({ + required this.parent, + required this.properties, + this.title: const [], + }) : url = ''; + /// Main database constructor. - /// + /// TODO: Update docs. /// Can receive the [parent] (required), the [title] (empty), the [pagesColumnName] ("Name") and the [properties] (null). - /// - /// The [pagesColumnName] is the value of the page column header. - Database({ + Database.constructor({ + // Object properties + required String id, + DateTime? createdTime, + DateTime? lastEditedTime, + // Datebase properties + required this.title, + // TODO: Add icon & cover + required this.properties, required this.parent, - this.title: const [], - String pagesColumnName: 'Name', - Properties? properties, - }) : this.properties = Properties(map: { - pagesColumnName: TitleProp(), - if (properties != null) ...properties.entries, - }) { - this.id = id; - this.setBaseProperties( - createdTime: createdTime, - lastEditedTime: lastEditedTime, - ); - } + required this.url, + }) : super( + id: id, + createdTime: createdTime, + lastEditedTime: lastEditedTime, + ); /// Constructor for empty database. - Database.empty(); + Database.empty() + : url = "", + parent = Parent.none(); /// Database constructor with defaults parameters. /// /// Can receive the [parent] (none parent), [title] (empty), the [createdTime] (""), the [lastEditedTime] ("") and the database [id] ("") but every parameter is optional. Database.withDefaults({ this.parent: const Parent.none(), - this.title: const [], - String createdTime: '', - String lastEditedTime: '', + this.title: const [], + this.url: '', String id: '', - }) { - this.id = id; - this.setBaseProperties( - createdTime: createdTime, - lastEditedTime: lastEditedTime, - ); - } + DateTime? createdTime, + DateTime? lastEditedTime, + }) : super( + id: id, + createdTime: createdTime, + lastEditedTime: lastEditedTime, + ); /// Map a new database instance from a [json] map. - factory Database.fromJson(Map json) => Database.withDefaults( - id: json['id'] ?? '', - parent: Parent.fromJson(json['parent'] ?? {}), - title: Text.fromListJson(json['title'] ?? []), - createdTime: json['created_time'] ?? '', - lastEditedTime: json['last_edited_time'] ?? '', - ).addPropertiesFromJson(json['properties'] ?? {}); + factory Database.fromJson(Map json) { + throwIfAnyNull(json, ['id', 'properties', 'parent', 'url']); + + return Database.constructor( + id: json['id'], + createdTime: json['created_time'] != null + ? DateTime.parse(json['created_time']) + : null, + lastEditedTime: json['last_edited_time'] != null + ? DateTime.parse(json['last_edited_time']) + : null, + title: RichText.fromListJson(json['title'] ?? []), + properties: Properties.fromJson(json['properties']), + parent: Parent.fromJson(json['parent']), + url: json['url'], + ); + } /// Add a new database [property] with an specific [name]. /// @@ -94,8 +114,18 @@ class Database extends BaseFields { } /// Convert this to a valid json representation for the Notion API. + Map toRequestJson() => { + 'parent': parent.toJson(), + 'title': title.map((richText) => richText.toJson()).toList(), + 'properties': properties.toJson(), + }; + + /// Convert this to a valid json representation for the Notion API response. Map toJson() => { 'object': objectTypeToString(this.object), + 'id': this.id, + 'created_time': createdTime, + 'last_edited_by': lastEditedTime, 'title': title.map((e) => e.toJson()).toList(), 'parent': parent.toJson(), 'properties': properties.toJson(), diff --git a/lib/src/notion_databases.dart b/lib/src/notion_databases.dart index 0d5fd35..8b7a72d 100644 --- a/lib/src/notion_databases.dart +++ b/lib/src/notion_databases.dart @@ -76,7 +76,7 @@ class NotionDatabasesClient { Future create(Database database) async { http.Response res = await http.post( Uri.https(host, '/$_v/$path'), - body: jsonEncode(database.toJson()), + body: jsonEncode(database.toRequestJson()), headers: { 'Authorization': 'Bearer $_token', 'Notion-Version': _dateVersion, diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index 9767991..dcb113f 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -211,7 +211,9 @@ void main() { await databases.retrieve(database_id: testDatabaseId ?? ''); expect(res.status, 200); - expect(res.isOk, true); + expect(res.isOk, isTrue); + expect(res.isDatabase, isTrue); + expect(res.content, isA()); }); test('Retrieve all databases', () async { @@ -248,21 +250,21 @@ void main() { expect(res.content.length, lessThanOrEqualTo(limit)); }); - test('Create a database', () async { + test('Create a database with title', () async { final NotionDatabasesClient databases = NotionDatabasesClient(auth: token ?? ''); NotionResponse res = await databases.create(Database( parent: Parent.page(id: testPageId ?? ''), title: [ - Text('Database from test'), + RichText('Database from test'), ], - pagesColumnName: 'Custom pages column', properties: Properties(map: { 'Description': MultiSelectProp(options: [ MultiSelectOption(name: 'Read', color: ColorsTypes.Blue), MultiSelectOption(name: 'Sleep', color: ColorsTypes.Green), - ]) + ]), + 'Test': TitleProp(), }), )); @@ -270,12 +272,13 @@ void main() { expect(res.isOk, true); }); - test('Create a database with default', () async { + test('Create a database without title', () async { final NotionDatabasesClient databases = NotionDatabasesClient(auth: token ?? ''); NotionResponse res = await databases.create(Database( parent: Parent.page(id: testPageId ?? ''), + properties: Properties.forDatabase(title: 'ABC'), )); expect(res.status, 200); diff --git a/test/objects/database_test.dart b/test/objects/database_test.dart index 655c6b9..d37ec27 100644 --- a/test/objects/database_test.dart +++ b/test/objects/database_test.dart @@ -15,9 +15,9 @@ void main() { test('Create new database instance', () { Database database = Database( parent: Parent.page(id: 'some_id'), - title: [Text('Database title')], - pagesColumnName: 'CustomColumName', + title: [RichText('Database title')], properties: Properties(map: { + 'CustomColumName': TitleProp(), 'Description': RichTextProp(), }), ); @@ -29,7 +29,7 @@ void main() { }); test('Create new instance with data', () { - Database database = Database.withDefaults(title: [Text('Title')]) + Database database = Database.withDefaults(title: [RichText('Title')]) .addProperty( name: 'Tags', property: MultiSelectProp(options: [ @@ -56,7 +56,7 @@ void main() { test('Create json from instance', () { Map database = - Database.withDefaults(title: [Text('Title')]) + Database.withDefaults(title: [RichText('Title')]) .addProperty( name: 'Tags', property: MultiSelectProp(options: [ @@ -109,7 +109,12 @@ void main() { "multi_select": {"options": []} }, "Details": {"id": "title", "type": "title", "title": {}} - } + }, + "parent": { + "type": "page_id", + "page_id": "ba3e9659-1de0-4c93-b3ad-78b9b16e5507" + }, + "url": "https://www.notion.so/8bd452157e1642dd8aad5734a2372518", }; Database database = Database.fromJson(jsonDatabase); @@ -125,12 +130,8 @@ void main() { test('Map from wrong json', () { Map wrongJsonDatabase = {}; - Database database = Database.fromJson(wrongJsonDatabase); - - expect(database.title, isEmpty); - expect(database.id, isEmpty); - expect(database.properties.contains('Tags'), false); - expect(database.properties.contains('Details'), false); + expect(() => Database.fromJson(wrongJsonDatabase), + throwsA(isA())); }); test('Add properties from json', () { From 2cf0a2fe7b7314383a63e34d7821a895eca1fa16 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 23 Feb 2022 22:17:55 -0600 Subject: [PATCH 27/42] Fixes wrong field type on test --- test/blocks/block.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/blocks/block.dart b/test/blocks/block.dart index 3580ad0..6f9d28c 100644 --- a/test/blocks/block.dart +++ b/test/blocks/block.dart @@ -34,8 +34,8 @@ void main() { }, ] }, - createdTime: '2021-05-20T21:01:00.000Z', - lastEditedTime: '2021-05-26T19:10:00.000Z', + createdTime: DateTime.parse('2021-05-20T21:01:00.000Z'), + lastEditedTime: DateTime.parse('2021-05-26T19:10:00.000Z'), ); expect(block.strType, 'paragraph'); @@ -65,8 +65,8 @@ void main() { }, ] }, - createdTime: '2021-05-20T21:01:00.000Z', - lastEditedTime: '2021-05-26T19:10:00.000Z', + createdTime: DateTime.parse('2021-05-20T21:01:00.000Z'), + lastEditedTime: DateTime.parse('2021-05-26T19:10:00.000Z'), ).toJson(); expect(json['type'], 'paragraph'); From b9dbd9da843385e3e78f360fa5a9c9cc0d4bd965 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 23 Feb 2022 23:08:57 -0600 Subject: [PATCH 28/42] Improves Database class Updates documentation Removes unused code - empty constructor - addPropertiesFromJson Improves `withDefaults` constructor & rename it to `simple` --- lib/src/notion/objects/database.dart | 44 ++++++-------- test/objects/database_test.dart | 86 ++++++++-------------------- 2 files changed, 42 insertions(+), 88 deletions(-) diff --git a/lib/src/notion/objects/database.dart b/lib/src/notion/objects/database.dart index 2e66f3f..f67ad21 100644 --- a/lib/src/notion/objects/database.dart +++ b/lib/src/notion/objects/database.dart @@ -24,6 +24,10 @@ class Database extends Object { String url; /// Map a new database instance for a new request. + /// + /// Receive the database [parent] and [properties], and also con receive the database [title] but is optional (by default will set to "Untitled"). + /// + /// We recommend to use `Properties.forDatabase` on the [properties] field to be sure that any required property is missing, like the Title property. Database({ required this.parent, required this.properties, @@ -31,8 +35,8 @@ class Database extends Object { }) : url = ''; /// Main database constructor. - /// TODO: Update docs. - /// Can receive the [parent] (required), the [title] (empty), the [pagesColumnName] ("Name") and the [properties] (null). + /// + /// Can receive all the available properties for a database which are the [id], [createdTime], [lastEditedTime], [title], [properties], [parent] and [url]. Database.constructor({ // Object properties required String id, @@ -50,26 +54,20 @@ class Database extends Object { lastEditedTime: lastEditedTime, ); - /// Constructor for empty database. - Database.empty() - : url = "", - parent = Parent.none(); - /// Database constructor with defaults parameters. /// - /// Can receive the [parent] (none parent), [title] (empty), the [createdTime] (""), the [lastEditedTime] ("") and the database [id] ("") but every parameter is optional. - Database.withDefaults({ - this.parent: const Parent.none(), - this.title: const [], - this.url: '', - String id: '', - DateTime? createdTime, - DateTime? lastEditedTime, - }) : super( - id: id, - createdTime: createdTime, - lastEditedTime: lastEditedTime, - ); + /// Can receive the database [parent], [title] and the [titleColumnName] but in a simplified way. + /// + /// The [title] parameter is a string that will be the content at the only `RichtText` element in the `title` attribute. And the [titleColumnName] is the name of the default title column for the database that is mandatory. + Database.simple({ + required this.parent, + required String titleColumnName, + String? title, + }) : this.title = [if (title != null) RichText(title)], + this.properties = Properties(map: { + titleColumnName: TitleProp(), + }), + this.url = ''; /// Map a new database instance from a [json] map. factory Database.fromJson(Map json) { @@ -107,12 +105,6 @@ class Database extends Object { return this; } - /// Add a group of properties from a [json] map and return this instance. - Database addPropertiesFromJson(Map json) { - this.properties.addAllFromJson(json); - return this; - } - /// Convert this to a valid json representation for the Notion API. Map toRequestJson() => { 'parent': parent.toJson(), diff --git a/test/objects/database_test.dart b/test/objects/database_test.dart index d37ec27..5c4b93d 100644 --- a/test/objects/database_test.dart +++ b/test/objects/database_test.dart @@ -3,15 +3,6 @@ import 'package:test/test.dart'; void main() { group('Database Instance =>', () { - test('Create new empty instance', () { - Database database = Database.empty(); - - expect(database, isNotNull); - expect(database.title, isEmpty); - expect(database.properties.entries, isEmpty); - expect(database.object, ObjectTypes.Database); - }); - test('Create new database instance', () { Database database = Database( parent: Parent.page(id: 'some_id'), @@ -29,7 +20,10 @@ void main() { }); test('Create new instance with data', () { - Database database = Database.withDefaults(title: [RichText('Title')]) + Database database = Database.simple( + parent: Parent.none(), + title: 'New Database', + titleColumnName: 'Pages') .addProperty( name: 'Tags', property: MultiSelectProp(options: [ @@ -41,38 +35,35 @@ void main() { property: RichTextProp(content: [ Text('Detail A'), Text('Detail B'), - ])) - .addProperty( - name: 'Name', - property: TitleProp(content: [Text('Something here...')])); + ])); expect(database, isNotNull); expect(database.title.length, 1); expect(database.properties.entries, isNotEmpty); expect(database.properties.getByName('Tags').isMultiSelect, true); expect(database.properties.getByName('Details').isRichText, true); - expect(database.properties.getByName('Name').isTitle, true); + expect(database.properties.getByName('Pages').isTitle, true); }); test('Create json from instance', () { - Map database = - Database.withDefaults(title: [RichText('Title')]) - .addProperty( - name: 'Tags', - property: MultiSelectProp(options: [ - MultiSelectOption(name: 'Option A'), - MultiSelectOption(name: 'Option B'), - ])) - .addProperty( - name: 'Details', - property: RichTextProp(content: [ - Text('Detail A'), - Text('Detail B'), - ])) - .addProperty( - name: 'Name', - property: TitleProp(content: [Text('Something here...')])) - .toJson(); + Map database = Database.simple( + parent: Parent.none(), + title: 'Title', + titleColumnName: 'Pages', + ) + .addProperty( + name: 'Tags', + property: MultiSelectProp(options: [ + MultiSelectOption(name: 'Option A'), + MultiSelectOption(name: 'Option B'), + ])) + .addProperty( + name: 'Details', + property: RichTextProp(content: [ + Text('Detail A'), + Text('Detail B'), + ])) + .toJson(); expect(database, isNotNull); expect(database['object'], 'database'); @@ -133,34 +124,5 @@ void main() { expect(() => Database.fromJson(wrongJsonDatabase), throwsA(isA())); }); - - test('Add properties from json', () { - Database database = Database.empty().addPropertiesFromJson({ - "Tags": { - "id": ">cp;", - "type": "multi_select", - "multi_select": { - "options": [ - {"name": "A"}, - {"name": "B"} - ] - } - }, - "Details": {"id": "title", "type": "title", "title": {}} - }); - - expect(database.properties.contains('Tags'), true); - expect(database.properties.getByName('Tags').isMultiSelect, true); - expect( - database.properties.getByName('Tags').value, - allOf([ - isList, - hasLength(2), - isA>(), - ])); - expect(database.properties.contains('Details'), true); - expect(database.properties.getByName('Details').isTitle, true); - expect(database.properties.getByName('Details').value, isList); - }); }); } From 37a24276f93242f5a84592d81e8abce6720fc70a Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Wed, 23 Feb 2022 23:18:17 -0600 Subject: [PATCH 29/42] Rename database_id to databaseId And mark as deprecated list databases method --- lib/src/notion_databases.dart | 51 ++++++++++++++++++----------------- test/notion_api_test.dart | 18 +++++++++++-- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/lib/src/notion_databases.dart b/lib/src/notion_databases.dart index 8b7a72d..8443ebe 100644 --- a/lib/src/notion_databases.dart +++ b/lib/src/notion_databases.dart @@ -33,15 +33,34 @@ class NotionDatabasesClient { this._v = version, this._dateVersion = dateVersion; - /// Retrieve the database specified by the [database_id]. + /// Retrieve the database specified by the [databaseId]. /// /// _See more at https://developers.notion.com/reference/get-database_ - Future retrieve({required String database_id}) async { - http.Response res = - await http.get(Uri.https(host, '/$_v/$path/$database_id'), headers: { - 'Authorization': 'Bearer $_token', - 'Notion-Version': _dateVersion, - }); + Future retrieve({required String databaseId}) async { + http.Response res = await http.get( + Uri.https(host, '/$_v/$path/$databaseId'), + headers: { + 'Authorization': 'Bearer $_token', + 'Notion-Version': _dateVersion, + }, + ); + + return NotionResponse.fromResponse(res); + } + + /// Create a [database]. + /// + /// _See more at https://developers.notion.com/reference/create-a-database_ + Future create(Database database) async { + http.Response res = await http.post( + Uri.https(host, '/$_v/$path'), + body: jsonEncode(database.toRequestJson()), + headers: { + 'Authorization': 'Bearer $_token', + 'Notion-Version': _dateVersion, + 'Content-Type': 'application/json', + }, + ); return NotionResponse.fromResponse(res); } @@ -52,6 +71,7 @@ class NotionDatabasesClient { /// Also a [pageSize] can be defined to limit the result. The max value is 100. /// /// _See more at https://developers.notion.com/reference/get-databases_ + @deprecated Future list({String? startCursor, int? pageSize}) async { Map query = {}; if (startCursor != null) { @@ -69,21 +89,4 @@ class NotionDatabasesClient { return NotionResponse.fromResponse(res); } - - /// Create a [database]. - /// - /// _See more at https://developers.notion.com/reference/create-a-database_ - Future create(Database database) async { - http.Response res = await http.post( - Uri.https(host, '/$_v/$path'), - body: jsonEncode(database.toRequestJson()), - headers: { - 'Authorization': 'Bearer $_token', - 'Notion-Version': _dateVersion, - 'Content-Type': 'application/json', - }, - ); - - return NotionResponse.fromResponse(res); - } } diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index dcb113f..142c512 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -208,7 +208,7 @@ void main() { NotionDatabasesClient(auth: token ?? ''); NotionResponse res = - await databases.retrieve(database_id: testDatabaseId ?? ''); + await databases.retrieve(databaseId: testDatabaseId ?? ''); expect(res.status, 200); expect(res.isOk, isTrue); @@ -278,7 +278,21 @@ void main() { NotionResponse res = await databases.create(Database( parent: Parent.page(id: testPageId ?? ''), - properties: Properties.forDatabase(title: 'ABC'), + properties: Properties.forDatabase(title: 'Title Column'), + )); + + expect(res.status, 200); + expect(res.isOk, true); + }); + + test('Create a database with simple constructor', () async { + final NotionDatabasesClient databases = + NotionDatabasesClient(auth: token ?? ''); + + NotionResponse res = await databases.create(Database.simple( + parent: Parent.page(id: testPageId ?? ''), + title: 'Simple database', + titleColumnName: 'Title Column', )); expect(res.status, 200); From 493632e5b449960f8f11ece24a2d37f958c9f31b Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Thu, 24 Feb 2022 01:16:17 -0600 Subject: [PATCH 30/42] Renames database_id to databaseId --- test/response_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/response_test.dart b/test/response_test.dart index 91ca6e2..1150834 100644 --- a/test/response_test.dart +++ b/test/response_test.dart @@ -148,7 +148,7 @@ void main() { NotionDatabasesClient db = NotionDatabasesClient(auth: token ?? ''); NotionResponse response = - await db.retrieve(database_id: testDatabaseId ?? ''); + await db.retrieve(databaseId: testDatabaseId ?? ''); expect(response.isDatabase, true); expect(response.content.title, allOf([isList, isNotEmpty, hasLength(1)])); From e502432301e902aa38d07c0ed9c48387e8b445eb Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Thu, 24 Feb 2022 01:16:41 -0600 Subject: [PATCH 31/42] Adds database properties library and add name as a base field of properties --- lib/src/notion/general/property.dart | 122 +++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 8 deletions(-) diff --git a/lib/src/notion/general/property.dart b/lib/src/notion/general/property.dart index c747391..2b2fc6e 100644 --- a/lib/src/notion/general/property.dart +++ b/lib/src/notion/general/property.dart @@ -10,6 +10,9 @@ class Property { /// The property id. String? id; + /// The property name. + String? name; + /// The base getter for the content of any property. dynamic get value => false; @@ -30,8 +33,8 @@ class Property { /// Main property constructor. /// - /// Can receive the property [id]. - Property({this.id}); + /// Can receive the property [id] and [name]. + Property({this.id, this.name}); /// Constructor for empty property. Property.empty(); @@ -203,7 +206,10 @@ class MultiSelectProp extends Property { /// Main multi select constructor. /// /// Can receive the list6 of the options. - MultiSelectProp({this.options: const []}); + MultiSelectProp({ + this.options: const [], + String? name, + }) : super(name: name); MultiSelectProp.fromJson(Map json, {String? subfield}) : this.options = MultiSelectOption.fromListJson((subfield != null @@ -220,11 +226,11 @@ class MultiSelectProp extends Property { /// Convert this to a valid json representation for the Notion API. @override Map toJson() { - Map json = {'type': strType}; - - if (id != null) { - json['id'] = id; - } + Map json = { + 'type': strType, + if (id != null) 'id': id, + if (name != null) 'name': name, + }; json[strType] = {'options': options.map((e) => e.toJson()).toList()}; @@ -279,3 +285,103 @@ class MultiSelectOption { static List fromListJson(List options) => options.map((e) => MultiSelectOption.fromJson(e)).toList(); } + +/// The library of database properties. +class DatabaseProperties { + /// Returns a title property. + /// + /// Can specify the [name] of the property. + static TitleDatabaseProperty Title({String? name}) => + TitleDatabaseProperty(name: name); + + /// Returns a rich text property. + /// + /// Can specify the [name] of the property. + static RichTextDatabaseProperty RichText({String? name}) => + RichTextDatabaseProperty(name: name); + + /// Returns a checkbox property. + /// + /// Can specify the [name] of the property. + static CheckboxDatabaseProperty Checkbox({String? name}) => + CheckboxDatabaseProperty(name: name); + + /// Returns a multiselect property. + /// + /// Can specify the [options] and the [name] of the property. + static MultiSelectProp MultiSelect( + {List? options, String? name}) => + MultiSelectProp(options: options ?? [], name: name); +} + +/// A representation of a title property for any Notion object. +class TitleDatabaseProperty extends Property { + /// The property type. Always Title for this. + @override + final PropertiesTypes type = PropertiesTypes.Title; + + /// Main title property constructor. + TitleDatabaseProperty({String? name}) : super(name: name); + + /// Create a new property instance from json. + /// + /// Receive a [json] from where the information is extracted. + TitleDatabaseProperty.fromJson(Map json) + : super(id: json['id']); + + /// Convert this to a valid json representation for the Notion API. + @override + Map toJson() => { + 'type': strType, + if (name != null) 'name': name, + strType: {}, + }; +} + +/// A representation of a rich text property for any Notion object. +class RichTextDatabaseProperty extends Property { + /// The property type. Always RichText for this. + @override + final PropertiesTypes type = PropertiesTypes.RichText; + + /// Main RichText constructor. + RichTextDatabaseProperty({String? name}) : super(name: name); + + /// Create a new rich text instance from json. + /// + /// Receive a [json] from where the information is extracted. + RichTextDatabaseProperty.fromJson(Map json) + : super(id: json['id']); + + /// Convert this to a valid json representation for the Notion API. + @override + Map toJson() => { + 'type': strType, + if (name != null) 'name': name, + strType: {}, + }; +} + +/// A representation of a checkbox property for any Notion object. +class CheckboxDatabaseProperty extends Property { + /// The property type. Always Checkbox for this. + @override + final PropertiesTypes type = PropertiesTypes.Checkbox; + + /// Main checkbox property constructor. + CheckboxDatabaseProperty({String? name}) : super(name: name); + + /// Create a new property instance from json. + /// + /// Receive a [json] from where the information is extracted. + CheckboxDatabaseProperty.fromJson(Map json) + : super(id: json['id']); + + /// Convert this to a valid json representation for a Notion database property. + @override + Map toJson() => { + 'type': strType, + if (name != null) 'name': name, + strType: {}, + }; +} From 2049c75c6e0903bb4f9e7e5225ce07c8235855fa Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Thu, 24 Feb 2022 01:17:25 -0600 Subject: [PATCH 32/42] Implements database properties --- lib/src/notion/objects/database.dart | 2 +- test/notion_api_test.dart | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/src/notion/objects/database.dart b/lib/src/notion/objects/database.dart index f67ad21..a02d4ff 100644 --- a/lib/src/notion/objects/database.dart +++ b/lib/src/notion/objects/database.dart @@ -65,7 +65,7 @@ class Database extends Object { String? title, }) : this.title = [if (title != null) RichText(title)], this.properties = Properties(map: { - titleColumnName: TitleProp(), + titleColumnName: DatabaseProperties.Title(), }), this.url = ''; diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index 142c512..445ec83 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -298,6 +298,29 @@ void main() { expect(res.status, 200); expect(res.isOk, true); }); + + test('Update a database', () async { + final NotionDatabasesClient databases = + NotionDatabasesClient(auth: token ?? ''); + + NotionResponse res = await databases.update( + databaseId: '8bd452157e1642dd8aad5734a2372518', + title: [RichText('New Title')], + properties: Properties(map: { + 'Test': DatabaseProperties.MultiSelect( + options: [ + MultiSelectOption(name: 'Read', color: ColorsTypes.Blue), + MultiSelectOption(name: 'Sleep', color: ColorsTypes.Green), + ], + ), + 'Column': DatabaseProperties.Checkbox(name: 'Ready') + })); + + print(res.message); + + expect(res.status, 200); + expect(res.isOk, true); + }); }); group('Notion Block Client =>', () { From 01bf7c4e00676702f4fbff38f154065a7a860b68 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Thu, 24 Feb 2022 01:17:32 -0600 Subject: [PATCH 33/42] Adds update database --- lib/src/notion_databases.dart | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/lib/src/notion_databases.dart b/lib/src/notion_databases.dart index 8443ebe..ad0ca8c 100644 --- a/lib/src/notion_databases.dart +++ b/lib/src/notion_databases.dart @@ -65,6 +65,61 @@ class NotionDatabasesClient { return NotionResponse.fromResponse(res); } + /// Update the database [title] and [properties] with the [databaseId]. + /// + /// To **add a new property** set the key and the property type. Example: + /// ``` + /// NotionResponse res = await databases.update( + /// databaseId: 'some_existing_database_id', + /// properties: Properties(map: { + /// 'Tag': DatabaseProperties.Checkbox() // "Tag" will be created as a checkbox property + /// })); + /// ``` + /// + /// To **update an existing property** set the key as the current property name. Example: + /// ``` + /// NotionResponse res = await databases.update( + /// databaseId: 'some_existing_database_id', + /// properties: Properties(map: { + /// 'Tag': DatabaseProperties.RichText() // If "Tag" was Checkbox will be turn into RichText property + /// })); + /// ``` + /// + /// To **rename an existing property** set the key as the current property name and set the name parameters to the new name. Example: + /// ``` + /// NotionResponse res = await databases.update( + /// databaseId: 'some_existing_database_id', + /// properties: Properties(map: { + /// 'Tag': DatabaseProperties.RichText(name: 'Details') // "Tag" will be renamed to "Details" + /// })); + /// ``` + /// + /// **Warning:** Cannot change a title property to a different property type. + /// + /// _https://developers.notion.com/reference/update-a-database_ + Future update({ + required String databaseId, + List? title, + Properties? properties, + }) async { + Map toUpdate = {}; + + if (title != null) toUpdate['title'] = title; + if (properties != null) toUpdate['properties'] = properties; + + http.Response res = await http.patch( + Uri.https(host, '/$_v/$path/${databaseId}'), + body: jsonEncode(toUpdate), + headers: { + 'Authorization': 'Bearer $_token', + 'Notion-Version': _dateVersion, + 'Content-Type': 'application/json', + }, + ); + + return NotionResponse.fromResponse(res); + } + /// Retrieve all databases. /// /// A [startCursor] can be defined to specify the page where to start. From 90529583410ff319c0204b0d65f34afe7a1a343f Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Thu, 24 Feb 2022 01:18:30 -0600 Subject: [PATCH 34/42] Implements database properties library --- test/notion_api_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index 445ec83..ac091e6 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -264,7 +264,7 @@ void main() { MultiSelectOption(name: 'Read', color: ColorsTypes.Blue), MultiSelectOption(name: 'Sleep', color: ColorsTypes.Green), ]), - 'Test': TitleProp(), + 'Test': DatabaseProperties.Title(), }), )); From 66276239d7166a9d73f109552df14899be3d0c71 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Thu, 24 Feb 2022 12:49:56 -0600 Subject: [PATCH 35/42] Fixes error String not a subtype of DateTime? --- lib/src/notion/objects/block.dart | 8 ++++++-- lib/src/notion/objects/pages.dart | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/src/notion/objects/block.dart b/lib/src/notion/objects/block.dart index 5b08d33..f4ff3fd 100644 --- a/lib/src/notion/objects/block.dart +++ b/lib/src/notion/objects/block.dart @@ -79,8 +79,12 @@ class Block extends Object { this.jsonContent = json['type'] != null ? json[json['type']] ?? {} : {}, this.type = stringToBlockType(json['type'] ?? ''), super( - createdTime: json['created_time'] ?? '', - lastEditedTime: json['last_edited_time'] ?? '', + createdTime: json['created_time'] != null + ? DateTime.parse(json['created_time']) + : null, + lastEditedTime: json['last_edited_time'] != null + ? DateTime.parse(json['last_edited_time']) + : null, ); /// Convert this to a valid json representation for the Notion API. diff --git a/lib/src/notion/objects/pages.dart b/lib/src/notion/objects/pages.dart index 82475ad..7401b49 100644 --- a/lib/src/notion/objects/pages.dart +++ b/lib/src/notion/objects/pages.dart @@ -59,8 +59,12 @@ class Page extends Object { archived: json['archived'] ?? false, ).addPropertiesFromJson(json['properties'] ?? {}); page.setBaseProperties( - createdTime: json['created_time'] ?? '', - lastEditedTime: json['last_edited_time'] ?? ''); + createdTime: json['created_time'] != null + ? DateTime.parse(json['created_time']) + : null, + lastEditedTime: json['last_edited_time'] != null + ? DateTime.parse(json['last_edited_time']) + : null); return page; } From 1fe5f93d10d2dbeabea0737632542ba443fcdd99 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Thu, 24 Feb 2022 12:50:17 -0600 Subject: [PATCH 36/42] Updates release date for v2.0.0 --- ROADMAP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index 2b9703a..b687aec 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -28,7 +28,7 @@ If you have suggestions feel free to create an Issue or to create a PR with the ## v2.0.0 ||| |:---------------|:------------| -| Release date | 15/Mar/2022 | +| Release date | 31/Mar/2022 | | Notion-Version | 2021-08-16 | * **Full refactorization to all the project** From 6ed5bbb3aa26f6f3527832133eb7a4cab7aa0081 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Thu, 24 Feb 2022 12:50:56 -0600 Subject: [PATCH 37/42] [Try] Improve database and properties --- lib/src/notion/general/property.dart | 100 -------- .../new/database/database_property.dart | 230 ++++++++++++++++++ lib/src/notion/new/properties.dart | 50 ++++ lib/src/notion/new/property.dart | 18 ++ lib/src/notion/objects/database.dart | 71 +++--- lib/src/notion_databases.dart | 31 ++- test/notion_api_test.dart | 93 +++---- test/objects/database_test.dart | 113 +++++---- 8 files changed, 478 insertions(+), 228 deletions(-) create mode 100644 lib/src/notion/new/database/database_property.dart create mode 100644 lib/src/notion/new/properties.dart create mode 100644 lib/src/notion/new/property.dart diff --git a/lib/src/notion/general/property.dart b/lib/src/notion/general/property.dart index 2b2fc6e..37194ef 100644 --- a/lib/src/notion/general/property.dart +++ b/lib/src/notion/general/property.dart @@ -285,103 +285,3 @@ class MultiSelectOption { static List fromListJson(List options) => options.map((e) => MultiSelectOption.fromJson(e)).toList(); } - -/// The library of database properties. -class DatabaseProperties { - /// Returns a title property. - /// - /// Can specify the [name] of the property. - static TitleDatabaseProperty Title({String? name}) => - TitleDatabaseProperty(name: name); - - /// Returns a rich text property. - /// - /// Can specify the [name] of the property. - static RichTextDatabaseProperty RichText({String? name}) => - RichTextDatabaseProperty(name: name); - - /// Returns a checkbox property. - /// - /// Can specify the [name] of the property. - static CheckboxDatabaseProperty Checkbox({String? name}) => - CheckboxDatabaseProperty(name: name); - - /// Returns a multiselect property. - /// - /// Can specify the [options] and the [name] of the property. - static MultiSelectProp MultiSelect( - {List? options, String? name}) => - MultiSelectProp(options: options ?? [], name: name); -} - -/// A representation of a title property for any Notion object. -class TitleDatabaseProperty extends Property { - /// The property type. Always Title for this. - @override - final PropertiesTypes type = PropertiesTypes.Title; - - /// Main title property constructor. - TitleDatabaseProperty({String? name}) : super(name: name); - - /// Create a new property instance from json. - /// - /// Receive a [json] from where the information is extracted. - TitleDatabaseProperty.fromJson(Map json) - : super(id: json['id']); - - /// Convert this to a valid json representation for the Notion API. - @override - Map toJson() => { - 'type': strType, - if (name != null) 'name': name, - strType: {}, - }; -} - -/// A representation of a rich text property for any Notion object. -class RichTextDatabaseProperty extends Property { - /// The property type. Always RichText for this. - @override - final PropertiesTypes type = PropertiesTypes.RichText; - - /// Main RichText constructor. - RichTextDatabaseProperty({String? name}) : super(name: name); - - /// Create a new rich text instance from json. - /// - /// Receive a [json] from where the information is extracted. - RichTextDatabaseProperty.fromJson(Map json) - : super(id: json['id']); - - /// Convert this to a valid json representation for the Notion API. - @override - Map toJson() => { - 'type': strType, - if (name != null) 'name': name, - strType: {}, - }; -} - -/// A representation of a checkbox property for any Notion object. -class CheckboxDatabaseProperty extends Property { - /// The property type. Always Checkbox for this. - @override - final PropertiesTypes type = PropertiesTypes.Checkbox; - - /// Main checkbox property constructor. - CheckboxDatabaseProperty({String? name}) : super(name: name); - - /// Create a new property instance from json. - /// - /// Receive a [json] from where the information is extracted. - CheckboxDatabaseProperty.fromJson(Map json) - : super(id: json['id']); - - /// Convert this to a valid json representation for a Notion database property. - @override - Map toJson() => { - 'type': strType, - if (name != null) 'name': name, - strType: {}, - }; -} diff --git a/lib/src/notion/new/database/database_property.dart b/lib/src/notion/new/database/database_property.dart new file mode 100644 index 0000000..125c4be --- /dev/null +++ b/lib/src/notion/new/database/database_property.dart @@ -0,0 +1,230 @@ +import 'package:notion_api/src/notion/new/properties.dart'; +import 'package:notion_api/src/notion/new/property.dart'; +import 'package:notion_api/src/utils/utils.dart'; +import 'package:notion_api/src/notion/general/notion_types.dart'; + +class DatabaseProperties extends Properties { + /// Main properties constructor. + /// + /// Should receive the default [mainColumnName] for the permanent title column. Also can receive a properties [properties]. + DatabaseProperties({ + String? mainColumnName, + Map? properties, + }) : super(map: properties) { + if (mainColumnName != null) + add(name: mainColumnName, property: DatabaseProperty.Title()); + } + + /// Map a new properties instance from a [json] map. + DatabaseProperties.fromJson(Map json) { + json.entries.forEach((entry) { + entries[entry.key] = DatabaseProperty.fromJson(entry.value); + }); + } + + /// Convert this to a valid json representation for the Notion API. + Map toJson() { + Map json = {}; + + entries.entries.forEach((element) { + json[element.key] = element.value.toJson(); + }); + + return json; + } +} + +/// A representation of a single property for any Notion object. +class DatabaseProperty extends Property { + /// The property name. + String name; + + /// Main property constructor. + /// + /// Can receive the property [id] and [name]. + DatabaseProperty({String? id, String? name}) + : name = name ?? '', + super(id: id); + + /// Get this as a valid partial json representation for the Notion API. + Map toJson() => { + 'type': strType, + if (id.isNotEmpty) 'id': id, + if (name.isNotEmpty) 'name': name, + }; + + /// Create a new Property instance from json. + /// + /// Receive a [json] from where the information is extracted. + factory DatabaseProperty.fromJson(Map json) { + PropertiesTypes type = extractPropertyType(json); + if (type == PropertiesTypes.Title) { + return TitleDbProp.fromJson(json); + } else if (type == PropertiesTypes.RichText) { + return RichTextDbProp.fromJson(json); + } else if (type == PropertiesTypes.MultiSelect) { + return MultiSelectDbProp.fromJson(json); + } else if (type == PropertiesTypes.Checkbox) { + return CheckboxtDbProp.fromJson(json); + } else { + return DatabaseProperty(); + } + } + + static TitleDbProp Title({ + String? name, + }) => + TitleDbProp(name: name); + + static RichTextDbProp RichText({ + String? name, + }) => + RichTextDbProp(name: name); + + static MultiSelectDbProp MultiSelect({ + List options: const [], + String? name, + }) => + MultiSelectDbProp(name: name); + + static CheckboxtDbProp Checkbox({ + String? name, + }) => + CheckboxtDbProp(name: name); +} + +class TitleDbProp extends DatabaseProperty { + @override + final PropertiesTypes type = PropertiesTypes.Title; + + TitleDbProp({String? name}) : super(name: name); + + TitleDbProp.fromJson(Map json) + : super( + id: json['id'], + name: json['name'], + ); + + /// Get this as a valid json representation for the Notion API. + @override + Map toJson() => { + 'type': strType, + if (id.isNotEmpty) 'id': id, + if (name.isNotEmpty) 'name': name, + strType: {}, + }; +} + +class RichTextDbProp extends DatabaseProperty { + @override + final PropertiesTypes type = PropertiesTypes.RichText; + + RichTextDbProp({String? name}) : super(name: name); + + RichTextDbProp.fromJson(Map json) + : super( + id: json['id'], + name: json['name'], + ); + + /// Get this as a valid json representation for the Notion API. + @override + Map toJson() => { + 'type': strType, + if (id.isNotEmpty) 'id': id, + if (name.isNotEmpty) 'name': name, + strType: {}, + }; +} + +class CheckboxtDbProp extends DatabaseProperty { + @override + final PropertiesTypes type = PropertiesTypes.Checkbox; + + CheckboxtDbProp({String? name}) : super(name: name); + + CheckboxtDbProp.fromJson(Map json) + : super( + id: json['id'], + name: json['name'], + ); + + /// Get this as a valid json representation for the Notion API. + @override + Map toJson() => { + 'type': strType, + if (id.isNotEmpty) 'id': id, + if (name.isNotEmpty) 'name': name, + strType: {}, + }; +} + +class MultiSelectDbProp extends DatabaseProperty { + @override + PropertiesTypes type = PropertiesTypes.MultiSelect; + + List options; + + MultiSelectDbProp({ + this.options: const [], + String? name, + }) : super(name: name); + + MultiSelectDbProp.fromJson(Map json) + : options = List.from( + json[propertyTypeToString(PropertiesTypes.MultiSelect)] + ['options']) + .map((e) => MultiSelectOptionDbProp.fromJson(e)) + .toList(), + super( + id: json['id'], + name: json['name'], + ); + + /// Get this as a valid json representation for the Notion API. + @override + Map toJson() => { + 'type': strType, + if (id.isNotEmpty) 'id': id, + if (name.isNotEmpty) 'name': name, + strType: { + 'options': + options.isNotEmpty ? options.map((e) => e.toJson()).toList() : [], + }, + }; +} + +class MultiSelectOptionDbProp { + /// The option name. + String name; + + /// The option id. + String? id; + + /// The option color. + ColorsTypes color; + + /// Main multi select option property constructor. + /// + /// Required the [name] field to display a text for the option. Also can receive the [id] and the [color] of the option. + MultiSelectOptionDbProp({ + required this.name, + this.id, + this.color: ColorsTypes.Default, + }); + + /// Create a new multi select instance from json. + /// + /// Receive a [json] from where the information is extracted. + MultiSelectOptionDbProp.fromJson(Map json) + : this.id = json['id'], + this.name = json['name'], + this.color = stringToColorType(json['color']); + + /// Convert this to a valid json representation for the Notion API. + Map toJson() => { + if (id != null) 'id': id, + 'name': name, + 'color': colorTypeToString(color), + }; +} diff --git a/lib/src/notion/new/properties.dart b/lib/src/notion/new/properties.dart new file mode 100644 index 0000000..3da9902 --- /dev/null +++ b/lib/src/notion/new/properties.dart @@ -0,0 +1,50 @@ +class Properties { + final Map entries = {}; + + /// Returns true if the properties map IS empty + bool get isEmpty => this.entries.isEmpty; + + /// Main properties constructor. + /// + /// Can receive a properties [map]. + Properties({Map? map}) { + this.entries.addAll(map ?? {}); + } + + /// Add a new [property] with a specific [name]. + void add({required String name, required T property}) { + this.entries[name] = property; + } + + /// Remove the property with the specific [name] and return the deleted property. + /// + /// Throws an Exception is any property is found with the [name]. + T remove(String name) { + if (contains(name)) { + return entries.remove(name)!; + } else { + throw 'No property found with "$name" name'; + } + } + + /// Get the property with the specific [name]. + /// + /// Throws an Exception is any property is found with the [name]. + T getByName(String name) { + if (contains(name)) { + return entries[name]!; + } else { + throw 'No property found with "$name" name'; + } + } + + /// Returns true if the property with the specific [name] is contained. + bool contains(String name) { + return this.entries.containsKey(name); + } + + /// Convert this to a valid json representation for the Notion API. + Map toJson() { + throw 'Not implemented'; + } +} diff --git a/lib/src/notion/new/property.dart b/lib/src/notion/new/property.dart new file mode 100644 index 0000000..b8d907d --- /dev/null +++ b/lib/src/notion/new/property.dart @@ -0,0 +1,18 @@ +import 'package:notion_api/notion_api.dart'; + +/// A representation of a single property for any Notion object. +class Property { + /// The property type. + final PropertiesTypes type = PropertiesTypes.None; + + /// The property id. + String id; + + /// The string value for this property type. + String get strType => propertyTypeToString(type); + + /// Main property constructor. + /// + /// Can receive the property [id] and [name]. + Property({String? id}) : id = id ?? ''; +} diff --git a/lib/src/notion/objects/database.dart b/lib/src/notion/objects/database.dart index a02d4ff..072deed 100644 --- a/lib/src/notion/objects/database.dart +++ b/lib/src/notion/objects/database.dart @@ -1,6 +1,7 @@ +import 'package:notion_api/src/notion/new/database/database_property.dart'; + import '../../utils/utils.dart'; import '../general/exports.dart'; -import '../lists/properties.dart'; import '../rich_text.dart'; import 'object.dart'; import 'parent.dart'; @@ -12,10 +13,10 @@ class Database extends Object { final ObjectTypes object = ObjectTypes.Database; /// The title of this database. - List title = []; + final List _title = []; /// The properties of this database. - Properties properties = Properties(); + DatabaseProperties properties; /// The information of the page parent. Parent parent; @@ -23,6 +24,8 @@ class Database extends Object { /// The URL of the Notion datanase. String url; + String get title => _title.first.text; + /// Map a new database instance for a new request. /// /// Receive the database [parent] and [properties], and also con receive the database [title] but is optional (by default will set to "Untitled"). @@ -31,8 +34,11 @@ class Database extends Object { Database({ required this.parent, required this.properties, - this.title: const [], - }) : url = ''; + String? title, + }) : url = '' { + if (parent.type != ParentType.Page) throw 'The parent should be a page'; + if (title != null) _title.add(RichText(title)); + } /// Main database constructor. /// @@ -43,7 +49,7 @@ class Database extends Object { DateTime? createdTime, DateTime? lastEditedTime, // Datebase properties - required this.title, + required String title, // TODO: Add icon & cover required this.properties, required this.parent, @@ -52,40 +58,46 @@ class Database extends Object { id: id, createdTime: createdTime, lastEditedTime: lastEditedTime, - ); + ) { + _title.add(RichText(title)); + } /// Database constructor with defaults parameters. /// - /// Can receive the database [parent], [title] and the [titleColumnName] but in a simplified way. + /// Can receive the database [parent], [title] and the [mainColumnName] but in a simplified way. /// - /// The [title] parameter is a string that will be the content at the only `RichtText` element in the `title` attribute. And the [titleColumnName] is the name of the default title column for the database that is mandatory. + /// The [title] parameter is a string that will be the content at the only `RichtText` element in the `title` attribute. And the [mainColumnName] is the name of the default title column for the database that is mandatory. Database.simple({ required this.parent, - required String titleColumnName, + required String mainColumnName, String? title, - }) : this.title = [if (title != null) RichText(title)], - this.properties = Properties(map: { - titleColumnName: DatabaseProperties.Title(), - }), - this.url = ''; + }) : this.url = '', + this.properties = DatabaseProperties(mainColumnName: mainColumnName) { + if (title != null) _title.add(RichText(title)); + } /// Map a new database instance from a [json] map. factory Database.fromJson(Map json) { throwIfAnyNull(json, ['id', 'properties', 'parent', 'url']); - return Database.constructor( - id: json['id'], - createdTime: json['created_time'] != null - ? DateTime.parse(json['created_time']) - : null, - lastEditedTime: json['last_edited_time'] != null - ? DateTime.parse(json['last_edited_time']) - : null, - title: RichText.fromListJson(json['title'] ?? []), - properties: Properties.fromJson(json['properties']), + Database database = Database( + properties: DatabaseProperties.fromJson(json['properties']), parent: Parent.fromJson(json['parent']), - url: json['url'], ); + + database.id = json['id']; + database.url = json['url']; + database._title.addAll(RichText.fromListJson(json['title'] ?? [])); + + if (json['last_edited_time'] != null) { + database.lastEditedTime = DateTime.parse(json['last_edited_time']); + } + + if (json['created_time'] != null) { + database.createdTime = DateTime.parse(json['created_time']); + } + + return database; } /// Add a new database [property] with an specific [name]. @@ -100,15 +112,14 @@ class Database extends Object { /// ]), /// ); /// ``` - Database addProperty({required String name, required Property property}) { + void addProperty({required String name, required DatabaseProperty property}) { this.properties.add(name: name, property: property); - return this; } /// Convert this to a valid json representation for the Notion API. Map toRequestJson() => { 'parent': parent.toJson(), - 'title': title.map((richText) => richText.toJson()).toList(), + 'title': _title.map((richText) => richText.toJson()).toList(), 'properties': properties.toJson(), }; @@ -118,7 +129,7 @@ class Database extends Object { 'id': this.id, 'created_time': createdTime, 'last_edited_by': lastEditedTime, - 'title': title.map((e) => e.toJson()).toList(), + 'title': _title.map((e) => e.toJson()).toList(), 'parent': parent.toJson(), 'properties': properties.toJson(), }; diff --git a/lib/src/notion_databases.dart b/lib/src/notion_databases.dart index ad0ca8c..d49a42a 100644 --- a/lib/src/notion_databases.dart +++ b/lib/src/notion_databases.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:http/http.dart' as http; +import 'package:notion_api/src/notion/new/database/database_property.dart'; import 'notion/exports.dart'; import 'responses/notion_response.dart'; @@ -51,7 +52,35 @@ class NotionDatabasesClient { /// Create a [database]. /// /// _See more at https://developers.notion.com/reference/create-a-database_ - Future create(Database database) async { + @deprecated + Future oldCreate(Database database) async { + http.Response res = await http.post( + Uri.https(host, '/$_v/$path'), + body: jsonEncode(database.toRequestJson()), + headers: { + 'Authorization': 'Bearer $_token', + 'Notion-Version': _dateVersion, + 'Content-Type': 'application/json', + }, + ); + + return NotionResponse.fromResponse(res); + } + + /// Create a [database]. + /// + /// _See more at https://developers.notion.com/reference/create-a-database_ + Future create({ + required String pageId, + required DatabaseProperties properties, + String? title, + }) async { + Database database = Database( + parent: Parent.page(id: pageId), + properties: properties, + title: title, + ); + http.Response res = await http.post( Uri.https(host, '/$_v/$path'), body: jsonEncode(database.toRequestJson()), diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index ac091e6..9a328c3 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -2,6 +2,7 @@ import 'dart:io' show Platform; import 'package:dotenv/dotenv.dart' show load, env, clean; import 'package:notion_api/notion_api.dart'; +import 'package:notion_api/src/notion/new/database/database_property.dart'; import 'package:test/test.dart'; void main() { @@ -41,6 +42,18 @@ void main() { }); group('Notion Pages Client =>', () { + test('Retrieve a page content', () async { + final Client notion = Client(auth: token ?? ''); + NotionResponse res = + await notion.pages.retrieve(page_id: testPageId ?? ''); + + expect(res.status, 200); + expect(res.isPage, true); + expect(res.content, isNotNull); + expect(res.content, isA()); + expect(res.isOk, true); + }); + test('Create a page', () async { final NotionPagesClient pages = NotionPagesClient(auth: token ?? ''); @@ -250,53 +263,39 @@ void main() { expect(res.content.length, lessThanOrEqualTo(limit)); }); - test('Create a database with title', () async { - final NotionDatabasesClient databases = - NotionDatabasesClient(auth: token ?? ''); - - NotionResponse res = await databases.create(Database( - parent: Parent.page(id: testPageId ?? ''), - title: [ - RichText('Database from test'), - ], - properties: Properties(map: { - 'Description': MultiSelectProp(options: [ - MultiSelectOption(name: 'Read', color: ColorsTypes.Blue), - MultiSelectOption(name: 'Sleep', color: ColorsTypes.Green), - ]), - 'Test': DatabaseProperties.Title(), - }), - )); - - expect(res.status, 200); - expect(res.isOk, true); - }); - - test('Create a database without title', () async { - final NotionDatabasesClient databases = - NotionDatabasesClient(auth: token ?? ''); - - NotionResponse res = await databases.create(Database( - parent: Parent.page(id: testPageId ?? ''), - properties: Properties.forDatabase(title: 'Title Column'), - )); + group('Create', () { + test('Create a database with title', () async { + final NotionDatabasesClient databases = + NotionDatabasesClient(auth: token ?? ''); + + NotionResponse res = await databases.create( + pageId: testPageId ?? '', + title: 'Database from test', + properties: DatabaseProperties( + mainColumnName: 'ABC', + properties: { + 'Description': DatabaseProperty.RichText(), + 'Done': DatabaseProperty.Checkbox(), + }, + ), + ); - expect(res.status, 200); - expect(res.isOk, true); - }); + expect(res.status, 200); + expect(res.isOk, true); + }); - test('Create a database with simple constructor', () async { - final NotionDatabasesClient databases = - NotionDatabasesClient(auth: token ?? ''); + test('Create a database without title', () async { + final NotionDatabasesClient databases = + NotionDatabasesClient(auth: token ?? ''); - NotionResponse res = await databases.create(Database.simple( - parent: Parent.page(id: testPageId ?? ''), - title: 'Simple database', - titleColumnName: 'Title Column', - )); + NotionResponse res = await databases.create( + pageId: testPageId ?? '', + properties: DatabaseProperties(mainColumnName: 'Title Column'), + ); - expect(res.status, 200); - expect(res.isOk, true); + expect(res.status, 200); + expect(res.isOk, true); + }); }); test('Update a database', () async { @@ -307,13 +306,13 @@ void main() { databaseId: '8bd452157e1642dd8aad5734a2372518', title: [RichText('New Title')], properties: Properties(map: { - 'Test': DatabaseProperties.MultiSelect( + 'Test': MultiSelectProp( options: [ MultiSelectOption(name: 'Read', color: ColorsTypes.Blue), MultiSelectOption(name: 'Sleep', color: ColorsTypes.Green), ], ), - 'Column': DatabaseProperties.Checkbox(name: 'Ready') + 'Column': RichTextProp() })); print(res.message); @@ -329,6 +328,10 @@ void main() { NotionResponse res = await blocks.list(block_id: testBlockId ?? ''); + res.pagination!.blocks.forEach((element) { + print(element.jsonContent); + }); + expect(res.status, 200); expect(res.isOk, true); }); diff --git a/test/objects/database_test.dart b/test/objects/database_test.dart index 5c4b93d..38a1665 100644 --- a/test/objects/database_test.dart +++ b/test/objects/database_test.dart @@ -1,74 +1,84 @@ -import 'package:notion_api/notion_api.dart'; +import 'package:notion_api/notion_api.dart' hide MultiSelectOption; +import 'package:notion_api/src/notion/new/database/database_property.dart'; import 'package:test/test.dart'; void main() { group('Database Instance =>', () { test('Create new database instance', () { + String title = 'Database title'; Database database = Database( parent: Parent.page(id: 'some_id'), - title: [RichText('Database title')], - properties: Properties(map: { - 'CustomColumName': TitleProp(), - 'Description': RichTextProp(), - }), + title: title, + properties: DatabaseProperties( + mainColumnName: 'CustomColumName', + properties: { + 'Description': DatabaseProperty.RichText(), + }, + ), ); expect(database.parent.type, ParentType.Page); - expect(database.title.length, 1); - expect(database.properties.entries.length, - 2); // pages column name and 'Description' + expect(database.title, title); + expect(database.properties.entries, + isNotEmpty); // pages column name and 'Description' }); test('Create new instance with data', () { Database database = Database.simple( - parent: Parent.none(), - title: 'New Database', - titleColumnName: 'Pages') - .addProperty( - name: 'Tags', - property: MultiSelectProp(options: [ - MultiSelectOption(name: 'Option A'), - MultiSelectOption(name: 'Option B'), - ])) - .addProperty( - name: 'Details', - property: RichTextProp(content: [ - Text('Detail A'), - Text('Detail B'), - ])); + parent: Parent.none(), + title: 'New Database', + mainColumnName: 'Pages'); + + database.addProperty( + name: 'Tags', + property: DatabaseProperty.MultiSelect( + options: [ + MultiSelectOptionDbProp(name: 'Option A'), + MultiSelectOptionDbProp(name: 'Option B'), + ], + ), + ); + + database.addProperty( + name: 'Details', + property: DatabaseProperty.RichText(), + ); expect(database, isNotNull); - expect(database.title.length, 1); - expect(database.properties.entries, isNotEmpty); - expect(database.properties.getByName('Tags').isMultiSelect, true); - expect(database.properties.getByName('Details').isRichText, true); - expect(database.properties.getByName('Pages').isTitle, true); + expect(database.properties.entries.length, 3); + expect(database.properties.getByName('Tags'), isA()); + expect(database.properties.getByName('Details'), isA()); + expect(database.properties.getByName('Pages'), isA()); }); test('Create json from instance', () { - Map database = Database.simple( + Database database = Database.simple( parent: Parent.none(), title: 'Title', - titleColumnName: 'Pages', - ) - .addProperty( - name: 'Tags', - property: MultiSelectProp(options: [ - MultiSelectOption(name: 'Option A'), - MultiSelectOption(name: 'Option B'), - ])) - .addProperty( - name: 'Details', - property: RichTextProp(content: [ - Text('Detail A'), - Text('Detail B'), - ])) - .toJson(); + mainColumnName: 'Pages', + ); - expect(database, isNotNull); - expect(database['object'], 'database'); - expect(database['title'], isList); - expect(database['properties'], isMap); + database.addProperty( + name: 'Tags', + property: DatabaseProperty.MultiSelect( + options: [ + MultiSelectOptionDbProp(name: 'Option A'), + MultiSelectOptionDbProp(name: 'Option B'), + ], + ), + ); + + database.addProperty( + name: 'Details', + property: DatabaseProperty.RichText(), + ); + + Map json = database.toJson(); + + expect(json, isNotNull); + expect(json['object'], 'database'); + expect(json['title'], isList); + expect(json['properties'], isMap); }); test('Map from json', () { @@ -113,9 +123,8 @@ void main() { expect(database.title, isNotEmpty); expect(database.id, isNotEmpty); expect(database.properties.contains('Tags'), true); - expect(database.properties.getByName('Tags').isMultiSelect, true); - expect(database.properties.contains('Details'), true); - expect(database.properties.getByName('Details').isTitle, true); + expect(database.properties.getByName('Tags'), isA()); + expect(database.properties.getByName('Details'), isA()); }); test('Map from wrong json', () { From 9d311728bc69c737ce2d08c9fa7fbf89ab6f7900 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Thu, 24 Feb 2022 12:58:47 -0600 Subject: [PATCH 38/42] Removes prints and adds more expectations for retrieve a database --- test/notion_api_test.dart | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index 9a328c3..4dbf47f 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -216,17 +216,30 @@ void main() { }); group('Notion Databases Client =>', () { - test('Retrieve a database', () async { - final NotionDatabasesClient databases = - NotionDatabasesClient(auth: token ?? ''); + group('Retrieve', () { + test('Retrieve a database', () async { + final NotionDatabasesClient databases = + NotionDatabasesClient(auth: token ?? ''); - NotionResponse res = - await databases.retrieve(databaseId: testDatabaseId ?? ''); + NotionResponse res = + await databases.retrieve(databaseId: testDatabaseId ?? ''); - expect(res.status, 200); - expect(res.isOk, isTrue); - expect(res.isDatabase, isTrue); - expect(res.content, isA()); + /// TODO: Separate test and retrieve database on a `setUp`. + expect(res.status, 200); + expect(res.isOk, isTrue); + expect(res.isDatabase, isTrue); + expect(res.content, isA()); + + // Can read the title + expect(res.database!.title, 'New Title'); + + // Can read properties main column. + expect(res.database!.properties.getByName('This is a test'), + isA()); + + // TODO: Can read multiselect property options + // expect(res.database!.properties.getByName('Tags').options.length, 2); + }); }); test('Retrieve all databases', () async { @@ -315,8 +328,6 @@ void main() { 'Column': RichTextProp() })); - print(res.message); - expect(res.status, 200); expect(res.isOk, true); }); @@ -328,10 +339,6 @@ void main() { NotionResponse res = await blocks.list(block_id: testBlockId ?? ''); - res.pagination!.blocks.forEach((element) { - print(element.jsonContent); - }); - expect(res.status, 200); expect(res.isOk, true); }); From ac8b9083dc6e7909bff9d01d052d272eb92b84ec Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Thu, 24 Feb 2022 13:14:55 -0600 Subject: [PATCH 39/42] Fixes errors on test and DateTime errors --- lib/src/notion/objects/object.dart | 8 +- lib/src/notion/objects/pages.dart | 6 +- test/general_test.dart | 5 +- test/lists/pagination_test.dart | 124 ++++++++++++++++++++--------- test/response_test.dart | 3 +- 5 files changed, 100 insertions(+), 46 deletions(-) diff --git a/lib/src/notion/objects/object.dart b/lib/src/notion/objects/object.dart index 16e559a..373a426 100644 --- a/lib/src/notion/objects/object.dart +++ b/lib/src/notion/objects/object.dart @@ -34,8 +34,12 @@ class Object { Object.fromJson(Map json) : this.object = stringToObjectType(json['object']), this.id = json['id'] ?? '', - this.createdTime = json['created_time'] ?? '', - this.lastEditedTime = json['last_edited_time'] ?? ''; + this.createdTime = json['created_time'] != null + ? DateTime.parse(json['created_time']) + : null, + this.lastEditedTime = json['last_edited_time'] != null + ? DateTime.parse(json['last_edited_time']) + : null; /// Set the [createdTime] and the [lastEditedTime] properties. /// diff --git a/lib/src/notion/objects/pages.dart b/lib/src/notion/objects/pages.dart index 7401b49..f4fa318 100644 --- a/lib/src/notion/objects/pages.dart +++ b/lib/src/notion/objects/pages.dart @@ -101,8 +101,10 @@ class Page extends Object { if (isResponse) { json['object'] = strObject; json['id'] = id; - json['created_time'] = createdTime; - json['last_edited_time'] = lastEditedTime; + if (createdTime != null) + json['created_time'] = createdTime!.toIso8601String(); + if (lastEditedTime != null) + json['last_edited_time'] = lastEditedTime!.toIso8601String(); json['archived'] = archived; } diff --git a/test/general_test.dart b/test/general_test.dart index 1d7704a..90b7d9e 100644 --- a/test/general_test.dart +++ b/test/general_test.dart @@ -15,8 +15,9 @@ void main() { expect(base.object, ObjectTypes.Database); expect(base.id, "386da3c6-46bb-4581-8807-1fdb2fbbf447"); - expect(base.createdTime, "2021-05-19T20:21:11.420Z"); - expect(base.lastEditedTime, "2021-06-07T23:02:00.000Z"); + expect(base.createdTime!.toIso8601String(), "2021-05-19T20:21:11.420Z"); + expect( + base.lastEditedTime!.toIso8601String(), "2021-06-07T23:02:00.000Z"); }); }); } diff --git a/test/lists/pagination_test.dart b/test/lists/pagination_test.dart index 57576c3..aa318c0 100644 --- a/test/lists/pagination_test.dart +++ b/test/lists/pagination_test.dart @@ -23,13 +23,23 @@ void main() { "results": [ { "object": "database", - "id": "386da3c6-46bb-4581-8807-1fdb2fbbf447", - "created_time": "2021-05-19T20:21:11.420Z", - "last_edited_time": "2021-06-07T23:02:00.000Z", + "id": "386da3c6-46bb-4581-8877-1fdb2fbbf447", + "cover": null, + "icon": null, + "created_time": "2021-05-19T20:21:00.000Z", + "created_by": { + "object": "user", + "id": "cfea802c-a071-46ff-ac1f-81713e43d15b" + }, + "last_edited_by": { + "object": "user", + "id": "59457011-46b2-4542-8a0b-2ee2602ee02c" + }, + "last_edited_time": "2022-02-24T06:18:00.000Z", "title": [ { "type": "text", - "text": {"content": "test", "link": null}, + "text": {"content": "New Title", "link": null}, "annotations": { "bold": false, "italic": false, @@ -38,18 +48,24 @@ void main() { "code": false, "color": "default" }, - "plain_text": "test", + "plain_text": "New Title", "href": null } ], "properties": { - "Tags": { - "id": ">cp;", - "type": "multi_select", - "multi_select": {"options": []} - }, - "This is a test": {"id": "title", "type": "title", "title": {}} - } + "Title": { + "id": "title", + "name": "Title", + "type": "title", + "title": {} + } + }, + "parent": { + "type": "page_id", + "page_id": "ba3e9659-1de0-4c93-b3ad-78b9b1de5007" + }, + "url": "https://www.notion.so/386da3c646bb458188071fdb1fbbf447", + "archived": false } ], "next_cursor": null, @@ -67,13 +83,23 @@ void main() { "results": [ { "object": "database", - "id": "386da3c6-46bb-4581-8807-1fdb2fbbf447", - "created_time": "2021-05-19T20:21:11.420Z", - "last_edited_time": "2021-06-07T23:02:00.000Z", + "id": "386da3c6-46bb-4581-8807-1fdb2fbbf446", + "cover": null, + "icon": null, + "created_time": "2021-05-19T20:21:00.000Z", + "created_by": { + "object": "user", + "id": "cfea802c-a071-46ff-ac1f-81713e43d15b" + }, + "last_edited_by": { + "object": "user", + "id": "59457011-46b2-4542-8a0b-2ee2602ee02c" + }, + "last_edited_time": "2022-02-24T06:18:00.000Z", "title": [ { "type": "text", - "text": {"content": "test", "link": null}, + "text": {"content": "New Title", "link": null}, "annotations": { "bold": false, "italic": false, @@ -82,28 +108,44 @@ void main() { "code": false, "color": "default" }, - "plain_text": "test", + "plain_text": "New Title", "href": null } ], "properties": { - "Tags": { - "id": ">cp;", - "type": "multi_select", - "multi_select": {"options": []} - }, - "This is a test": {"id": "title", "type": "title", "title": {}} - } + "Title": { + "id": "title", + "name": "Title", + "type": "title", + "title": {} + } + }, + "parent": { + "type": "page_id", + "page_id": "ba3e9659-1de0-4c93-b3ad-78b9b1de5007" + }, + "url": "https://www.notion.so/386da3c646bb458188071fdb1fbbf448", + "archived": false }, { "object": "database", - "id": "386da3c6-46bb-4581-8807-1fdb2fbbf446", - "created_time": "2021-05-19T20:21:11.420Z", - "last_edited_time": "2021-06-07T23:02:00.000Z", + "id": "386da3c6-46bb-4581-8807-1fdb2fbbf448", + "cover": null, + "icon": null, + "created_time": "2021-05-19T20:21:00.000Z", + "created_by": { + "object": "user", + "id": "cfea802c-a071-46ff-ac1f-81713e43d15b" + }, + "last_edited_by": { + "object": "user", + "id": "59457011-46b2-4542-8a0b-2ee2602ee02c" + }, + "last_edited_time": "2022-02-24T06:18:00.000Z", "title": [ { "type": "text", - "text": {"content": "test", "link": null}, + "text": {"content": "New Title", "link": null}, "annotations": { "bold": false, "italic": false, @@ -112,18 +154,24 @@ void main() { "code": false, "color": "default" }, - "plain_text": "test", + "plain_text": "New Title", "href": null } ], "properties": { - "Tags": { - "id": ">cp;", - "type": "multi_select", - "multi_select": {"options": []} - }, - "This is a test": {"id": "title", "type": "title", "title": {}} - } + "Title": { + "id": "title", + "name": "Title", + "type": "title", + "title": {} + } + }, + "parent": { + "type": "page_id", + "page_id": "ba3e9659-1de0-4c93-b3ad-78b9b1de5007" + }, + "url": "https://www.notion.so/386da3c646bb458188071fdb1fbbf447", + "archived": false } ], "next_cursor": null, @@ -133,9 +181,9 @@ void main() { List exclude = pag .filterDatabases(exclude: ['386da3c6-46bb-4581-8807-1fdb2fbbf446']); List include = pag - .filterDatabases(include: ['386da3c6-46bb-4581-8807-1fdb2fbbf447']); + .filterDatabases(include: ['386da3c6-46bb-4581-8807-1fdb2fbbf448']); List id = - pag.filterDatabases(id: '386da3c6-46bb-4581-8807-1fdb2fbbf447'); + pag.filterDatabases(id: '386da3c6-46bb-4581-8807-1fdb2fbbf448'); expect(exclude.length, lessThan(pag.list.length)); expect(include.length, lessThan(pag.list.length)); diff --git a/test/response_test.dart b/test/response_test.dart index 1150834..664df7a 100644 --- a/test/response_test.dart +++ b/test/response_test.dart @@ -151,8 +151,7 @@ void main() { await db.retrieve(databaseId: testDatabaseId ?? ''); expect(response.isDatabase, true); - expect(response.content.title, allOf([isList, isNotEmpty, hasLength(1)])); - expect(response.content.title.first.text, 'test'); + expect(response.content.title, 'New Title'); expect(response.content.properties.entries, allOf([isMap, isNotEmpty, hasLength(3)])); }); From b1cf99fe048ed18a1e4f22431c94d970b245d25f Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 25 Feb 2022 13:30:21 -0600 Subject: [PATCH 40/42] Adds access to properties with explicit type Adds missing url field from `toJSON` Removes `this` for usage of class member when is obvious Improves database test (logic and style) --- .../new/database/database_property.dart | 88 ++++- lib/src/notion/objects/database.dart | 11 +- test/notion_api_test.dart | 10 +- test/objects/database_test.dart | 340 +++++++++++------- 4 files changed, 299 insertions(+), 150 deletions(-) diff --git a/lib/src/notion/new/database/database_property.dart b/lib/src/notion/new/database/database_property.dart index 125c4be..ef94e77 100644 --- a/lib/src/notion/new/database/database_property.dart +++ b/lib/src/notion/new/database/database_property.dart @@ -12,7 +12,7 @@ class DatabaseProperties extends Properties { Map? properties, }) : super(map: properties) { if (mainColumnName != null) - add(name: mainColumnName, property: DatabaseProperty.Title()); + super.add(name: mainColumnName, property: DatabaseProperty.Title()); } /// Map a new properties instance from a [json] map. @@ -36,6 +36,27 @@ class DatabaseProperties extends Properties { /// A representation of a single property for any Notion object. class DatabaseProperty extends Property { + static TitleDbProp Title({ + String? name, + }) => + TitleDbProp(name: name); + + static RichTextDbProp RichText({ + String? name, + }) => + RichTextDbProp(name: name); + + static MultiSelectDbProp MultiSelect({ + List options: const [], + String? name, + }) => + MultiSelectDbProp(name: name, options: options); + + static CheckboxtDbProp Checkbox({ + String? name, + }) => + CheckboxtDbProp(name: name); + /// The property name. String name; @@ -71,26 +92,41 @@ class DatabaseProperty extends Property { } } - static TitleDbProp Title({ - String? name, - }) => - TitleDbProp(name: name); + /// Returns the property as a Title property. + /// + /// Throws an exception if the property is not of that type or if it has not been implemented from the corresponding property. + TitleDbProp get asTitle { + if (type != PropertiesTypes.Title) + throw 'Cannot convert as Title because property is a ${type}'; + throw 'Not Implemented'; + } - static RichTextDbProp RichText({ - String? name, - }) => - RichTextDbProp(name: name); + /// Returns the property as a RichText property. + /// + /// Throws an exception if the property is not of that type or if it has not been implemented from the corresponding property. + RichTextDbProp get asRichText { + if (type != PropertiesTypes.RichText) + throw 'Cannot convert as RichText because property is a ${type}'; + throw 'Not Implemented'; + } - static MultiSelectDbProp MultiSelect({ - List options: const [], - String? name, - }) => - MultiSelectDbProp(name: name); + /// Returns the property as a MultiSelect property. + /// + /// Throws an exception if the property is not of that type or if it has not been implemented from the corresponding property. + MultiSelectDbProp get asMultiSelect { + if (type != PropertiesTypes.MultiSelect) + throw 'Cannot convert as MultiSelect because property is a ${type}'; + throw 'Not Implemented'; + } - static CheckboxtDbProp Checkbox({ - String? name, - }) => - CheckboxtDbProp(name: name); + /// Returns the property as a Checkbox property. + /// + /// Throws an exception if the property is not of that type or if it has not been implemented from the corresponding property. + CheckboxtDbProp get asCheckbox { + if (type != PropertiesTypes.Checkbox) + throw 'Cannot convert as Checkbox because property is a ${type}'; + throw 'Not Implemented'; + } } class TitleDbProp extends DatabaseProperty { @@ -105,6 +141,10 @@ class TitleDbProp extends DatabaseProperty { name: json['name'], ); + /// Override `asTitle` method from class parent to format specifically to Title. + @override + TitleDbProp get asTitle => this; + /// Get this as a valid json representation for the Notion API. @override Map toJson() => { @@ -127,6 +167,10 @@ class RichTextDbProp extends DatabaseProperty { name: json['name'], ); + /// Override `asRichText` method from class parent to format specifically to RichText. + @override + RichTextDbProp get asRichText => this; + /// Get this as a valid json representation for the Notion API. @override Map toJson() => { @@ -149,6 +193,10 @@ class CheckboxtDbProp extends DatabaseProperty { name: json['name'], ); + /// Override `asCheckbox` method from class parent to format specifically to Checkbox. + @override + CheckboxtDbProp get asCheckbox => this; + /// Get this as a valid json representation for the Notion API. @override Map toJson() => { @@ -181,6 +229,10 @@ class MultiSelectDbProp extends DatabaseProperty { name: json['name'], ); + /// Override `asMultiSelect` method from class parent to format specifically to MultiSelect. + @override + MultiSelectDbProp get asMultiSelect => this; + /// Get this as a valid json representation for the Notion API. @override Map toJson() => { diff --git a/lib/src/notion/objects/database.dart b/lib/src/notion/objects/database.dart index 072deed..e563c75 100644 --- a/lib/src/notion/objects/database.dart +++ b/lib/src/notion/objects/database.dart @@ -71,8 +71,8 @@ class Database extends Object { required this.parent, required String mainColumnName, String? title, - }) : this.url = '', - this.properties = DatabaseProperties(mainColumnName: mainColumnName) { + }) : url = '', + properties = DatabaseProperties(mainColumnName: mainColumnName) { if (title != null) _title.add(RichText(title)); } @@ -113,7 +113,7 @@ class Database extends Object { /// ); /// ``` void addProperty({required String name, required DatabaseProperty property}) { - this.properties.add(name: name, property: property); + properties.add(name: name, property: property); } /// Convert this to a valid json representation for the Notion API. @@ -125,12 +125,13 @@ class Database extends Object { /// Convert this to a valid json representation for the Notion API response. Map toJson() => { - 'object': objectTypeToString(this.object), - 'id': this.id, + 'object': objectTypeToString(object), + 'id': id, 'created_time': createdTime, 'last_edited_by': lastEditedTime, 'title': _title.map((e) => e.toJson()).toList(), 'parent': parent.toJson(), 'properties': properties.toJson(), + 'url': url, }; } diff --git a/test/notion_api_test.dart b/test/notion_api_test.dart index 4dbf47f..10754e5 100644 --- a/test/notion_api_test.dart +++ b/test/notion_api_test.dart @@ -237,8 +237,14 @@ void main() { expect(res.database!.properties.getByName('This is a test'), isA()); - // TODO: Can read multiselect property options - // expect(res.database!.properties.getByName('Tags').options.length, 2); + // Can read multiselect property options + expect( + res.database!.properties + .getByName('Tags') + .asMultiSelect + .options + .length, + 1); }); }); diff --git a/test/objects/database_test.dart b/test/objects/database_test.dart index 38a1665..56cf383 100644 --- a/test/objects/database_test.dart +++ b/test/objects/database_test.dart @@ -4,134 +4,224 @@ import 'package:test/test.dart'; void main() { group('Database Instance =>', () { - test('Create new database instance', () { - String title = 'Database title'; - Database database = Database( - parent: Parent.page(id: 'some_id'), - title: title, - properties: DatabaseProperties( - mainColumnName: 'CustomColumName', - properties: { - 'Description': DatabaseProperty.RichText(), - }, - ), - ); - - expect(database.parent.type, ParentType.Page); - expect(database.title, title); - expect(database.properties.entries, - isNotEmpty); // pages column name and 'Description' + group('Create Instance', () { + group('[Default:', () { + const String title = 'DatabaseTitle'; + + test('new database instance]', () { + Database database = Database( + parent: Parent.page(id: 'someId'), + title: title, + properties: DatabaseProperties( + mainColumnName: 'Main', + properties: { + 'Details': DatabaseProperty.RichText(), + }, + ), + ); + + expect(database.title, title); + expect(database.parent.type, ParentType.Page); + expect(database.properties.entries, + isNotEmpty); // pages column name and 'Details' + }); + }); + + group('[Usage:', () { + test('add individual properties]', () { + Database database = Database.simple( + parent: Parent.page(id: 'someId'), + title: 'DatabaseTitle', + mainColumnName: 'Main', + ); + expect(database.properties.getByName('Main'), isA()); + expect(database.properties.entries.length, 1); + + // add one more property + database.addProperty( + name: 'Tags', + property: DatabaseProperty.MultiSelect( + options: [ + MultiSelectOptionDbProp(name: 'Option A'), + MultiSelectOptionDbProp(name: 'Option B'), + ], + ), + ); + expect( + database.properties.getByName('Tags'), isA()); + expect(database.properties.entries.length, 2); + + // add one more property + database.addProperty( + name: 'Details', + property: DatabaseProperty.RichText(), + ); + expect( + database.properties.getByName('Details'), isA()); + + expect(database.properties.entries.length, 3); + }); + + test('access database properties with type]', () { + var multiSelectOptions = [ + MultiSelectOptionDbProp(name: 'TagA'), + MultiSelectOptionDbProp(name: 'TagB'), + MultiSelectOptionDbProp(name: 'TagC'), + ]; + + Database database = Database( + parent: Parent.page(id: 'someId'), + title: 'DatabaseTitle', + properties: DatabaseProperties( + mainColumnName: 'Main', + properties: { + 'Tags': DatabaseProperty.MultiSelect( + options: [...multiSelectOptions], + ), + }, + ), + ); + + expect(database.parent.type, ParentType.Page); + expect(database.properties.getByName('Tags').asMultiSelect.options, + equals(multiSelectOptions)); // pages column name and 'Details' + }); + + test('create json for request]', () { + Database database = Database( + parent: Parent.page(id: 'someId'), + title: 'DatabaseTitle', + properties: DatabaseProperties( + mainColumnName: 'Main', + properties: { + 'Details': DatabaseProperty.RichText(), + }, + ), + ); + + Map json = database.toRequestJson(); + + expect(json, isNotNull); + + // required + expect(json['parent'], allOf([isMap, isNotEmpty])); + expect(json['title'], allOf([isList, isNotEmpty])); + expect(json['properties'], allOf([isMap, isNotEmpty])); + + // not required + expect(json.containsKey('id'), isFalse); + expect(json.containsKey('url'), isFalse); + }); + + test('create full json]', () { + Database database = Database( + parent: Parent.page(id: 'someId'), + title: 'DatabaseTitle', + properties: DatabaseProperties( + mainColumnName: 'Main', + properties: { + 'Details': DatabaseProperty.RichText(), + }, + ), + ); + + Map json = database.toJson(); + + expect(json, isNotNull); + expect(json['object'], 'database'); + expect(json['title'], isList); + expect(json['properties'], isNotEmpty); + expect(json['id'], isEmpty); + expect(json['url'], isEmpty); + }); + }); }); - test('Create new instance with data', () { - Database database = Database.simple( - parent: Parent.none(), - title: 'New Database', - mainColumnName: 'Pages'); - - database.addProperty( - name: 'Tags', - property: DatabaseProperty.MultiSelect( - options: [ - MultiSelectOptionDbProp(name: 'Option A'), - MultiSelectOptionDbProp(name: 'Option B'), - ], - ), - ); - - database.addProperty( - name: 'Details', - property: DatabaseProperty.RichText(), - ); - - expect(database, isNotNull); - expect(database.properties.entries.length, 3); - expect(database.properties.getByName('Tags'), isA()); - expect(database.properties.getByName('Details'), isA()); - expect(database.properties.getByName('Pages'), isA()); - }); - - test('Create json from instance', () { - Database database = Database.simple( - parent: Parent.none(), - title: 'Title', - mainColumnName: 'Pages', - ); - - database.addProperty( - name: 'Tags', - property: DatabaseProperty.MultiSelect( - options: [ - MultiSelectOptionDbProp(name: 'Option A'), - MultiSelectOptionDbProp(name: 'Option B'), - ], - ), - ); - - database.addProperty( - name: 'Details', - property: DatabaseProperty.RichText(), - ); - - Map json = database.toJson(); - - expect(json, isNotNull); - expect(json['object'], 'database'); - expect(json['title'], isList); - expect(json['properties'], isMap); - }); - - test('Map from json', () { - var jsonDatabase = { - "object": "database", - "id": "386da3c6-46bb-4581-8807-1fdb2fbbf447", - "created_time": "2021-05-19T20:21:11.420Z", - "last_edited_time": "2021-06-07T23:02:00.000Z", - "title": [ - { - "type": "text", - "text": {"content": "test", "link": null}, - "annotations": { - "bold": false, - "italic": false, - "strikethrough": false, - "underline": false, - "code": false, - "color": "default" + group('Read from JSON', () { + group('[Mapping:', () { + String title = 'test'; + late Database database; + setUp(() { + database = Database.fromJson({ + "object": "database", + "id": "386da3c6-46bb-4581-8807-1fdb2fbbf447", + "created_time": "2021-05-19T20:21:11.420Z", + "last_edited_time": "2021-06-07T23:02:00.000Z", + "title": [ + { + "type": "text", + "text": {"content": title, "link": null}, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "test", + "href": null + } + ], + "properties": { + "Tags": { + "id": ">cp;", + "type": "multi_select", + "multi_select": {"options": []} + }, + "Details": {"id": "title", "type": "title", "title": {}} }, - "plain_text": "test", - "href": null - } - ], - "properties": { - "Tags": { - "id": ">cp;", - "type": "multi_select", - "multi_select": {"options": []} - }, - "Details": {"id": "title", "type": "title", "title": {}} - }, - "parent": { - "type": "page_id", - "page_id": "ba3e9659-1de0-4c93-b3ad-78b9b16e5507" - }, - "url": "https://www.notion.so/8bd452157e1642dd8aad5734a2372518", - }; - - Database database = Database.fromJson(jsonDatabase); - - expect(database.title, isNotEmpty); - expect(database.id, isNotEmpty); - expect(database.properties.contains('Tags'), true); - expect(database.properties.getByName('Tags'), isA()); - expect(database.properties.getByName('Details'), isA()); - }); - - test('Map from wrong json', () { - Map wrongJsonDatabase = {}; - - expect(() => Database.fromJson(wrongJsonDatabase), - throwsA(isA())); + "parent": { + "type": "page_id", + "page_id": "ba3e9659-1de0-4c93-b3ad-78b9b16e5507" + }, + "url": "https://www.notion.so/8bd452157e1642dd8aad5734a2372518", + }); + }); + + test('Map full json]', () { + expect(database.title, isNotEmpty); + expect(database.id, isNotEmpty); + expect(database.properties.entries, isNotEmpty); + expect(Uri.tryParse(database.url)?.hasAbsolutePath ?? false, isTrue); + expect(database.properties.contains('Tags'), isTrue); + expect(database.properties.contains('Details'), isTrue); + }); + + test('get database title]', () { + expect(database.title, title); + }); + + test('get database properties]', () { + expect( + database.properties.getByName('Tags'), isA()); + expect( + database.properties.getByName('Tags'), isA()); + expect(database.properties.getByName('Details'), isA()); + }); + + test('access specific properties with type]', () { + expect(database.properties.getByName('Tags').asMultiSelect.options, + isList); + }); + }); + + group('[Throw exception:', () { + test('for empty json]', () { + expect(() => Database.fromJson({}), throwsA(isA())); + }); + + test('for null required value]', () { + expect( + () => Database.fromJson({ + "object": "database", + "id": "386da3c6-46bb-4581-8807-1fdb2fbbf447", + "created_time": "2021-05-19T20:21:11.420Z", + "last_edited_time": "2021-06-07T23:02:00.000Z", + }), + throwsA(isA())); + }); + }); }); }); } From b1cba995273214414b014c40c5e89ba3b56bcad8 Mon Sep 17 00:00:00 2001 From: jonathangomz Date: Fri, 25 Feb 2022 13:34:20 -0600 Subject: [PATCH 41/42] Improves docs for `add` property --- lib/src/notion/new/properties.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/notion/new/properties.dart b/lib/src/notion/new/properties.dart index 3da9902..f89afba 100644 --- a/lib/src/notion/new/properties.dart +++ b/lib/src/notion/new/properties.dart @@ -12,6 +12,8 @@ class Properties { } /// Add a new [property] with a specific [name]. + /// + /// If there is a current entry with that [name], the new [property] will overwrite the other value. void add({required String name, required T property}) { this.entries[name] = property; } From e4bfacfbcbbadccf924bc66219c7d30c79781057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20G=C3=B3mez?= Date: Fri, 11 Aug 2023 13:02:09 -0600 Subject: [PATCH 42/42] Updates colon for equal for default parameters And updates sdk version --- lib/notion_api.dart | 4 +- lib/src/notion/general/property.dart | 8 +- lib/src/notion/lists/children.dart | 6 +- lib/src/notion/lists/pagination.dart | 12 +- lib/src/notion/lists/properties.dart | 4 +- .../new/database/database_property.dart | 6 +- lib/src/notion/objects/block.dart | 8 +- .../objects/blocks/bulleted_list_item.dart | 6 +- lib/src/notion/objects/blocks/heading.dart | 6 +- .../objects/blocks/numbered_list_item.dart | 6 +- lib/src/notion/objects/blocks/paragraph.dart | 6 +- lib/src/notion/objects/blocks/todo.dart | 10 +- lib/src/notion/objects/blocks/toggle.dart | 6 +- lib/src/notion/objects/object.dart | 4 +- lib/src/notion/objects/pages.dart | 6 +- lib/src/notion/rich_text.dart | 52 +++--- lib/src/notion_blocks.dart | 4 +- lib/src/notion_databases.dart | 4 +- lib/src/notion_pages.dart | 4 +- lib/src/responses/notion_response.dart | 4 +- pubspec.lock | 152 ++++++++++++------ 21 files changed, 184 insertions(+), 134 deletions(-) diff --git a/lib/notion_api.dart b/lib/notion_api.dart index 26364b7..1e2c4c4 100644 --- a/lib/notion_api.dart +++ b/lib/notion_api.dart @@ -40,8 +40,8 @@ class Client { /// This class is used as the main entry point for all clients. From the instances of this class any other client can be used. Client({ required String auth, - String version: latestVersion, - String dateVersion: latestDateVersion, + String version = latestVersion, + String dateVersion = latestDateVersion, }) : this.pages = NotionPagesClient( auth: auth, version: version, dateVersion: dateVersion), this.databases = NotionDatabasesClient( diff --git a/lib/src/notion/general/property.dart b/lib/src/notion/general/property.dart index 37194ef..7bea6ef 100644 --- a/lib/src/notion/general/property.dart +++ b/lib/src/notion/general/property.dart @@ -115,7 +115,7 @@ class TitleProp extends Property { /// Main title property constructor. /// /// Can receive a list ot texts as the title [content]. - TitleProp({this.content: const [], this.name}); + TitleProp({this.content = const [], this.name}); /// Create a new property instance from json. /// @@ -164,7 +164,7 @@ class RichTextProp extends Property { /// Main RichText constructor. /// /// Can receive the [content] as a list of texts. - RichTextProp({this.content: const []}); + RichTextProp({this.content = const []}); /// Create a new rich text instance from json. /// @@ -207,7 +207,7 @@ class MultiSelectProp extends Property { /// /// Can receive the list6 of the options. MultiSelectProp({ - this.options: const [], + this.options = const [], String? name, }) : super(name: name); @@ -257,7 +257,7 @@ class MultiSelectOption { /// /// Required the [name] field to display a text for the option. Also can receive the [id] and the [color] of the option. MultiSelectOption( - {required this.name, this.id, this.color: ColorsTypes.Default}); + {required this.name, this.id, this.color = ColorsTypes.Default}); /// Create a new multi select instance from json. /// diff --git a/lib/src/notion/lists/children.dart b/lib/src/notion/lists/children.dart index 1b9918e..354d7c1 100644 --- a/lib/src/notion/lists/children.dart +++ b/lib/src/notion/lists/children.dart @@ -17,7 +17,7 @@ class Children { /// Main children constructor. /// /// Can receive a list of [blocks]. - Children({List blocks: const []}) { + Children({List blocks = const []}) { this._blocks.addAll(blocks); } @@ -55,8 +55,8 @@ class Children { /// /// If all fields are included then all filters are applied as a chain following the next order: [exclude], [include], [onlyLeft], and the [id]. List filterBlocks({ - List exclude: const [], - List include: const [], + List exclude = const [], + List include = const [], BlockTypes? onlyLeft, String? id, }) { diff --git a/lib/src/notion/lists/pagination.dart b/lib/src/notion/lists/pagination.dart index b4c193b..09a91a9 100644 --- a/lib/src/notion/lists/pagination.dart +++ b/lib/src/notion/lists/pagination.dart @@ -47,8 +47,8 @@ class Pagination { /// Can receive the [nextCursor], if [hasMore] pages, if [isEmpty] and the corresponding list: [blocks], [databases] or [pages]. Pagination({ this.nextCursor, - this.hasMore: false, - this.isEmpty: false, + this.hasMore = false, + this.isEmpty = false, List? blocks, List? databases, }); @@ -90,8 +90,8 @@ class Pagination { /// /// If all fields are included then all filters are applied as a chain following the next order: [exclude], [include], [onlyLeft], and the [id]. List filterBlocks({ - List exclude: const [], - List include: const [], + List exclude = const [], + List include = const [], BlockTypes? onlyLeft, String? id, }) { @@ -118,8 +118,8 @@ class Pagination { /// /// If all fields are included then all filters are applied as a chain following the next order: [exclude], [include], and the [id]. List filterDatabases({ - List exclude: const [], - List include: const [], + List exclude = const [], + List include = const [], String? id, }) { List filetered = []; diff --git a/lib/src/notion/lists/properties.dart b/lib/src/notion/lists/properties.dart index 1ae781a..79d4a07 100644 --- a/lib/src/notion/lists/properties.dart +++ b/lib/src/notion/lists/properties.dart @@ -13,7 +13,7 @@ class Properties { /// Main properties constructor. /// /// Can receive a properties [map]. - Properties({Map map: const {}}) { + Properties({Map map = const {}}) { this._map.addAll(map); } @@ -22,7 +22,7 @@ class Properties { /// Can receive a properties [map]. Properties.forDatabase({ required String title, - Map map: const {}, + Map map = const {}, }) { _map[title] = TitleProp(); _map.addAll(map); diff --git a/lib/src/notion/new/database/database_property.dart b/lib/src/notion/new/database/database_property.dart index ef94e77..0ad9225 100644 --- a/lib/src/notion/new/database/database_property.dart +++ b/lib/src/notion/new/database/database_property.dart @@ -47,7 +47,7 @@ class DatabaseProperty extends Property { RichTextDbProp(name: name); static MultiSelectDbProp MultiSelect({ - List options: const [], + List options = const [], String? name, }) => MultiSelectDbProp(name: name, options: options); @@ -214,7 +214,7 @@ class MultiSelectDbProp extends DatabaseProperty { List options; MultiSelectDbProp({ - this.options: const [], + this.options = const [], String? name, }) : super(name: name); @@ -262,7 +262,7 @@ class MultiSelectOptionDbProp { MultiSelectOptionDbProp({ required this.name, this.id, - this.color: ColorsTypes.Default, + this.color = ColorsTypes.Default, }); /// Create a new multi select instance from json. diff --git a/lib/src/notion/objects/block.dart b/lib/src/notion/objects/block.dart index f4ff3fd..5a13342 100644 --- a/lib/src/notion/objects/block.dart +++ b/lib/src/notion/objects/block.dart @@ -57,10 +57,10 @@ class Block extends Object { /// /// Also can receive the [createdTime] and the [lastEditedTime] of the block in case that the information is filled from response. Block({ - this.id: '', - this.hasChildren: false, - this.jsonContent: const {}, - this.type: BlockTypes.None, + this.id = '', + this.hasChildren = false, + this.jsonContent = const {}, + this.type = BlockTypes.None, DateTime? createdTime, DateTime? lastEditedTime, }) { diff --git a/lib/src/notion/objects/blocks/bulleted_list_item.dart b/lib/src/notion/objects/blocks/bulleted_list_item.dart index 91e85c9..faa90e9 100644 --- a/lib/src/notion/objects/blocks/bulleted_list_item.dart +++ b/lib/src/notion/objects/blocks/bulleted_list_item.dart @@ -22,8 +22,8 @@ class BulletedListItem extends Block { /// Can receive a single [text] or a list of [texts]. If both are included also both fields are added to the heading content adding first the [text] field. Also can receive the [children] of the block. BulletedListItem({ Text? text, - List texts: const [], - List children: const [], + List texts = const [], + List children = const [], }) { this._content.addAll([ if (text != null) text, @@ -40,7 +40,7 @@ class BulletedListItem extends Block { BulletedListItem.text( String content, { TextAnnotations? annotations, - List children: const [], + List children = const [], }) : this._content = [Text(content, annotations: annotations)], this._children = children; diff --git a/lib/src/notion/objects/blocks/heading.dart b/lib/src/notion/objects/blocks/heading.dart index ac66bbb..c859042 100644 --- a/lib/src/notion/objects/blocks/heading.dart +++ b/lib/src/notion/objects/blocks/heading.dart @@ -20,8 +20,8 @@ class Heading extends Block { /// Also can receive the [type] of the heading as an integer between 1 and 3. Set to 1 by default when no specified or when is out of the range declared before. Heading({ Text? text, - List texts: const [], - int type: 1, + List texts = const [], + int type = 1, }) : this.type = headingTypeFromInt(type) { this._content.addAll([ if (text != null) text, @@ -37,7 +37,7 @@ class Heading extends Block { Heading.text( String content, { TextAnnotations? annotations, - int type: 1, + int type = 1, }) : this._content = [Text(content, annotations: annotations)], this.type = headingTypeFromInt(type); diff --git a/lib/src/notion/objects/blocks/numbered_list_item.dart b/lib/src/notion/objects/blocks/numbered_list_item.dart index 240c7a0..f5aa2c6 100644 --- a/lib/src/notion/objects/blocks/numbered_list_item.dart +++ b/lib/src/notion/objects/blocks/numbered_list_item.dart @@ -22,8 +22,8 @@ class NumberedListItem extends Block { /// Can receive a single [text] or a list of [texts]. If both are included also both fields are added to the heading content adding first the [text] field. Also can receive the [children] of the block. NumberedListItem({ Text? text, - List texts: const [], - List children: const [], + List texts = const [], + List children = const [], }) { this._content.addAll([ if (text != null) text, @@ -40,7 +40,7 @@ class NumberedListItem extends Block { NumberedListItem.text( String content, { TextAnnotations? annotations, - List children: const [], + List children = const [], }) : this._content = [Text(content, annotations: annotations)], this._children = children; diff --git a/lib/src/notion/objects/blocks/paragraph.dart b/lib/src/notion/objects/blocks/paragraph.dart index 96a3e62..6fce98b 100644 --- a/lib/src/notion/objects/blocks/paragraph.dart +++ b/lib/src/notion/objects/blocks/paragraph.dart @@ -22,8 +22,8 @@ class Paragraph extends Block { /// Can receive a single [text] or a list of [texts]. If both are included also both fields are added to the heading content adding first the [text] field. Also can receive the [children] of the block. Paragraph({ Text? text, - List texts: const [], - List children: const [], + List texts = const [], + List children = const [], }) { this._content.addAll([ if (text != null) text, @@ -40,7 +40,7 @@ class Paragraph extends Block { Paragraph.text( String content, { TextAnnotations? annotations, - List children: const [], + List children = const [], }) : this._content = [Text(content, annotations: annotations)], this._children = children; diff --git a/lib/src/notion/objects/blocks/todo.dart b/lib/src/notion/objects/blocks/todo.dart index c783656..fed5df2 100644 --- a/lib/src/notion/objects/blocks/todo.dart +++ b/lib/src/notion/objects/blocks/todo.dart @@ -27,9 +27,9 @@ class ToDo extends Block { /// The [checked] field define if the To do option is marked as done. By default is false. ToDo({ Text? text, - List texts: const [], - List children: const [], - this.checked: false, + List texts = const [], + List children = const [], + this.checked = false, }) { this._content.addAll([ if (text != null) text, @@ -46,8 +46,8 @@ class ToDo extends Block { ToDo.text( String content, { TextAnnotations? annotations, - List children: const [], - this.checked: false, + List children = const [], + this.checked = false, }) : this._content = [Text(content, annotations: annotations)], this._children = children; diff --git a/lib/src/notion/objects/blocks/toggle.dart b/lib/src/notion/objects/blocks/toggle.dart index 8e8e810..7ca32f0 100644 --- a/lib/src/notion/objects/blocks/toggle.dart +++ b/lib/src/notion/objects/blocks/toggle.dart @@ -22,8 +22,8 @@ class Toggle extends Block { /// Can receive a single [text] or a list of [texts]. If both are included also both fields are added to the heading content adding first the [text] field. Also can receive the [children] of the block. Toggle({ Text? text, - List texts: const [], - List children: const [], + List texts = const [], + List children = const [], }) { this._content.addAll([ if (text != null) text, @@ -40,7 +40,7 @@ class Toggle extends Block { Toggle.text( String content, { TextAnnotations? annotations, - List children: const [], + List children = const [], }) : this._content = [Text(content, annotations: annotations)], this._children = children; diff --git a/lib/src/notion/objects/object.dart b/lib/src/notion/objects/object.dart index 373a426..7798959 100644 --- a/lib/src/notion/objects/object.dart +++ b/lib/src/notion/objects/object.dart @@ -24,8 +24,8 @@ class Object { /// /// **Note:** This class is mainly (if no only) used by extending it. Object({ - this.object: ObjectTypes.Object, - this.id: '', + this.object = ObjectTypes.Object, + this.id = '', DateTime? this.createdTime, DateTime? this.lastEditedTime, }); diff --git a/lib/src/notion/objects/pages.dart b/lib/src/notion/objects/pages.dart index f4fa318..0954af7 100644 --- a/lib/src/notion/objects/pages.dart +++ b/lib/src/notion/objects/pages.dart @@ -32,9 +32,9 @@ class Page extends Object { /// for when a new page is created. Page({ required this.parent, - this.archived: false, + this.archived = false, this.children, - String id: '', + String id = '', Text? title, }) { this.id = id; @@ -91,7 +91,7 @@ class Page extends Object { } /// Convert this to a json representation valid for the Notion API. - Map toJson({bool isResponse: false}) { + Map toJson({bool isResponse = false}) { Map json = { 'parent': this.parent.toJson(), 'properties': this.properties.toJson(), diff --git a/lib/src/notion/rich_text.dart b/lib/src/notion/rich_text.dart index 4bbfea4..6b558c0 100644 --- a/lib/src/notion/rich_text.dart +++ b/lib/src/notion/rich_text.dart @@ -24,7 +24,7 @@ class Text { /// Only can receive the [text] itself and the [color]. Text.bold( this.text, { - ColorsTypes color: ColorsTypes.Default, + ColorsTypes color = ColorsTypes.Default, }) : this.annotations = TextAnnotations(bold: true, color: color); /// Text constructor with _italic_ content by default. @@ -32,7 +32,7 @@ class Text { /// Only can receive the [text] itself and the [color]. Text.italic( this.text, { - ColorsTypes color: ColorsTypes.Default, + ColorsTypes color = ColorsTypes.Default, }) : this.annotations = TextAnnotations(italic: true, color: color); /// Text constructor with `code` content by default. @@ -40,7 +40,7 @@ class Text { /// Only can receive the [text] itself and the [color]. Text.code( this.text, { - ColorsTypes color: ColorsTypes.Default, + ColorsTypes color = ColorsTypes.Default, }) : this.annotations = TextAnnotations(code: true, color: color); /// Text constructor with underline content by default. @@ -48,7 +48,7 @@ class Text { /// Only can receive the [text] itself and the [color]. Text.underline( this.text, { - ColorsTypes color: ColorsTypes.Default, + ColorsTypes color = ColorsTypes.Default, }) : this.annotations = TextAnnotations(underline: true, color: color); /// Text constructor to change the default color of a text. @@ -56,7 +56,7 @@ class Text { /// Only can receive the [text] itself and the [color]. Text.color( this.text, { - ColorsTypes color: ColorsTypes.Default, + ColorsTypes color = ColorsTypes.Default, }) : this.annotations = TextAnnotations(color: color); /// Text mapper for lists. @@ -100,8 +100,8 @@ class Text { /// ``` static List list({ required List texts, - String separator: ', ', - String lastSeparator: ' and ', + String separator = ', ', + String lastSeparator = ' and ', }) { List list = []; texts.asMap().forEach((index, element) { @@ -190,12 +190,12 @@ class TextAnnotations { /// /// Valid colors are defined by the Colors enum. By default the color type is... Default dah. TextAnnotations({ - this.bold: false, - this.italic: false, - this.strikethrough: false, - this.underline: false, - this.code: false, - this.color: ColorsTypes.Default, + this.bold = false, + this.italic = false, + this.strikethrough = false, + this.underline = false, + this.code = false, + this.color = ColorsTypes.Default, }); /// Create a new text annotation instance from json. @@ -258,7 +258,7 @@ class RichText { /// Only can receive the [text] itself and the [color]. RichText.bold( this.text, { - ColorsTypes color: ColorsTypes.Default, + ColorsTypes color = ColorsTypes.Default, }) : this.annotations = TextAnnotations(bold: true, color: color); /// Text constructor with _italic_ content by default. @@ -266,7 +266,7 @@ class RichText { /// Only can receive the [text] itself and the [color]. RichText.italic( this.text, { - ColorsTypes color: ColorsTypes.Default, + ColorsTypes color = ColorsTypes.Default, }) : this.annotations = TextAnnotations(italic: true, color: color); /// Text constructor with `code` content by default. @@ -274,7 +274,7 @@ class RichText { /// Only can receive the [text] itself and the [color]. RichText.code( this.text, { - ColorsTypes color: ColorsTypes.Default, + ColorsTypes color = ColorsTypes.Default, }) : this.annotations = TextAnnotations(code: true, color: color); /// Text constructor with underline content by default. @@ -282,7 +282,7 @@ class RichText { /// Only can receive the [text] itself and the [color]. RichText.underline( this.text, { - ColorsTypes color: ColorsTypes.Default, + ColorsTypes color = ColorsTypes.Default, }) : this.annotations = TextAnnotations(underline: true, color: color); /// Text constructor to change the default color of a text. @@ -290,7 +290,7 @@ class RichText { /// Only can receive the [text] itself and the [color]. RichText.color( this.text, { - ColorsTypes color: ColorsTypes.Default, + ColorsTypes color = ColorsTypes.Default, }) : this.annotations = TextAnnotations(color: color); /// Text mapper for lists. @@ -334,8 +334,8 @@ class RichText { /// ``` static List list({ required List texts, - String separator: ', ', - String lastSeparator: ' and ', + String separator = ', ', + String lastSeparator = ' and ', }) { List list = []; texts.asMap().forEach((index, element) { @@ -424,12 +424,12 @@ class RichTextAnnotations { /// /// Valid colors are defined by the Colors enum. By default the color type is... Default dah. RichTextAnnotations({ - this.bold: false, - this.italic: false, - this.strikethrough: false, - this.underline: false, - this.code: false, - this.color: ColorsTypes.Default, + this.bold = false, + this.italic = false, + this.strikethrough = false, + this.underline = false, + this.code = false, + this.color = ColorsTypes.Default, }); /// Create a new text annotation instance from json. diff --git a/lib/src/notion_blocks.dart b/lib/src/notion_blocks.dart index b8362f0..d424c3d 100644 --- a/lib/src/notion_blocks.dart +++ b/lib/src/notion_blocks.dart @@ -27,8 +27,8 @@ class NotionBlockClient { /// Require the [auth] token to authenticate the requests, and the API [version] where to make the calls, which is the latests by default (v1). Also can receive the [dateVersion], which is by default "2021-05-13". NotionBlockClient({ required String auth, - String version: latestVersion, - String dateVersion: latestDateVersion, + String version = latestVersion, + String dateVersion = latestDateVersion, }) : this._token = auth, this._v = version, this._dateVersion = dateVersion; diff --git a/lib/src/notion_databases.dart b/lib/src/notion_databases.dart index d49a42a..1b1d67b 100644 --- a/lib/src/notion_databases.dart +++ b/lib/src/notion_databases.dart @@ -28,8 +28,8 @@ class NotionDatabasesClient { /// Require the [auth] token to authenticate the requests, and the API [version] where to make the calls, which is the latests by default (v1). Also can receive the [dateVersion], which is by default "2021-05-13". NotionDatabasesClient({ required String auth, - String version: latestVersion, - String dateVersion: latestDateVersion, + String version = latestVersion, + String dateVersion = latestDateVersion, }) : this._token = auth, this._v = version, this._dateVersion = dateVersion; diff --git a/lib/src/notion_pages.dart b/lib/src/notion_pages.dart index a4fdf43..d0fb88e 100644 --- a/lib/src/notion_pages.dart +++ b/lib/src/notion_pages.dart @@ -27,8 +27,8 @@ class NotionPagesClient { /// Require the [auth] token to authenticate the requests, and the API [version] where to make the calls, which is the latests by default (v1). Also can receive the [dateVersion], which is by default "2021-05-13". NotionPagesClient({ required String auth, - String version: latestVersion, - String dateVersion: latestDateVersion, + String version = latestVersion, + String dateVersion = latestDateVersion, }) : this._token = auth, this._v = version, this._dateVersion = dateVersion; diff --git a/lib/src/responses/notion_response.dart b/lib/src/responses/notion_response.dart index 311ac7d..74d1ab6 100644 --- a/lib/src/responses/notion_response.dart +++ b/lib/src/responses/notion_response.dart @@ -70,8 +70,8 @@ class NotionResponse { /// /// By default the [object] type is None and the [status] is zero. NotionResponse({ - this.object: ObjectTypes.None, - this.status: 0, + this.object = ObjectTypes.None, + this.status = 0, this.code, this.message, }); diff --git a/pubspec.lock b/pubspec.lock index 9101701..2714d64 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,351 +5,401 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - url: "https://pub.dartlang.org" + sha256: d93b0378aadce9c1388108067946276582c2ae89426c64c17920c74988508fed + url: "https://pub.dev" source: hosted version: "22.0.0" analyzer: dependency: transitive description: name: analyzer - url: "https://pub.dartlang.org" + sha256: "90d0daecd576ee4afe1a67d7fe0fef70cc08cb4cb87423e7a5a8770eabd3ee9f" + url: "https://pub.dev" source: hosted version: "1.7.1" args: dependency: transitive description: name: args - url: "https://pub.dartlang.org" + sha256: ad180a697bf97dd54ab519a4665c57683bf4f70649a18671cea661cf0397c055 + url: "https://pub.dev" source: hosted version: "2.1.0" async: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: "6eda8392a48ae1de7ea438c91a4ba3e77205f043e7013102a424863aa6db368f" + url: "https://pub.dev" source: hosted version: "2.5.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "5bbf32bc9e518d41ec49718e2931cd4527292c9b0c6d2dffcf7fe6b9a8a8cf72" + url: "https://pub.dev" source: hosted version: "2.1.0" charcode: dependency: transitive description: name: charcode - url: "https://pub.dartlang.org" + sha256: "8e36feea6de5ea69f2199f29cf42a450a855738c498b57c0b980e2d3cca9c362" + url: "https://pub.dev" source: hosted version: "1.2.0" cli_util: dependency: transitive description: name: cli_util - url: "https://pub.dartlang.org" + sha256: cf1c02840bbbcf8fcd13feb5933c62d643cc58ddf4f6088707cf48d1892cbc5d + url: "https://pub.dev" source: hosted version: "0.3.0" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: "6d4193120997ecfd09acf0e313f13dc122b119e5eca87ef57a7d065ec9183762" + url: "https://pub.dev" source: hosted version: "1.15.0" convert: dependency: transitive description: name: convert - url: "https://pub.dartlang.org" + sha256: df567b950053d83b4dba3e8c5799c411895d146f82b2147114b666a4fd9a80dd + url: "https://pub.dev" source: hosted version: "3.0.0" coverage: dependency: transitive description: name: coverage - url: "https://pub.dartlang.org" + sha256: ad538fa2e8f6b828d54c04a438af816ce814de404690136d3b9dfb3a436cd01c + url: "https://pub.dev" source: hosted version: "1.0.3" crypto: dependency: transitive description: name: crypto - url: "https://pub.dartlang.org" + sha256: cf75650c66c0316274e21d7c43d3dea246273af5955bd94e8184837cd577575c + url: "https://pub.dev" source: hosted version: "3.0.1" dotenv: dependency: "direct dev" description: name: dotenv - url: "https://pub.dartlang.org" + sha256: dc4c91d8d5e9e361803fc81e8ea7ba0f35be483b656837ea6b9a3c41df308c68 + url: "https://pub.dev" source: hosted version: "3.0.0" file: dependency: transitive description: name: file - url: "https://pub.dartlang.org" + sha256: bbbe4cbd826c19385c87dcb11d07af2b26c98ac9ed94c1cd65172818570e25b2 + url: "https://pub.dev" source: hosted version: "6.1.1" frontend_server_client: dependency: transitive description: name: frontend_server_client - url: "https://pub.dartlang.org" + sha256: "780784ec9e9362ed5278272d39b6590474dba495483ec97eba31df4d23622fa0" + url: "https://pub.dev" source: hosted version: "2.1.0" glob: dependency: transitive description: name: glob - url: "https://pub.dartlang.org" + sha256: dda85ce2aefce16f7e75586acbcb1e8320bf176f69fd94082e31945d6de67f3e + url: "https://pub.dev" source: hosted version: "2.0.1" http: dependency: "direct main" description: name: http - url: "https://pub.dartlang.org" + sha256: b6f1f143a71e1fe1b34670f1acd6f13960ade2557c96b87e127e0cf661969791 + url: "https://pub.dev" source: hosted version: "0.13.3" http_multi_server: dependency: transitive description: name: http_multi_server - url: "https://pub.dartlang.org" + sha256: bfb651625e251a88804ad6d596af01ea903544757906addcb2dcdf088b5ea185 + url: "https://pub.dev" source: hosted version: "3.0.1" http_parser: dependency: transitive description: name: http_parser - url: "https://pub.dartlang.org" + sha256: e362d639ba3bc07d5a71faebb98cde68c05bfbcfbbb444b60b6f60bb67719185 + url: "https://pub.dev" source: hosted version: "4.0.0" io: dependency: transitive description: name: io - url: "https://pub.dartlang.org" + sha256: "15a5436d2a02dc60e6dc2fb5d7dfaac08b7b137cff3d4bf3158d38ecab656b69" + url: "https://pub.dev" source: hosted version: "1.0.0" js: dependency: transitive description: name: js - url: "https://pub.dartlang.org" + sha256: d9bdfd70d828eeb352390f81b18d6a354ef2044aa28ef25682079797fa7cd174 + url: "https://pub.dev" source: hosted version: "0.6.3" logging: dependency: transitive description: name: logging - url: "https://pub.dartlang.org" + sha256: "0520a4826042a8a5d09ddd4755623a50d37ee536d79a70452aff8c8ad7bb6c27" + url: "https://pub.dev" source: hosted version: "1.0.1" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "38c7be344ac5057e10161a5ecb00c9d9d67ed2f150001278601dd27d9fe64206" + url: "https://pub.dev" source: hosted version: "0.12.10" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "98a7492d10d7049ea129fd4e50f7cdd2d5008522b1dfa1148bbbc542b9dd21f7" + url: "https://pub.dev" source: hosted version: "1.3.0" mime: dependency: transitive description: name: mime - url: "https://pub.dartlang.org" + sha256: a7a98ea7f366e2cc9d2b20873815aebec5e2bc124fe0da9d3f7f59b0625ea180 + url: "https://pub.dev" source: hosted version: "1.0.0" node_preamble: dependency: transitive description: name: node_preamble - url: "https://pub.dartlang.org" + sha256: c133f761a6a790d0b000efa4f74eae9700bb6e9e9f5e996f0e8d6fe92703ced6 + url: "https://pub.dev" source: hosted version: "2.0.0" package_config: dependency: transitive description: name: package_config - url: "https://pub.dartlang.org" + sha256: "20e7154d701fedaeb219dad732815ecb66677667871127998a9a6581c2aba4ba" + url: "https://pub.dev" source: hosted version: "2.0.0" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: "2ad4cddff7f5cc0e2d13069f2a3f7a73ca18f66abd6f5ecf215219cdb3638edb" + url: "https://pub.dev" source: hosted version: "1.8.0" pedantic: dependency: transitive description: name: pedantic - url: "https://pub.dartlang.org" + sha256: "8f6460c77a98ad2807cd3b98c67096db4286f56166852d0ce5951bb600a63594" + url: "https://pub.dev" source: hosted version: "1.11.0" pool: dependency: transitive description: name: pool - url: "https://pub.dartlang.org" + sha256: "05955e3de2683e1746222efd14b775df7131139e07695dc8e24650f6b4204504" + url: "https://pub.dev" source: hosted version: "1.5.0" pub_semver: dependency: transitive description: name: pub_semver - url: "https://pub.dartlang.org" + sha256: "59ed538734419e81f7fc18c98249ae72c3c7188bdd9dceff2840585227f79843" + url: "https://pub.dev" source: hosted version: "2.0.0" shelf: dependency: transitive description: name: shelf - url: "https://pub.dartlang.org" + sha256: "26d22c68cf9c349fb1adb4a830da3e014cb5f7ed9cc57f721d9d9e20cf8d6de5" + url: "https://pub.dev" source: hosted version: "1.1.4" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler - url: "https://pub.dartlang.org" + sha256: e0b44ebddec91e70a713e13adf93c1b2100821303b86a18e1ef1d082bd8bd9b8 + url: "https://pub.dev" source: hosted version: "3.0.0" shelf_static: dependency: transitive description: name: shelf_static - url: "https://pub.dartlang.org" + sha256: "8584c0aa0f5756a61519b1a2fc2cd22ddbc518e9396bd33ebf06b9836bb23d13" + url: "https://pub.dev" source: hosted version: "1.0.0" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - url: "https://pub.dartlang.org" + sha256: fd84910bf7d58db109082edf7326b75322b8f186162028482f53dc892f00332d + url: "https://pub.dev" source: hosted version: "1.0.1" source_map_stack_trace: dependency: transitive description: name: source_map_stack_trace - url: "https://pub.dartlang.org" + sha256: "8c463326277f68a628abab20580047b419c2ff66756fd0affd451f73f9508c11" + url: "https://pub.dev" source: hosted version: "2.1.0" source_maps: dependency: transitive description: name: source_maps - url: "https://pub.dartlang.org" + sha256: "52de2200bb098de739794c82d09c41ac27b2e42fd7e23cce7b9c74bf653c7296" + url: "https://pub.dev" source: hosted version: "0.10.10" source_span: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: f4b22294de9a549967d0033d4f30fcad4f0afc200f4bf58e82d815725feec70c + url: "https://pub.dev" source: hosted version: "1.8.0" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: f8d9f247e2f9f90e32d1495ff32dac7e4ae34ffa7194c5ff8fcc0fd0e52df774 + url: "https://pub.dev" source: hosted version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: db47e4797198ee601990820437179bb90219f918962318d494ada2b4b11e6f6d + url: "https://pub.dev" source: hosted version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: dd11571b8a03f7cadcf91ec26a77e02bfbd6bbba2a512924d3116646b4198fc4 + url: "https://pub.dev" source: hosted version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a88162591b02c1f3a3db3af8ce1ea2b374bd75a7bb8d5e353bcfbdc79d719830 + url: "https://pub.dev" source: hosted version: "1.2.0" test: dependency: "direct dev" description: name: test - url: "https://pub.dartlang.org" + sha256: da03cbb1dd2537def0ea0d7f134cdfae2c97b4df95687827ffaac9a54eeb20db + url: "https://pub.dev" source: hosted version: "1.17.5" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: f27b321e23d18b58891d880ed565be7f517cd9dcce2652873101a7c742a9c8ca + url: "https://pub.dev" source: hosted version: "0.4.0" test_core: dependency: transitive description: name: test_core - url: "https://pub.dartlang.org" + sha256: "382f73c8fdc29bec39fdb23347204b2341ce56a90b6479ec2b893dfd56351168" + url: "https://pub.dev" source: hosted version: "0.3.25" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + sha256: "53bdf7e979cfbf3e28987552fd72f637e63f3c8724c9e56d9246942dc2fa36ee" + url: "https://pub.dev" source: hosted version: "1.3.0" vm_service: dependency: transitive description: name: vm_service - url: "https://pub.dartlang.org" + sha256: f6c7c62374647d36cc0c67908a934f99ef17eb603cf678db090f01e55fa3e34d + url: "https://pub.dev" source: hosted version: "7.1.0" watcher: dependency: transitive description: name: watcher - url: "https://pub.dartlang.org" + sha256: "68173f2fa67d241323a4123be7ed4e43424c54befa5505d71c8ad4b7baf8f71d" + url: "https://pub.dev" source: hosted version: "1.0.0" web_socket_channel: dependency: transitive description: name: web_socket_channel - url: "https://pub.dartlang.org" + sha256: "0c2ada1b1aeb2ad031ca81872add6be049b8cb479262c6ad3c4b0f9c24eaab2f" + url: "https://pub.dev" source: hosted version: "2.1.0" webkit_inspection_protocol: dependency: transitive description: name: webkit_inspection_protocol - url: "https://pub.dartlang.org" + sha256: "5adb6ab8ed14e22bb907aae7338f0c206ea21e7a27004e97664b16c120306f00" + url: "https://pub.dev" source: hosted version: "1.0.0" yaml: dependency: transitive description: name: yaml - url: "https://pub.dartlang.org" + sha256: "3cee79b1715110341012d27756d9bae38e650588acd38d3f3c610822e1337ace" + url: "https://pub.dev" source: hosted version: "3.1.0" sdks: - dart: ">=2.12.0 <3.0.0" + dart: ">=2.12.0 <4.0.0"