@visus-io/notion-sdk-ts 3.0.2 → 3.1.1
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/README.md +20 -87
- package/dist/api/asyncTasks.api.d.ts +72 -0
- package/dist/api/asyncTasks.api.js +70 -0
- package/dist/api/base.api.d.ts +15 -4
- package/dist/api/base.api.js +20 -8
- package/dist/api/blocks.api.d.ts +435 -73
- package/dist/api/blocks.api.js +43 -1
- package/dist/api/comments.api.d.ts +42 -5
- package/dist/api/comments.api.js +45 -1
- package/dist/api/customEmojis.api.d.ts +38 -0
- package/dist/api/customEmojis.api.js +38 -0
- package/dist/api/dataSources.api.d.ts +67 -14
- package/dist/api/dataSources.api.js +26 -1
- package/dist/api/databases.api.d.ts +47 -11
- package/dist/api/databases.api.js +4 -1
- package/dist/api/fileUploads.api.d.ts +8 -5
- package/dist/api/fileUploads.api.js +11 -7
- package/dist/api/index.d.ts +3 -0
- package/dist/api/index.js +7 -1
- package/dist/api/pages.api.d.ts +144 -10
- package/dist/api/pages.api.js +66 -0
- package/dist/api/search.api.d.ts +12 -2
- package/dist/api/search.api.js +5 -2
- package/dist/api/users.api.d.ts +3 -0
- package/dist/api/users.api.js +2 -0
- package/dist/api/views.api.d.ts +286 -0
- package/dist/api/views.api.js +172 -0
- package/dist/client.d.ts +17 -17
- package/dist/client.js +25 -30
- package/dist/errors.d.ts +19 -5
- package/dist/errors.js +16 -4
- package/dist/helpers/block.helpers.d.ts +49 -5
- package/dist/helpers/block.helpers.js +50 -6
- package/dist/helpers/file.helpers.d.ts +46 -5
- package/dist/helpers/file.helpers.js +36 -8
- package/dist/helpers/filter.helpers.d.ts +8 -6
- package/dist/helpers/filter.helpers.js +2 -0
- package/dist/helpers/index.d.ts +3 -2
- package/dist/helpers/index.js +5 -1
- package/dist/helpers/pagination.helpers.d.ts +85 -13
- package/dist/helpers/pagination.helpers.js +114 -8
- package/dist/helpers/parent.helpers.d.ts +5 -3
- package/dist/helpers/parent.helpers.js +5 -3
- package/dist/helpers/property.helpers.d.ts +31 -0
- package/dist/helpers/property.helpers.js +30 -1
- package/dist/helpers/richText.helpers.d.ts +10 -5
- package/dist/helpers/richText.helpers.js +11 -6
- package/dist/helpers/sort.helpers.d.ts +2 -0
- package/dist/helpers/sort.helpers.js +2 -0
- package/dist/helpers/webhook.helpers.d.ts +54 -0
- package/dist/helpers/webhook.helpers.js +83 -0
- package/dist/models/asyncTask.model.d.ts +61 -0
- package/dist/models/asyncTask.model.js +91 -0
- package/dist/models/base.model.d.ts +16 -4
- package/dist/models/base.model.js +17 -5
- package/dist/models/block.model.d.ts +6 -2
- package/dist/models/block.model.js +48 -33
- package/dist/models/comment.model.d.ts +4 -2
- package/dist/models/comment.model.js +4 -2
- package/dist/models/customEmoji.model.d.ts +30 -0
- package/dist/models/customEmoji.model.js +44 -0
- package/dist/models/dataSource.model.d.ts +7 -5
- package/dist/models/dataSource.model.js +5 -3
- package/dist/models/database.model.d.ts +13 -5
- package/dist/models/database.model.js +15 -5
- package/dist/models/fileUpload.model.d.ts +6 -4
- package/dist/models/fileUpload.model.js +6 -4
- package/dist/models/index.d.ts +3 -0
- package/dist/models/index.js +7 -1
- package/dist/models/page.model.d.ts +8 -2
- package/dist/models/page.model.js +14 -4
- package/dist/models/richText.model.d.ts +3 -1
- package/dist/models/richText.model.js +3 -1
- package/dist/models/user.model.d.ts +4 -2
- package/dist/models/user.model.js +4 -2
- package/dist/models/view.model.d.ts +81 -0
- package/dist/models/view.model.js +121 -0
- package/dist/notion.d.ts +32 -8
- package/dist/notion.js +25 -4
- package/dist/schemas/asyncTask.schema.d.ts +53 -0
- package/dist/schemas/asyncTask.schema.js +88 -0
- package/dist/schemas/block.schema.d.ts +390 -73
- package/dist/schemas/block.schema.js +39 -8
- package/dist/schemas/codeLanguages.d.ts +7 -1
- package/dist/schemas/codeLanguages.js +4 -1
- package/dist/schemas/colors.d.ts +7 -1
- package/dist/schemas/colors.js +4 -1
- package/dist/schemas/comment.schema.d.ts +28 -5
- package/dist/schemas/comment.schema.js +11 -2
- package/dist/schemas/customEmoji.schema.d.ts +18 -0
- package/dist/schemas/customEmoji.schema.js +50 -0
- package/dist/schemas/dataSource.schema.d.ts +84 -10
- package/dist/schemas/dataSource.schema.js +31 -6
- package/dist/schemas/database.schema.d.ts +51 -7
- package/dist/schemas/database.schema.js +10 -3
- package/dist/schemas/emoji.schema.d.ts +7 -2
- package/dist/schemas/emoji.schema.js +4 -2
- package/dist/schemas/file.schema.d.ts +18 -2
- package/dist/schemas/file.schema.js +6 -2
- package/dist/schemas/fileUpload.schema.d.ts +9 -3
- package/dist/schemas/fileUpload.schema.js +5 -2
- package/dist/schemas/icon.schema.d.ts +116 -0
- package/dist/schemas/icon.schema.js +100 -0
- package/dist/schemas/index.d.ts +6 -0
- package/dist/schemas/index.js +6 -0
- package/dist/schemas/meetingNotesQuery.schema.d.ts +4198 -0
- package/dist/schemas/meetingNotesQuery.schema.js +67 -0
- package/dist/schemas/page.schema.d.ts +51 -9
- package/dist/schemas/page.schema.js +6 -2
- package/dist/schemas/pageMarkdown.schema.d.ts +70 -0
- package/dist/schemas/pageMarkdown.schema.js +70 -0
- package/dist/schemas/pageProperties.schema.d.ts +105 -21
- package/dist/schemas/pageProperties.schema.js +8 -6
- package/dist/schemas/pagination.schema.d.ts +57 -7
- package/dist/schemas/pagination.schema.js +25 -1
- package/dist/schemas/parent.schema.d.ts +39 -3
- package/dist/schemas/parent.schema.js +17 -5
- package/dist/schemas/propertyObjects.schema.d.ts +93 -15
- package/dist/schemas/propertyObjects.schema.js +11 -5
- package/dist/schemas/richText.schema.d.ts +23 -6
- package/dist/schemas/richText.schema.js +7 -4
- package/dist/schemas/shared.schema.d.ts +6 -3
- package/dist/schemas/shared.schema.js +6 -3
- package/dist/schemas/user.schema.d.ts +17 -0
- package/dist/schemas/user.schema.js +7 -3
- package/dist/schemas/view.schema.d.ts +1111 -0
- package/dist/schemas/view.schema.js +134 -0
- package/dist/validation.d.ts +11 -4
- package/dist/validation.js +11 -4
- package/package.json +6 -3
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { PaginatedList } from '../schemas';
|
|
2
2
|
/**
|
|
3
|
-
* Pagination
|
|
3
|
+
* Pagination helpers that collect all results from paginated Notion API endpoints.
|
|
4
4
|
*
|
|
5
|
-
* The Notion API uses cursor-based pagination.
|
|
6
|
-
* with `results`, `next_cursor`, and `has_more` properties.
|
|
7
|
-
*
|
|
5
|
+
* The Notion API uses cursor-based pagination. Each list endpoint returns a
|
|
6
|
+
* `PaginatedList<T>` object with `results`, `next_cursor`, and `has_more` properties.
|
|
7
|
+
* These helpers fetch every page automatically.
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
10
10
|
* ```typescript
|
|
@@ -35,14 +35,16 @@ import type { PaginatedList } from '../schemas';
|
|
|
35
35
|
*/
|
|
36
36
|
/**
|
|
37
37
|
* Fetch function that returns a paginated list.
|
|
38
|
-
*
|
|
38
|
+
* This function receives an optional cursor. It returns the next page of results.
|
|
39
|
+
*
|
|
40
|
+
* @category Pagination
|
|
39
41
|
*/
|
|
40
42
|
export type PaginatedFetchFunction<T> = (cursor?: string) => Promise<PaginatedList<T>>;
|
|
41
43
|
/**
|
|
42
44
|
* Collects all results from a paginated endpoint by automatically following cursors.
|
|
43
45
|
*
|
|
44
|
-
* This function
|
|
45
|
-
*
|
|
46
|
+
* This function fetches pages until `has_more` is `false`. It collects all results
|
|
47
|
+
* into one array. Use this function when you need all results at once.
|
|
46
48
|
*
|
|
47
49
|
* @param fetchPage - Function that fetches a single page of results
|
|
48
50
|
* @returns Array containing all results from all pages
|
|
@@ -82,14 +84,16 @@ export type PaginatedFetchFunction<T> = (cursor?: string) => Promise<PaginatedLi
|
|
|
82
84
|
* })
|
|
83
85
|
* );
|
|
84
86
|
* ```
|
|
87
|
+
*
|
|
88
|
+
* @category Pagination
|
|
85
89
|
*/
|
|
86
90
|
export declare function paginate<T>(fetchPage: PaginatedFetchFunction<T>): Promise<T[]>;
|
|
87
91
|
/**
|
|
88
92
|
* Creates an async iterator that yields individual items from paginated results.
|
|
89
93
|
*
|
|
90
|
-
* This function
|
|
91
|
-
* one page at a time and
|
|
92
|
-
*
|
|
94
|
+
* This function iterates over large result sets without loading everything into
|
|
95
|
+
* memory. It fetches one page at a time and yields items as needed. Use this function
|
|
96
|
+
* with `for await...of` to process results one at a time.
|
|
93
97
|
*
|
|
94
98
|
* @param fetchPage - Function that fetches a single page of results
|
|
95
99
|
* @yields Individual items from each page
|
|
@@ -124,13 +128,15 @@ export declare function paginate<T>(fetchPage: PaginatedFetchFunction<T>): Promi
|
|
|
124
128
|
* console.log(result.url);
|
|
125
129
|
* }
|
|
126
130
|
* ```
|
|
131
|
+
*
|
|
132
|
+
* @category Pagination
|
|
127
133
|
*/
|
|
128
134
|
export declare function paginateIterator<T>(fetchPage: PaginatedFetchFunction<T>): AsyncGenerator<T, void, undefined>;
|
|
129
135
|
/**
|
|
130
|
-
* Collects all results
|
|
136
|
+
* Collects all results. Returns the items together with pagination metadata.
|
|
131
137
|
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
138
|
+
* Use this function when you need the page count or the total number of API
|
|
139
|
+
* calls.
|
|
134
140
|
*
|
|
135
141
|
* @param fetchPage - Function that fetches a single page of results
|
|
136
142
|
* @returns Object containing all results and pagination metadata
|
|
@@ -143,9 +149,75 @@ export declare function paginateIterator<T>(fetchPage: PaginatedFetchFunction<T>
|
|
|
143
149
|
*
|
|
144
150
|
* console.log(`Fetched ${totalCount} blocks across ${pageCount} pages`);
|
|
145
151
|
* ```
|
|
152
|
+
*
|
|
153
|
+
* @category Pagination
|
|
146
154
|
*/
|
|
147
155
|
export declare function paginateWithMetadata<T>(fetchPage: PaginatedFetchFunction<T>): Promise<{
|
|
148
156
|
items: T[];
|
|
149
157
|
pageCount: number;
|
|
150
158
|
totalCount: number;
|
|
151
159
|
}>;
|
|
160
|
+
/**
|
|
161
|
+
* Fetch function for windowed row collection. It extends
|
|
162
|
+
* {@link PaginatedFetchFunction} with a second parameter: the ISO 8601
|
|
163
|
+
* `created_time` lower bound for the next window. This parameter appears only
|
|
164
|
+
* after the previous window hits the query result limit
|
|
165
|
+
* (`request_status.type === 'incomplete'`). Merge this bound into your own
|
|
166
|
+
* created_time-ascending query, for example
|
|
167
|
+
* `filter.createdTime().onOrAfter(createdTimeCursor)`.
|
|
168
|
+
*
|
|
169
|
+
* @category Pagination
|
|
170
|
+
*/
|
|
171
|
+
export type WindowedFetchFunction<T extends {
|
|
172
|
+
id: string;
|
|
173
|
+
createdTime: Date;
|
|
174
|
+
}> = (cursor: string | undefined, createdTimeCursor: string | undefined) => Promise<PaginatedList<T>>;
|
|
175
|
+
/**
|
|
176
|
+
* Iterates over every row of a data source query. It works around the API's
|
|
177
|
+
* 10,000-result-per-query cap.
|
|
178
|
+
*
|
|
179
|
+
* Data source and view queries cap at 10,000 results. When a query hits this cap, the
|
|
180
|
+
* response's `has_more` field is still `false`. Following `next_cursor` and `has_more`
|
|
181
|
+
* alone silently truncates the result set. When a window hits the cap
|
|
182
|
+
* (`request_status.type === 'incomplete'`), this function starts a new query filtered
|
|
183
|
+
* to `created_time >=` the last row seen. It de-duplicates rows by `id` across the
|
|
184
|
+
* window boundary. The query must sort by `created_time` in ascending order.
|
|
185
|
+
*
|
|
186
|
+
* @param fetchWindow - Function that fetches one page. Pass the current cursor. After
|
|
187
|
+
* a window hits the cap, also pass a `created_time` lower bound for the next window.
|
|
188
|
+
* @yields Individual rows across all windows
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* const rows = collectAllDataSourceRows((cursor, createdTimeCursor) =>
|
|
193
|
+
* notion.dataSources.query(dataSourceId, {
|
|
194
|
+
* start_cursor: cursor,
|
|
195
|
+
* sorts: [{ timestamp: 'created_time', direction: 'ascending' }],
|
|
196
|
+
* filter: createdTimeCursor
|
|
197
|
+
* ? filter.and(baseFilter, filter.createdTime().onOrAfter(createdTimeCursor))
|
|
198
|
+
* : baseFilter,
|
|
199
|
+
* }),
|
|
200
|
+
* );
|
|
201
|
+
* ```
|
|
202
|
+
*
|
|
203
|
+
* @category Pagination
|
|
204
|
+
*/
|
|
205
|
+
export declare function iterateAllDataSourceRows<T extends {
|
|
206
|
+
id: string;
|
|
207
|
+
createdTime: Date;
|
|
208
|
+
}>(fetchWindow: WindowedFetchFunction<T>): AsyncGenerator<T, void, undefined>;
|
|
209
|
+
/**
|
|
210
|
+
* Collects every row of a data source query into an array. It works around the API's
|
|
211
|
+
* 10,000-result-per-query cap. See {@link iterateAllDataSourceRows} for the windowing
|
|
212
|
+
* behavior.
|
|
213
|
+
*
|
|
214
|
+
* @param fetchWindow - Function that fetches one page. Pass the current cursor. After
|
|
215
|
+
* a window hits the cap, also pass a `created_time` lower bound for the next window.
|
|
216
|
+
* @returns Array containing all rows across all windows
|
|
217
|
+
*
|
|
218
|
+
* @category Pagination
|
|
219
|
+
*/
|
|
220
|
+
export declare function collectAllDataSourceRows<T extends {
|
|
221
|
+
id: string;
|
|
222
|
+
createdTime: Date;
|
|
223
|
+
}>(fetchWindow: WindowedFetchFunction<T>): Promise<T[]>;
|
|
@@ -3,11 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.paginate = paginate;
|
|
4
4
|
exports.paginateIterator = paginateIterator;
|
|
5
5
|
exports.paginateWithMetadata = paginateWithMetadata;
|
|
6
|
+
exports.iterateAllDataSourceRows = iterateAllDataSourceRows;
|
|
7
|
+
exports.collectAllDataSourceRows = collectAllDataSourceRows;
|
|
6
8
|
/**
|
|
7
9
|
* Collects all results from a paginated endpoint by automatically following cursors.
|
|
8
10
|
*
|
|
9
|
-
* This function
|
|
10
|
-
*
|
|
11
|
+
* This function fetches pages until `has_more` is `false`. It collects all results
|
|
12
|
+
* into one array. Use this function when you need all results at once.
|
|
11
13
|
*
|
|
12
14
|
* @param fetchPage - Function that fetches a single page of results
|
|
13
15
|
* @returns Array containing all results from all pages
|
|
@@ -47,6 +49,8 @@ exports.paginateWithMetadata = paginateWithMetadata;
|
|
|
47
49
|
* })
|
|
48
50
|
* );
|
|
49
51
|
* ```
|
|
52
|
+
*
|
|
53
|
+
* @category Pagination
|
|
50
54
|
*/
|
|
51
55
|
async function paginate(fetchPage) {
|
|
52
56
|
const all = [];
|
|
@@ -61,9 +65,9 @@ async function paginate(fetchPage) {
|
|
|
61
65
|
/**
|
|
62
66
|
* Creates an async iterator that yields individual items from paginated results.
|
|
63
67
|
*
|
|
64
|
-
* This function
|
|
65
|
-
* one page at a time and
|
|
66
|
-
*
|
|
68
|
+
* This function iterates over large result sets without loading everything into
|
|
69
|
+
* memory. It fetches one page at a time and yields items as needed. Use this function
|
|
70
|
+
* with `for await...of` to process results one at a time.
|
|
67
71
|
*
|
|
68
72
|
* @param fetchPage - Function that fetches a single page of results
|
|
69
73
|
* @yields Individual items from each page
|
|
@@ -98,6 +102,8 @@ async function paginate(fetchPage) {
|
|
|
98
102
|
* console.log(result.url);
|
|
99
103
|
* }
|
|
100
104
|
* ```
|
|
105
|
+
*
|
|
106
|
+
* @category Pagination
|
|
101
107
|
*/
|
|
102
108
|
async function* paginateIterator(fetchPage) {
|
|
103
109
|
let cursor;
|
|
@@ -110,10 +116,10 @@ async function* paginateIterator(fetchPage) {
|
|
|
110
116
|
} while (cursor);
|
|
111
117
|
}
|
|
112
118
|
/**
|
|
113
|
-
* Collects all results
|
|
119
|
+
* Collects all results. Returns the items together with pagination metadata.
|
|
114
120
|
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
121
|
+
* Use this function when you need the page count or the total number of API
|
|
122
|
+
* calls.
|
|
117
123
|
*
|
|
118
124
|
* @param fetchPage - Function that fetches a single page of results
|
|
119
125
|
* @returns Object containing all results and pagination metadata
|
|
@@ -126,6 +132,8 @@ async function* paginateIterator(fetchPage) {
|
|
|
126
132
|
*
|
|
127
133
|
* console.log(`Fetched ${totalCount} blocks across ${pageCount} pages`);
|
|
128
134
|
* ```
|
|
135
|
+
*
|
|
136
|
+
* @category Pagination
|
|
129
137
|
*/
|
|
130
138
|
async function paginateWithMetadata(fetchPage) {
|
|
131
139
|
const items = [];
|
|
@@ -143,3 +151,101 @@ async function paginateWithMetadata(fetchPage) {
|
|
|
143
151
|
totalCount: items.length,
|
|
144
152
|
};
|
|
145
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Iterates over every row of a data source query. It works around the API's
|
|
156
|
+
* 10,000-result-per-query cap.
|
|
157
|
+
*
|
|
158
|
+
* Data source and view queries cap at 10,000 results. When a query hits this cap, the
|
|
159
|
+
* response's `has_more` field is still `false`. Following `next_cursor` and `has_more`
|
|
160
|
+
* alone silently truncates the result set. When a window hits the cap
|
|
161
|
+
* (`request_status.type === 'incomplete'`), this function starts a new query filtered
|
|
162
|
+
* to `created_time >=` the last row seen. It de-duplicates rows by `id` across the
|
|
163
|
+
* window boundary. The query must sort by `created_time` in ascending order.
|
|
164
|
+
*
|
|
165
|
+
* @param fetchWindow - Function that fetches one page. Pass the current cursor. After
|
|
166
|
+
* a window hits the cap, also pass a `created_time` lower bound for the next window.
|
|
167
|
+
* @yields Individual rows across all windows
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```typescript
|
|
171
|
+
* const rows = collectAllDataSourceRows((cursor, createdTimeCursor) =>
|
|
172
|
+
* notion.dataSources.query(dataSourceId, {
|
|
173
|
+
* start_cursor: cursor,
|
|
174
|
+
* sorts: [{ timestamp: 'created_time', direction: 'ascending' }],
|
|
175
|
+
* filter: createdTimeCursor
|
|
176
|
+
* ? filter.and(baseFilter, filter.createdTime().onOrAfter(createdTimeCursor))
|
|
177
|
+
* : baseFilter,
|
|
178
|
+
* }),
|
|
179
|
+
* );
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* @category Pagination
|
|
183
|
+
*/
|
|
184
|
+
async function* iterateAllDataSourceRows(fetchWindow) {
|
|
185
|
+
// Rows repeat across a window boundary only when they share the exact `created_time`
|
|
186
|
+
// used as the next window's lower bound (results are sorted ascending by created_time,
|
|
187
|
+
// so ties are always contiguous). Tracking only that trailing tie group -- instead of
|
|
188
|
+
// every id ever yielded -- keeps memory bounded regardless of result set size.
|
|
189
|
+
let tailTimeMs;
|
|
190
|
+
let tailIds = new Set();
|
|
191
|
+
let cursor;
|
|
192
|
+
let createdTimeCursor;
|
|
193
|
+
let lastCreatedTime;
|
|
194
|
+
let hasMore = true;
|
|
195
|
+
while (hasMore) {
|
|
196
|
+
const response = await fetchWindow(cursor, createdTimeCursor);
|
|
197
|
+
let yieldedThisWindow = false;
|
|
198
|
+
for (const item of response.results) {
|
|
199
|
+
const itemTimeMs = item.createdTime.getTime();
|
|
200
|
+
if (tailTimeMs !== undefined && itemTimeMs === tailTimeMs && tailIds.has(item.id)) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (tailTimeMs === undefined || itemTimeMs > tailTimeMs) {
|
|
204
|
+
tailTimeMs = itemTimeMs;
|
|
205
|
+
tailIds = new Set();
|
|
206
|
+
}
|
|
207
|
+
tailIds.add(item.id);
|
|
208
|
+
lastCreatedTime = item.createdTime;
|
|
209
|
+
yieldedThisWindow = true;
|
|
210
|
+
yield item;
|
|
211
|
+
}
|
|
212
|
+
if (response.request_status?.type === 'incomplete' && lastCreatedTime) {
|
|
213
|
+
// has_more is false here, so normal cursor pagination would silently stop short.
|
|
214
|
+
// Start a fresh window scoped to created_time >= the last row seen, de-duping by
|
|
215
|
+
// id across the boundary (created_time, not last_edited_time -- the latter shifts
|
|
216
|
+
// rows between windows).
|
|
217
|
+
if (!yieldedThisWindow) {
|
|
218
|
+
// Every row in this capped window was already seen, meaning more rows share
|
|
219
|
+
// this exact created_time than fit in one window -- the created_time >= filter
|
|
220
|
+
// can't disambiguate further, so re-querying would return the same page forever.
|
|
221
|
+
throw new Error(`More than one window's worth of rows share the same created_time (${lastCreatedTime.toISOString()}); ` +
|
|
222
|
+
'iterateAllDataSourceRows cannot make forward progress past this timestamp.');
|
|
223
|
+
}
|
|
224
|
+
cursor = undefined;
|
|
225
|
+
createdTimeCursor = lastCreatedTime.toISOString();
|
|
226
|
+
hasMore = true;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
cursor = response.next_cursor ?? undefined;
|
|
230
|
+
hasMore = cursor !== undefined;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Collects every row of a data source query into an array. It works around the API's
|
|
236
|
+
* 10,000-result-per-query cap. See {@link iterateAllDataSourceRows} for the windowing
|
|
237
|
+
* behavior.
|
|
238
|
+
*
|
|
239
|
+
* @param fetchWindow - Function that fetches one page. Pass the current cursor. After
|
|
240
|
+
* a window hits the cap, also pass a `created_time` lower bound for the next window.
|
|
241
|
+
* @returns Array containing all rows across all windows
|
|
242
|
+
*
|
|
243
|
+
* @category Pagination
|
|
244
|
+
*/
|
|
245
|
+
async function collectAllDataSourceRows(fetchWindow) {
|
|
246
|
+
const all = [];
|
|
247
|
+
for await (const item of iterateAllDataSourceRows(fetchWindow)) {
|
|
248
|
+
all.push(item);
|
|
249
|
+
}
|
|
250
|
+
return all;
|
|
251
|
+
}
|
|
@@ -22,8 +22,8 @@ declare function database(databaseId: string): {
|
|
|
22
22
|
};
|
|
23
23
|
/**
|
|
24
24
|
* Create a data source parent object.
|
|
25
|
-
*
|
|
26
|
-
*
|
|
25
|
+
* A page with a data source parent needs both `data_source_id` and
|
|
26
|
+
* `database_id`.
|
|
27
27
|
*
|
|
28
28
|
* @example
|
|
29
29
|
* ```ts
|
|
@@ -51,7 +51,7 @@ declare function workspace(): {
|
|
|
51
51
|
workspace: true;
|
|
52
52
|
};
|
|
53
53
|
/**
|
|
54
|
-
* Create a block parent object
|
|
54
|
+
* Create a block parent object for comments on blocks.
|
|
55
55
|
*
|
|
56
56
|
* @example
|
|
57
57
|
* ```ts
|
|
@@ -86,6 +86,8 @@ declare function blockParent(blockId: string): {
|
|
|
86
86
|
* rich_text: [...],
|
|
87
87
|
* });
|
|
88
88
|
* ```
|
|
89
|
+
*
|
|
90
|
+
* @category Helpers
|
|
89
91
|
*/
|
|
90
92
|
export declare const parent: {
|
|
91
93
|
page: typeof page;
|
|
@@ -28,8 +28,8 @@ function database(databaseId) {
|
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* Create a data source parent object.
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* A page with a data source parent needs both `data_source_id` and
|
|
32
|
+
* `database_id`.
|
|
33
33
|
*
|
|
34
34
|
* @example
|
|
35
35
|
* ```ts
|
|
@@ -56,7 +56,7 @@ function workspace() {
|
|
|
56
56
|
return { workspace: true };
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
|
-
* Create a block parent object
|
|
59
|
+
* Create a block parent object for comments on blocks.
|
|
60
60
|
*
|
|
61
61
|
* @example
|
|
62
62
|
* ```ts
|
|
@@ -94,6 +94,8 @@ function blockParent(blockId) {
|
|
|
94
94
|
* rich_text: [...],
|
|
95
95
|
* });
|
|
96
96
|
* ```
|
|
97
|
+
*
|
|
98
|
+
* @category Helpers
|
|
97
99
|
*/
|
|
98
100
|
exports.parent = {
|
|
99
101
|
page,
|
|
@@ -181,6 +181,34 @@ declare function people(userIds: string[]): {
|
|
|
181
181
|
id: string;
|
|
182
182
|
}>;
|
|
183
183
|
};
|
|
184
|
+
/** Options for the verification property's optional date. */
|
|
185
|
+
interface VerificationDateOptions {
|
|
186
|
+
start: string;
|
|
187
|
+
end?: string | null;
|
|
188
|
+
timeZone?: string | null;
|
|
189
|
+
}
|
|
190
|
+
/** The shape of a verification property value. */
|
|
191
|
+
interface VerificationValue {
|
|
192
|
+
verification: {
|
|
193
|
+
state: 'verified' | 'unverified';
|
|
194
|
+
date?: {
|
|
195
|
+
start: string;
|
|
196
|
+
end: string | null;
|
|
197
|
+
time_zone: string | null;
|
|
198
|
+
} | null;
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Create a verification property value.
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```ts
|
|
206
|
+
* prop.verification('verified')
|
|
207
|
+
* prop.verification('verified', { start: '2025-01-15' })
|
|
208
|
+
* prop.verification('unverified')
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
declare function verification(state: 'verified' | 'unverified', date?: VerificationDateOptions): VerificationValue;
|
|
184
212
|
/** A single file entry for the files' property. */
|
|
185
213
|
interface FileEntry {
|
|
186
214
|
name: string;
|
|
@@ -227,6 +255,8 @@ declare function files(entries: FileEntry[]): {
|
|
|
227
255
|
* },
|
|
228
256
|
* });
|
|
229
257
|
* ```
|
|
258
|
+
*
|
|
259
|
+
* @category Helpers
|
|
230
260
|
*/
|
|
231
261
|
export declare const prop: {
|
|
232
262
|
title: typeof title;
|
|
@@ -243,5 +273,6 @@ export declare const prop: {
|
|
|
243
273
|
relation: typeof relation;
|
|
244
274
|
people: typeof people;
|
|
245
275
|
files: typeof files;
|
|
276
|
+
verification: typeof verification;
|
|
246
277
|
};
|
|
247
278
|
export {};
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.prop = void 0;
|
|
4
4
|
const validation_1 = require("../validation");
|
|
5
5
|
const richText_helpers_1 = require("./richText.helpers");
|
|
6
|
-
/** Resolve rich text input to a `NotionRichText
|
|
6
|
+
/** Resolve rich text input to a `NotionRichText`. */
|
|
7
7
|
function resolveRichText(input) {
|
|
8
8
|
if (typeof input === 'string') {
|
|
9
9
|
(0, validation_1.validateStringLength)(input, validation_1.LIMITS.RICH_TEXT_CONTENT, 'Rich text content');
|
|
@@ -210,6 +210,32 @@ function people(userIds) {
|
|
|
210
210
|
(0, validation_1.validateArrayLength)(userIds, validation_1.LIMITS.PEOPLE, 'People');
|
|
211
211
|
return { people: userIds.map((id) => ({ object: 'user', id })) };
|
|
212
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Create a verification property value.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* prop.verification('verified')
|
|
219
|
+
* prop.verification('verified', { start: '2025-01-15' })
|
|
220
|
+
* prop.verification('unverified')
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
function verification(state, date) {
|
|
224
|
+
return {
|
|
225
|
+
verification: {
|
|
226
|
+
state,
|
|
227
|
+
...(date
|
|
228
|
+
? {
|
|
229
|
+
date: {
|
|
230
|
+
start: date.start,
|
|
231
|
+
end: date.end ?? null,
|
|
232
|
+
time_zone: date.timeZone ?? null,
|
|
233
|
+
},
|
|
234
|
+
}
|
|
235
|
+
: {}),
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
}
|
|
213
239
|
/**
|
|
214
240
|
* Create a files property value.
|
|
215
241
|
*
|
|
@@ -252,6 +278,8 @@ function files(entries) {
|
|
|
252
278
|
* },
|
|
253
279
|
* });
|
|
254
280
|
* ```
|
|
281
|
+
*
|
|
282
|
+
* @category Helpers
|
|
255
283
|
*/
|
|
256
284
|
exports.prop = {
|
|
257
285
|
title,
|
|
@@ -268,4 +296,5 @@ exports.prop = {
|
|
|
268
296
|
relation,
|
|
269
297
|
people,
|
|
270
298
|
files,
|
|
299
|
+
verification,
|
|
271
300
|
};
|
|
@@ -5,8 +5,9 @@ import type { NotionColor, NotionRichText, NotionUser, TextRichText } from '../s
|
|
|
5
5
|
* Do not instantiate directly — use the {@link richText} factory function or
|
|
6
6
|
* the static helpers on it (`richText.mentionPage`, `richText.equation`, etc.).
|
|
7
7
|
*
|
|
8
|
-
* Call `.build()` to produce a
|
|
9
|
-
*
|
|
8
|
+
* Call `.build()` to produce a single-element `NotionRichText`.
|
|
9
|
+
* Alternatively, pass builders directly to `richText.join()`. This method
|
|
10
|
+
* calls `.build()` for you.
|
|
10
11
|
*
|
|
11
12
|
* @example
|
|
12
13
|
* ```ts
|
|
@@ -26,6 +27,8 @@ import type { NotionColor, NotionRichText, NotionUser, TextRichText } from '../s
|
|
|
26
27
|
* richText('!'),
|
|
27
28
|
* );
|
|
28
29
|
* ```
|
|
30
|
+
*
|
|
31
|
+
* @category Rich Text
|
|
29
32
|
*/
|
|
30
33
|
export declare class RichTextBuilder {
|
|
31
34
|
/** @internal */
|
|
@@ -52,7 +55,7 @@ export declare class RichTextBuilder {
|
|
|
52
55
|
*/
|
|
53
56
|
link(url: string): this;
|
|
54
57
|
/**
|
|
55
|
-
* Build a single-element `NotionRichText`
|
|
58
|
+
* Build a single-element `NotionRichText` from this builder.
|
|
56
59
|
*/
|
|
57
60
|
build(): NotionRichText;
|
|
58
61
|
}
|
|
@@ -99,8 +102,8 @@ declare function mentionLinkPreview(url: string): RichTextBuilder;
|
|
|
99
102
|
*/
|
|
100
103
|
declare function equation(expression: string): RichTextBuilder;
|
|
101
104
|
/**
|
|
102
|
-
* Combine multiple rich text builders (or pre-built `NotionRichText`
|
|
103
|
-
* into a single `NotionRichText
|
|
105
|
+
* Combine multiple rich text builders (or pre-built `NotionRichText` values)
|
|
106
|
+
* into a single `NotionRichText`.
|
|
104
107
|
*
|
|
105
108
|
* @example
|
|
106
109
|
* ```ts
|
|
@@ -136,6 +139,8 @@ declare function join(...parts: Array<RichTextBuilder | NotionRichText>): Notion
|
|
|
136
139
|
* richText('italic').italic(),
|
|
137
140
|
* );
|
|
138
141
|
* ```
|
|
142
|
+
*
|
|
143
|
+
* @category Rich Text
|
|
139
144
|
*/
|
|
140
145
|
export declare const richText: typeof createRichText & {
|
|
141
146
|
mentionPage: typeof mentionPage;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.richText = exports.RichTextBuilder = void 0;
|
|
4
4
|
const validation_1 = require("../validation");
|
|
5
5
|
/**
|
|
6
|
-
* Default annotations object with no formatting
|
|
6
|
+
* Default annotations object with no formatting.
|
|
7
7
|
*/
|
|
8
8
|
const DEFAULT_ANNOTATIONS = {
|
|
9
9
|
bold: false,
|
|
@@ -19,8 +19,9 @@ const DEFAULT_ANNOTATIONS = {
|
|
|
19
19
|
* Do not instantiate directly — use the {@link richText} factory function or
|
|
20
20
|
* the static helpers on it (`richText.mentionPage`, `richText.equation`, etc.).
|
|
21
21
|
*
|
|
22
|
-
* Call `.build()` to produce a
|
|
23
|
-
*
|
|
22
|
+
* Call `.build()` to produce a single-element `NotionRichText`.
|
|
23
|
+
* Alternatively, pass builders directly to `richText.join()`. This method
|
|
24
|
+
* calls `.build()` for you.
|
|
24
25
|
*
|
|
25
26
|
* @example
|
|
26
27
|
* ```ts
|
|
@@ -40,6 +41,8 @@ const DEFAULT_ANNOTATIONS = {
|
|
|
40
41
|
* richText('!'),
|
|
41
42
|
* );
|
|
42
43
|
* ```
|
|
44
|
+
*
|
|
45
|
+
* @category Rich Text
|
|
43
46
|
*/
|
|
44
47
|
class RichTextBuilder {
|
|
45
48
|
/** @internal */
|
|
@@ -93,7 +96,7 @@ class RichTextBuilder {
|
|
|
93
96
|
return this;
|
|
94
97
|
}
|
|
95
98
|
/**
|
|
96
|
-
* Build a single-element `NotionRichText`
|
|
99
|
+
* Build a single-element `NotionRichText` from this builder.
|
|
97
100
|
*/
|
|
98
101
|
build() {
|
|
99
102
|
return [{ ...this.segment, annotations: { ...this.annotations } }];
|
|
@@ -218,8 +221,8 @@ function equation(expression) {
|
|
|
218
221
|
return new RichTextBuilder(segment);
|
|
219
222
|
}
|
|
220
223
|
/**
|
|
221
|
-
* Combine multiple rich text builders (or pre-built `NotionRichText`
|
|
222
|
-
* into a single `NotionRichText
|
|
224
|
+
* Combine multiple rich text builders (or pre-built `NotionRichText` values)
|
|
225
|
+
* into a single `NotionRichText`.
|
|
223
226
|
*
|
|
224
227
|
* @example
|
|
225
228
|
* ```ts
|
|
@@ -269,6 +272,8 @@ function join(...parts) {
|
|
|
269
272
|
* richText('italic').italic(),
|
|
270
273
|
* );
|
|
271
274
|
* ```
|
|
275
|
+
*
|
|
276
|
+
* @category Rich Text
|
|
272
277
|
*/
|
|
273
278
|
exports.richText = Object.assign(createRichText, {
|
|
274
279
|
mentionPage,
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sign a payload to generate test webhook signatures.
|
|
3
|
+
*
|
|
4
|
+
* @param body - The payload to sign. This function signs a string as-is. It
|
|
5
|
+
* converts anything else with `JSON.stringify` first. This is safe because the
|
|
6
|
+
* caller controls the serialization of their own payload.
|
|
7
|
+
* @param verificationToken - The webhook subscription's verification token
|
|
8
|
+
* @returns The `sha256=<hex digest>` signature
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const signature = webhook.sign({ event: 'page.updated' }, verificationToken);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
declare function sign(body: unknown, verificationToken: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Verify an incoming webhook's `X-Notion-Signature` header via constant-time comparison.
|
|
18
|
+
*
|
|
19
|
+
* IMPORTANT: `rawBody` must be the exact raw request body that Notion sent. Do not use
|
|
20
|
+
* `JSON.stringify(parsedBody)`. Re-serializing a parsed object can produce a different
|
|
21
|
+
* byte sequence (key order, whitespace) than the original signed body, and this
|
|
22
|
+
* silently breaks verification. Use your framework's raw-body access, for example
|
|
23
|
+
* Express's `express.raw()` or `req.rawBody`. Do not use `req.body` after JSON
|
|
24
|
+
* middleware parses it.
|
|
25
|
+
*
|
|
26
|
+
* @param rawBody - The exact raw request body string Notion sent
|
|
27
|
+
* @param signatureHeader - The value of the `X-Notion-Signature` request header
|
|
28
|
+
* @param verificationToken - The webhook subscription's verification token
|
|
29
|
+
* @returns `true` if the signature is valid. Returns `false` for a mismatch or
|
|
30
|
+
* malformed input. This function never throws.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* const isValid = webhook.verifySignature(rawBody, req.headers['x-notion-signature'], verificationToken);
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare function verifySignature(rawBody: string, signatureHeader: string | null | undefined, verificationToken: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Helpers for signing and verifying Notion webhook payloads.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* import { webhook } from '@visus-io/notion-sdk-ts';
|
|
44
|
+
*
|
|
45
|
+
* const isValid = webhook.verifySignature(rawBody, req.headers['x-notion-signature'], verificationToken);
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @category Helpers
|
|
49
|
+
*/
|
|
50
|
+
export declare const webhook: {
|
|
51
|
+
sign: typeof sign;
|
|
52
|
+
verifySignature: typeof verifySignature;
|
|
53
|
+
};
|
|
54
|
+
export {};
|