@@ -2,8 +2,9 @@ import { inject, injectable } from 'inversify';
22
33import { logger } from '../../../platform/logging' ;
44import { IDeepnoteNotebookManager } from '../../types' ;
5- import { DATAFRAME_SQL_INTEGRATION_ID , IntegrationStatus , IntegrationWithStatus } from './integrationTypes' ;
5+ import { IntegrationStatus , IntegrationWithStatus } from './integrationTypes' ;
66import { IIntegrationDetector , IIntegrationStorage } from './types' ;
7+ import { BlockWithIntegration , scanBlocksForIntegrations } from './integrationUtils' ;
78
89/**
910 * Service for detecting integrations used in Deepnote notebooks
@@ -19,55 +20,31 @@ export class IntegrationDetector implements IIntegrationDetector {
1920 * Detect all integrations used in the given project
2021 */
2122 async detectIntegrations ( projectId : string ) : Promise < Map < string , IntegrationWithStatus > > {
22- const integrations = new Map < string , IntegrationWithStatus > ( ) ;
23-
2423 // Get the project
2524 const project = this . notebookManager . getOriginalProject ( projectId ) ;
2625 if ( ! project ) {
2726 logger . warn (
2827 `IntegrationDetector: No project found for ID: ${ projectId } . The project may not have been loaded yet.`
2928 ) ;
30- return integrations ;
29+ return new Map ( ) ;
3130 }
3231
3332 logger . debug (
3433 `IntegrationDetector: Scanning project ${ projectId } with ${ project . project . notebooks . length } notebooks`
3534 ) ;
3635
37- // Scan all notebooks in the project
36+ // Collect all blocks with SQL integration metadata from all notebooks
37+ const blocksWithIntegrations : BlockWithIntegration [ ] = [ ] ;
3838 for ( const notebook of project . project . notebooks ) {
3939 logger . trace ( `IntegrationDetector: Scanning notebook ${ notebook . id } with ${ notebook . blocks . length } blocks` ) ;
4040
41- // Scan all blocks in the notebook
4241 for ( const block of notebook . blocks ) {
4342 // Check if this is a code block with SQL integration metadata
4443 if ( block . type === 'code' && block . metadata ?. sql_integration_id ) {
45- const integrationId = block . metadata . sql_integration_id ;
46-
47- // Skip excluded integrations (e.g., internal DuckDB integration)
48- if ( integrationId === DATAFRAME_SQL_INTEGRATION_ID ) {
49- logger . trace (
50- `IntegrationDetector: Skipping excluded integration: ${ integrationId } in block ${ block . id } `
51- ) ;
52- continue ;
53- }
54-
55- logger . debug ( `IntegrationDetector: Found integration: ${ integrationId } in block ${ block . id } ` ) ;
56-
57- // Skip if we've already detected this integration
58- if ( integrations . has ( integrationId ) ) {
59- continue ;
60- }
61-
62- // Check if the integration is configured
63- const config = await this . integrationStorage . get ( integrationId ) ;
64-
65- const status : IntegrationWithStatus = {
66- config : config || null ,
67- status : config ? IntegrationStatus . Connected : IntegrationStatus . Disconnected
68- } ;
69-
70- integrations . set ( integrationId , status ) ;
44+ blocksWithIntegrations . push ( {
45+ id : block . id ,
46+ sql_integration_id : block . metadata . sql_integration_id
47+ } ) ;
7148 } else if ( block . type === 'code' ) {
7249 logger . trace (
7350 `IntegrationDetector: Block ${ block . id } has no sql_integration_id. Metadata:` ,
@@ -77,8 +54,8 @@ export class IntegrationDetector implements IIntegrationDetector {
7754 }
7855 }
7956
80- logger . debug ( `IntegrationDetector: Found ${ integrations . size } integrations` ) ;
81- return integrations ;
57+ // Use the shared utility to scan blocks and build the status map
58+ return scanBlocksForIntegrations ( blocksWithIntegrations , this . integrationStorage , 'IntegrationDetector' ) ;
8259 }
8360
8461 /**
0 commit comments