@@ -53,6 +53,7 @@ export class NotionAPI {
53
53
chunkNumber = 0 ,
54
54
throwOnCollectionErrors = false ,
55
55
collectionReducerLimit = 999 ,
56
+ fetchRelationPages = true , // New option
56
57
kyOptions
57
58
} : {
58
59
concurrency ?: number
@@ -63,6 +64,7 @@ export class NotionAPI {
63
64
chunkNumber ?: number
64
65
throwOnCollectionErrors ?: boolean
65
66
collectionReducerLimit ?: number
67
+ fetchRelationPages ?: boolean // New option
66
68
kyOptions ?: KyOptions
67
69
} = { }
68
70
) : Promise < notion . ExtendedRecordMap > {
@@ -220,6 +222,73 @@ export class NotionAPI {
220
222
await this . addSignedUrls ( { recordMap, contentBlockIds, kyOptions } )
221
223
}
222
224
225
+ if ( fetchRelationPages ) {
226
+ const maxIterations = 10 // Limit iterations to prevent infinite loops
227
+ for ( let i = 0 ; i < maxIterations ; ++ i ) {
228
+ const allRelationPageIdsInThisIteration = new Set < string > ( )
229
+
230
+ for ( const blockId of Object . keys ( recordMap . block ) ) {
231
+ const blockValue = recordMap . block [ blockId ] ?. value
232
+ if (
233
+ blockValue ?. parent_table === 'collection' &&
234
+ blockValue ?. parent_id
235
+ ) {
236
+ const collection = recordMap . collection [ blockValue . parent_id ] ?. value
237
+ if ( collection ?. schema ) {
238
+ for ( const propertyId of Object . keys (
239
+ blockValue . properties || { }
240
+ ) ) {
241
+ const schema = collection . schema [ propertyId ]
242
+ if ( schema ?. type === 'relation' ) {
243
+ const decorations = blockValue . properties ! [ propertyId ]
244
+ if ( decorations && Array . isArray ( decorations ) ) {
245
+ for ( const decoration of decorations ) {
246
+ if (
247
+ Array . isArray ( decoration ) &&
248
+ decoration . length > 1 &&
249
+ decoration [ 0 ] === '‣'
250
+ ) {
251
+ const pagePointer = decoration [ 1 ] ?. [ 0 ]
252
+ if (
253
+ Array . isArray ( pagePointer ) &&
254
+ pagePointer . length > 1 &&
255
+ pagePointer [ 0 ] === 'p'
256
+ ) {
257
+ allRelationPageIdsInThisIteration . add ( pagePointer [ 1 ] )
258
+ }
259
+ }
260
+ }
261
+ }
262
+ }
263
+ }
264
+ }
265
+ }
266
+ }
267
+
268
+ const pendingRelationPageIds = Array . from (
269
+ allRelationPageIdsInThisIteration
270
+ ) . filter ( ( id ) => ! recordMap . block [ id ] ?. value )
271
+
272
+ if ( ! pendingRelationPageIds . length ) {
273
+ break // No new related pages to fetch
274
+ }
275
+
276
+ try {
277
+ const newBlocks = await this . getBlocks (
278
+ pendingRelationPageIds ,
279
+ kyOptions
280
+ ) . then ( ( res ) => res . recordMap . block )
281
+ recordMap . block = { ...recordMap . block , ...newBlocks }
282
+ } catch ( err : any ) {
283
+ console . warn (
284
+ 'NotionAPI getBlocks error during fetchRelationPages:' ,
285
+ err . message
286
+ )
287
+ //TODO: Decide if we should break or continue if some blocks fail
288
+ }
289
+ }
290
+ }
291
+
223
292
return recordMap
224
293
}
225
294
0 commit comments