@@ -223,73 +223,94 @@ export class NotionAPI {
223
223
}
224
224
225
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 > ( )
226
+ const newBlocks = await this . fetchRelationPages ( recordMap , kyOptions )
227
+ recordMap . block = { ... recordMap . block , ... newBlocks }
228
+ }
229
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
- }
230
+ return recordMap
231
+ }
232
+
233
+ fetchRelationPages = async (
234
+ recordMap : notion . ExtendedRecordMap ,
235
+ kyOptions : KyOptions | undefined
236
+ ) : Promise < notion . BlockMap > => {
237
+ const maxIterations = 10
238
+
239
+ for ( let i = 0 ; i < maxIterations ; ++ i ) {
240
+ const relationPageIdsThisIteration = new Set < string > ( )
241
+
242
+ for ( const blockId of Object . keys ( recordMap . block ) ) {
243
+ const blockValue = recordMap . block [ blockId ] ?. value
244
+ if (
245
+ blockValue ?. parent_table === 'collection' &&
246
+ blockValue ?. parent_id
247
+ ) {
248
+ const collection = recordMap . collection [ blockValue . parent_id ] ?. value
249
+ if ( collection ?. schema ) {
250
+ const ids = this . extractRelationPageIdsFromBlock (
251
+ blockValue ,
252
+ collection . schema
253
+ )
254
+ for ( const id of ids ) relationPageIdsThisIteration . add ( id )
265
255
}
266
256
}
257
+ }
267
258
268
- const pendingRelationPageIds = Array . from (
269
- allRelationPageIdsInThisIteration
270
- ) . filter ( ( id ) => ! recordMap . block [ id ] ?. value )
259
+ const missingRelationPageIds = Array . from (
260
+ relationPageIdsThisIteration
261
+ ) . filter ( ( id ) => ! recordMap . block [ id ] ?. value )
271
262
272
- if ( ! pendingRelationPageIds . length ) {
273
- break // No new related pages to fetch
274
- }
263
+ if ( ! missingRelationPageIds . length ) break
275
264
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
- }
265
+ try {
266
+ const newBlocks = await this . getBlocks (
267
+ missingRelationPageIds ,
268
+ kyOptions
269
+ ) . then ( ( res ) => res . recordMap . block )
270
+ recordMap . block = { ...recordMap . block , ...newBlocks }
271
+ } catch ( err : any ) {
272
+ console . warn (
273
+ 'NotionAPI getBlocks error during fetchRelationPages:' ,
274
+ err
275
+ )
276
+ // consider break or delay/retry here
289
277
}
290
278
}
291
279
292
- return recordMap
280
+ return recordMap . block
281
+ }
282
+
283
+ extractRelationPageIdsFromBlock = (
284
+ blockValue : any ,
285
+ collectionSchema : any
286
+ ) : Set < string > => {
287
+ const pageIds = new Set < string > ( )
288
+
289
+ for ( const propertyId of Object . keys ( blockValue . properties || { } ) ) {
290
+ const schema = collectionSchema [ propertyId ]
291
+ if ( schema ?. type === 'relation' ) {
292
+ const decorations = blockValue . properties [ propertyId ]
293
+ if ( Array . isArray ( decorations ) ) {
294
+ for ( const decoration of decorations ) {
295
+ if (
296
+ Array . isArray ( decoration ) &&
297
+ decoration . length > 1 &&
298
+ decoration [ 0 ] === '‣'
299
+ ) {
300
+ const pagePointer = decoration [ 1 ] ?. [ 0 ]
301
+ if (
302
+ Array . isArray ( pagePointer ) &&
303
+ pagePointer . length > 1 &&
304
+ pagePointer [ 0 ] === 'p'
305
+ ) {
306
+ pageIds . add ( pagePointer [ 1 ] )
307
+ }
308
+ }
309
+ }
310
+ }
311
+ }
312
+ }
313
+ return pageIds
293
314
}
294
315
295
316
public async addSignedUrls ( {
0 commit comments