@@ -223,73 +223,94 @@ export class NotionAPI {
223223 }
224224
225225 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+ }
229229
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 )
265255 }
266256 }
257+ }
267258
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 )
271262
272- if ( ! pendingRelationPageIds . length ) {
273- break // No new related pages to fetch
274- }
263+ if ( ! missingRelationPageIds . length ) break
275264
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
289277 }
290278 }
291279
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
293314 }
294315
295316 public async addSignedUrls ( {
0 commit comments