@visus-io/notion-sdk-ts 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/blocks.api.d.ts +1083 -224
- package/dist/api/blocks.api.js +4 -0
- package/dist/api/comments.api.d.ts +19 -1
- package/dist/api/comments.api.js +1 -1
- package/dist/api/dataSources.api.d.ts +36 -0
- package/dist/api/databases.api.d.ts +36 -0
- package/dist/api/databases.api.js +1 -0
- package/dist/api/fileUploads.api.d.ts +17 -7
- package/dist/api/fileUploads.api.js +30 -16
- package/dist/api/pages.api.d.ts +50 -0
- package/dist/api/pages.api.js +5 -0
- package/dist/client.d.ts +64 -2
- package/dist/client.js +150 -36
- package/dist/errors.d.ts +36 -3
- package/dist/errors.js +59 -4
- package/dist/helpers/filter.helpers.d.ts +11 -4
- package/dist/helpers/filter.helpers.js +73 -30
- package/dist/helpers/pagination.helpers.d.ts +7 -2
- package/dist/helpers/pagination.helpers.js +26 -5
- package/dist/models/page.model.d.ts +20 -1
- package/dist/models/page.model.js +33 -2
- package/dist/schemas/block.schema.d.ts +1082 -224
- package/dist/schemas/block.schema.js +40 -25
- package/dist/schemas/comment.schema.d.ts +18 -0
- package/dist/schemas/dataSource.schema.d.ts +36 -0
- package/dist/schemas/database.schema.d.ts +36 -0
- package/dist/schemas/meetingNotesQuery.schema.d.ts +1082 -224
- package/dist/schemas/page.schema.d.ts +46 -0
- package/dist/schemas/page.schema.js +2 -1
- package/dist/schemas/pageMarkdown.schema.js +1 -1
- package/dist/schemas/pageProperties.schema.d.ts +99 -1
- package/dist/schemas/pageProperties.schema.js +16 -1
- package/dist/schemas/pagination.schema.d.ts +1 -1
- package/dist/schemas/propertyObjects.schema.js +2 -1
- package/dist/schemas/richText.schema.d.ts +36 -0
- package/dist/schemas/richText.schema.js +21 -0
- package/dist/schemas/shared.schema.d.ts +3 -7
- package/dist/schemas/shared.schema.js +5 -9
- package/dist/schemas/view.schema.d.ts +46 -0
- package/dist/validation.d.ts +8 -0
- package/dist/validation.js +16 -0
- package/package.json +2 -2
|
@@ -1,83 +1,117 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// ---------------------------------------------------------------------------
|
|
3
|
-
// Filter value types
|
|
4
|
-
// ---------------------------------------------------------------------------
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.filter = void 0;
|
|
4
|
+
const validation_1 = require("../validation");
|
|
5
|
+
/**
|
|
6
|
+
* Assert that a select-like filter value is a single string. Notion rejects an
|
|
7
|
+
* array for the `equals`, `does_not_equal`, `contains`, and `does_not_contain`
|
|
8
|
+
* operators on `select`, `status`, and `multi_select` properties.
|
|
9
|
+
*
|
|
10
|
+
* The parameter type still accepts `string[]` for backward compatibility. An
|
|
11
|
+
* array now fails fast with a clear error instead of a generic API 400.
|
|
12
|
+
*
|
|
13
|
+
* @throws {NotionValidationError} If `value` is an array.
|
|
14
|
+
*/
|
|
15
|
+
function assertScalarFilterValue(value, label) {
|
|
16
|
+
if (Array.isArray(value)) {
|
|
17
|
+
throw new validation_1.NotionValidationError(`${label} accepts a single string, not an array. Compose an OR filter with filter.or(...) to match multiple values.`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
7
20
|
// ---------------------------------------------------------------------------
|
|
8
21
|
// Property filter builders
|
|
9
22
|
// ---------------------------------------------------------------------------
|
|
10
23
|
/** Operators common to text-like properties (title, rich_text, url, email, phone_number). */
|
|
11
24
|
class TextFilter {
|
|
12
|
-
constructor(property, propertyType) {
|
|
25
|
+
constructor(property, propertyType, isFormula = false) {
|
|
13
26
|
this.property = property;
|
|
14
27
|
this.propertyType = propertyType;
|
|
28
|
+
this.isFormula = isFormula;
|
|
29
|
+
}
|
|
30
|
+
build(condition) {
|
|
31
|
+
if (this.isFormula) {
|
|
32
|
+
return { property: this.property, formula: { string: condition } };
|
|
33
|
+
}
|
|
34
|
+
return { property: this.property, [this.propertyType]: condition };
|
|
15
35
|
}
|
|
16
36
|
equals(value) {
|
|
17
|
-
return
|
|
37
|
+
return this.build({ equals: value });
|
|
18
38
|
}
|
|
19
39
|
doesNotEqual(value) {
|
|
20
|
-
return
|
|
40
|
+
return this.build({ does_not_equal: value });
|
|
21
41
|
}
|
|
22
42
|
contains(value) {
|
|
23
|
-
return
|
|
43
|
+
return this.build({ contains: value });
|
|
24
44
|
}
|
|
25
45
|
doesNotContain(value) {
|
|
26
|
-
return
|
|
46
|
+
return this.build({ does_not_contain: value });
|
|
27
47
|
}
|
|
28
48
|
startsWith(value) {
|
|
29
|
-
return
|
|
49
|
+
return this.build({ starts_with: value });
|
|
30
50
|
}
|
|
31
51
|
endsWith(value) {
|
|
32
|
-
return
|
|
52
|
+
return this.build({ ends_with: value });
|
|
33
53
|
}
|
|
34
54
|
isEmpty() {
|
|
35
|
-
return
|
|
55
|
+
return this.build({ is_empty: true });
|
|
36
56
|
}
|
|
37
57
|
isNotEmpty() {
|
|
38
|
-
return
|
|
58
|
+
return this.build({ is_not_empty: true });
|
|
39
59
|
}
|
|
40
60
|
}
|
|
41
61
|
/** Operators for number properties. */
|
|
42
62
|
class NumberFilter {
|
|
43
|
-
constructor(property) {
|
|
63
|
+
constructor(property, isFormula = false) {
|
|
44
64
|
this.property = property;
|
|
65
|
+
this.isFormula = isFormula;
|
|
66
|
+
}
|
|
67
|
+
build(condition) {
|
|
68
|
+
if (this.isFormula) {
|
|
69
|
+
return { property: this.property, formula: { number: condition } };
|
|
70
|
+
}
|
|
71
|
+
return { property: this.property, number: condition };
|
|
45
72
|
}
|
|
46
73
|
equals(value) {
|
|
47
|
-
return
|
|
74
|
+
return this.build({ equals: value });
|
|
48
75
|
}
|
|
49
76
|
doesNotEqual(value) {
|
|
50
|
-
return
|
|
77
|
+
return this.build({ does_not_equal: value });
|
|
51
78
|
}
|
|
52
79
|
greaterThan(value) {
|
|
53
|
-
return
|
|
80
|
+
return this.build({ greater_than: value });
|
|
54
81
|
}
|
|
55
82
|
greaterThanOrEqualTo(value) {
|
|
56
|
-
return
|
|
83
|
+
return this.build({ greater_than_or_equal_to: value });
|
|
57
84
|
}
|
|
58
85
|
lessThan(value) {
|
|
59
|
-
return
|
|
86
|
+
return this.build({ less_than: value });
|
|
60
87
|
}
|
|
61
88
|
lessThanOrEqualTo(value) {
|
|
62
|
-
return
|
|
89
|
+
return this.build({ less_than_or_equal_to: value });
|
|
63
90
|
}
|
|
64
91
|
isEmpty() {
|
|
65
|
-
return
|
|
92
|
+
return this.build({ is_empty: true });
|
|
66
93
|
}
|
|
67
94
|
isNotEmpty() {
|
|
68
|
-
return
|
|
95
|
+
return this.build({ is_not_empty: true });
|
|
69
96
|
}
|
|
70
97
|
}
|
|
71
98
|
/** Operators for checkbox properties. */
|
|
72
99
|
class CheckboxFilter {
|
|
73
|
-
constructor(property) {
|
|
100
|
+
constructor(property, isFormula = false) {
|
|
74
101
|
this.property = property;
|
|
102
|
+
this.isFormula = isFormula;
|
|
103
|
+
}
|
|
104
|
+
build(condition) {
|
|
105
|
+
if (this.isFormula) {
|
|
106
|
+
return { property: this.property, formula: { checkbox: condition } };
|
|
107
|
+
}
|
|
108
|
+
return { property: this.property, checkbox: condition };
|
|
75
109
|
}
|
|
76
110
|
equals(value) {
|
|
77
|
-
return
|
|
111
|
+
return this.build({ equals: value });
|
|
78
112
|
}
|
|
79
113
|
doesNotEqual(value) {
|
|
80
|
-
return
|
|
114
|
+
return this.build({ does_not_equal: value });
|
|
81
115
|
}
|
|
82
116
|
}
|
|
83
117
|
/** Operators for select properties. */
|
|
@@ -86,9 +120,11 @@ class SelectFilter {
|
|
|
86
120
|
this.property = property;
|
|
87
121
|
}
|
|
88
122
|
equals(value) {
|
|
123
|
+
assertScalarFilterValue(value, 'select().equals');
|
|
89
124
|
return { property: this.property, select: { equals: value } };
|
|
90
125
|
}
|
|
91
126
|
doesNotEqual(value) {
|
|
127
|
+
assertScalarFilterValue(value, 'select().doesNotEqual');
|
|
92
128
|
return { property: this.property, select: { does_not_equal: value } };
|
|
93
129
|
}
|
|
94
130
|
isEmpty() {
|
|
@@ -104,9 +140,11 @@ class MultiSelectFilter {
|
|
|
104
140
|
this.property = property;
|
|
105
141
|
}
|
|
106
142
|
contains(value) {
|
|
143
|
+
assertScalarFilterValue(value, 'multiSelect().contains');
|
|
107
144
|
return { property: this.property, multi_select: { contains: value } };
|
|
108
145
|
}
|
|
109
146
|
doesNotContain(value) {
|
|
147
|
+
assertScalarFilterValue(value, 'multiSelect().doesNotContain');
|
|
110
148
|
return { property: this.property, multi_select: { does_not_contain: value } };
|
|
111
149
|
}
|
|
112
150
|
isEmpty() {
|
|
@@ -122,9 +160,11 @@ class StatusFilter {
|
|
|
122
160
|
this.property = property;
|
|
123
161
|
}
|
|
124
162
|
equals(value) {
|
|
163
|
+
assertScalarFilterValue(value, 'status().equals');
|
|
125
164
|
return { property: this.property, status: { equals: value } };
|
|
126
165
|
}
|
|
127
166
|
doesNotEqual(value) {
|
|
167
|
+
assertScalarFilterValue(value, 'status().doesNotEqual');
|
|
128
168
|
return { property: this.property, status: { does_not_equal: value } };
|
|
129
169
|
}
|
|
130
170
|
isEmpty() {
|
|
@@ -136,11 +176,15 @@ class StatusFilter {
|
|
|
136
176
|
}
|
|
137
177
|
/** Operators for date properties and timestamp filters. */
|
|
138
178
|
class DateFilter {
|
|
139
|
-
constructor(key, isTimestamp) {
|
|
179
|
+
constructor(key, isTimestamp, isFormula = false) {
|
|
140
180
|
this.key = key;
|
|
141
181
|
this.isTimestamp = isTimestamp;
|
|
182
|
+
this.isFormula = isFormula;
|
|
142
183
|
}
|
|
143
184
|
wrap(condition) {
|
|
185
|
+
if (this.isFormula) {
|
|
186
|
+
return { property: this.key, formula: { date: condition } };
|
|
187
|
+
}
|
|
144
188
|
if (this.isTimestamp) {
|
|
145
189
|
return { timestamp: this.key, [this.key]: condition };
|
|
146
190
|
}
|
|
@@ -240,17 +284,16 @@ class FormulaFilter {
|
|
|
240
284
|
this.property = property;
|
|
241
285
|
}
|
|
242
286
|
text() {
|
|
243
|
-
return new TextFilter(this.property, 'formula');
|
|
287
|
+
return new TextFilter(this.property, 'formula', true);
|
|
244
288
|
}
|
|
245
289
|
number() {
|
|
246
|
-
|
|
247
|
-
return new NumberFilter(this.property);
|
|
290
|
+
return new NumberFilter(this.property, true);
|
|
248
291
|
}
|
|
249
292
|
checkbox() {
|
|
250
|
-
return new CheckboxFilter(this.property);
|
|
293
|
+
return new CheckboxFilter(this.property, true);
|
|
251
294
|
}
|
|
252
295
|
date() {
|
|
253
|
-
return new DateFilter(this.property, false);
|
|
296
|
+
return new DateFilter(this.property, false, true);
|
|
254
297
|
}
|
|
255
298
|
}
|
|
256
299
|
// ---------------------------------------------------------------------------
|
|
@@ -43,8 +43,13 @@ export type PaginatedFetchFunction<T> = (cursor?: string) => Promise<PaginatedLi
|
|
|
43
43
|
/**
|
|
44
44
|
* Collects all results from a paginated endpoint by automatically following cursors.
|
|
45
45
|
*
|
|
46
|
-
* This function fetches pages until `has_more` is `false
|
|
47
|
-
* into one array. Use this function when you need all results
|
|
46
|
+
* This function fetches pages until `has_more` is `false` or `next_cursor` is `null`.
|
|
47
|
+
* It collects all results into one array. Use this function when you need all results
|
|
48
|
+
* at once.
|
|
49
|
+
*
|
|
50
|
+
* This helper does not work around the 10,000-result cap on data source, view, and
|
|
51
|
+
* meeting-notes queries. When a query hits that cap, the result set is truncated and
|
|
52
|
+
* this helper writes a warning. Use {@link collectAllDataSourceRows} for those queries.
|
|
48
53
|
*
|
|
49
54
|
* @param fetchPage - Function that fetches a single page of results
|
|
50
55
|
* @returns Array containing all results from all pages
|
|
@@ -5,11 +5,32 @@ exports.paginateIterator = paginateIterator;
|
|
|
5
5
|
exports.paginateWithMetadata = paginateWithMetadata;
|
|
6
6
|
exports.iterateAllDataSourceRows = iterateAllDataSourceRows;
|
|
7
7
|
exports.collectAllDataSourceRows = collectAllDataSourceRows;
|
|
8
|
+
/**
|
|
9
|
+
* Return the cursor for the next page, or `undefined` when iteration must stop
|
|
10
|
+
* (`has_more` is `false`, or `next_cursor` is `null`). Warn when the result is a
|
|
11
|
+
* truncated query (`request_status.type === 'incomplete'`).
|
|
12
|
+
*/
|
|
13
|
+
function nextCursor(response) {
|
|
14
|
+
if (response.request_status?.type === 'incomplete') {
|
|
15
|
+
console.warn('Notion returned a truncated query result (the 10,000-result cap was reached). ' +
|
|
16
|
+
'This paginate helper stops here and the result set is incomplete. ' +
|
|
17
|
+
'Use collectAllDataSourceRows() or iterateAllDataSourceRows() to read every row.');
|
|
18
|
+
}
|
|
19
|
+
if (!response.has_more || response.next_cursor === null) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
return response.next_cursor ?? undefined;
|
|
23
|
+
}
|
|
8
24
|
/**
|
|
9
25
|
* Collects all results from a paginated endpoint by automatically following cursors.
|
|
10
26
|
*
|
|
11
|
-
* This function fetches pages until `has_more` is `false
|
|
12
|
-
* into one array. Use this function when you need all results
|
|
27
|
+
* This function fetches pages until `has_more` is `false` or `next_cursor` is `null`.
|
|
28
|
+
* It collects all results into one array. Use this function when you need all results
|
|
29
|
+
* at once.
|
|
30
|
+
*
|
|
31
|
+
* This helper does not work around the 10,000-result cap on data source, view, and
|
|
32
|
+
* meeting-notes queries. When a query hits that cap, the result set is truncated and
|
|
33
|
+
* this helper writes a warning. Use {@link collectAllDataSourceRows} for those queries.
|
|
13
34
|
*
|
|
14
35
|
* @param fetchPage - Function that fetches a single page of results
|
|
15
36
|
* @returns Array containing all results from all pages
|
|
@@ -58,7 +79,7 @@ async function paginate(fetchPage) {
|
|
|
58
79
|
do {
|
|
59
80
|
const response = await fetchPage(cursor);
|
|
60
81
|
all.push(...response.results);
|
|
61
|
-
cursor = response
|
|
82
|
+
cursor = nextCursor(response);
|
|
62
83
|
} while (cursor);
|
|
63
84
|
return all;
|
|
64
85
|
}
|
|
@@ -112,7 +133,7 @@ async function* paginateIterator(fetchPage) {
|
|
|
112
133
|
for (const item of response.results) {
|
|
113
134
|
yield item;
|
|
114
135
|
}
|
|
115
|
-
cursor = response
|
|
136
|
+
cursor = nextCursor(response);
|
|
116
137
|
} while (cursor);
|
|
117
138
|
}
|
|
118
139
|
/**
|
|
@@ -142,7 +163,7 @@ async function paginateWithMetadata(fetchPage) {
|
|
|
142
163
|
do {
|
|
143
164
|
const response = await fetchPage(cursor);
|
|
144
165
|
items.push(...response.results);
|
|
145
|
-
cursor = response
|
|
166
|
+
cursor = nextCursor(response);
|
|
146
167
|
pageCount++;
|
|
147
168
|
} while (cursor);
|
|
148
169
|
return {
|
|
@@ -28,11 +28,30 @@ export declare class Page extends BaseModel<NotionPage> {
|
|
|
28
28
|
*/
|
|
29
29
|
getTitle(): string | null;
|
|
30
30
|
/**
|
|
31
|
-
* Check if the page is a
|
|
31
|
+
* Check if the page is a row in a database.
|
|
32
|
+
*
|
|
33
|
+
* On API version 2025-09-03 and later, a database row has a `data_source_id`
|
|
34
|
+
* parent. Older responses use a `database_id` parent. This method returns `true`
|
|
35
|
+
* for both.
|
|
32
36
|
*/
|
|
33
37
|
isInDatabase(): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Check if the page is a row in a data source.
|
|
40
|
+
*/
|
|
41
|
+
isInDataSource(): boolean;
|
|
34
42
|
/**
|
|
35
43
|
* Check if the page is a child of another page.
|
|
36
44
|
*/
|
|
37
45
|
isSubpage(): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Get the parent data source ID.
|
|
48
|
+
* Return `null` when the parent is not a data source.
|
|
49
|
+
*/
|
|
50
|
+
getParentDataSourceId(): string | null;
|
|
51
|
+
/**
|
|
52
|
+
* Get the parent database ID.
|
|
53
|
+
* A `data_source_id` parent also carries its database ID. Return `null` when the
|
|
54
|
+
* parent is neither a database nor a data source.
|
|
55
|
+
*/
|
|
56
|
+
getParentDatabaseId(): string | null;
|
|
38
57
|
}
|
|
@@ -62,10 +62,20 @@ class Page extends base_model_1.BaseModel {
|
|
|
62
62
|
return null;
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
|
-
* Check if the page is a
|
|
65
|
+
* Check if the page is a row in a database.
|
|
66
|
+
*
|
|
67
|
+
* On API version 2025-09-03 and later, a database row has a `data_source_id`
|
|
68
|
+
* parent. Older responses use a `database_id` parent. This method returns `true`
|
|
69
|
+
* for both.
|
|
66
70
|
*/
|
|
67
71
|
isInDatabase() {
|
|
68
|
-
return this.data.parent.type === 'database_id';
|
|
72
|
+
return this.data.parent.type === 'data_source_id' || this.data.parent.type === 'database_id';
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Check if the page is a row in a data source.
|
|
76
|
+
*/
|
|
77
|
+
isInDataSource() {
|
|
78
|
+
return this.data.parent.type === 'data_source_id';
|
|
69
79
|
}
|
|
70
80
|
/**
|
|
71
81
|
* Check if the page is a child of another page.
|
|
@@ -73,5 +83,26 @@ class Page extends base_model_1.BaseModel {
|
|
|
73
83
|
isSubpage() {
|
|
74
84
|
return this.data.parent.type === 'page_id';
|
|
75
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Get the parent data source ID.
|
|
88
|
+
* Return `null` when the parent is not a data source.
|
|
89
|
+
*/
|
|
90
|
+
getParentDataSourceId() {
|
|
91
|
+
return this.data.parent.type === 'data_source_id' ? this.data.parent.data_source_id : null;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get the parent database ID.
|
|
95
|
+
* A `data_source_id` parent also carries its database ID. Return `null` when the
|
|
96
|
+
* parent is neither a database nor a data source.
|
|
97
|
+
*/
|
|
98
|
+
getParentDatabaseId() {
|
|
99
|
+
if (this.data.parent.type === 'database_id') {
|
|
100
|
+
return this.data.parent.database_id;
|
|
101
|
+
}
|
|
102
|
+
if (this.data.parent.type === 'data_source_id') {
|
|
103
|
+
return this.data.parent.database_id;
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
76
107
|
}
|
|
77
108
|
exports.Page = Page;
|