npm package: @incedoinc/connect-web-sdk
Description: A modern TypeScript SDK for integrating Incedo Connect financial services with support for inline and modal dialog modes
Author: Incedo Inc
Latest version: 2.0.1

# Incedo Connect Web SDK

A modern, TypeScript-first SDK for integrating with Incedo Connect financial services. This SDK provides a simple interface for embedding payment connection flows in your web applications with support for both inline and modal dialog modes.

## Features

- 🚀 **Modern TypeScript** - Full type safety and IntelliSense support
- 🎯 **Multiple Display Modes** - Inline and dialog modal rendering
- 📱 **Responsive Design** - Works seamlessly across desktop and mobile
- 🔧 **Easy Integration** - Simple API with comprehensive callbacks
- 🎨 **Customizable** - Flexible styling and configuration options
- 📦 **Zero Dependencies** - Lightweight with no external dependencies
- 🎪 **Event Manager Integration** - Robust event handling with typed events
- 🔄 **Real-time Events** - Listen to user interactions and flow progress

## Installation

```bash
npm install @incedoinc/connect-web-sdk
```

```bash
yarn add @incedoinc/connect-web-sdk
```

```bash
pnpm add @incedoinc/connect-web-sdk
```

## Quick Start

### Basic Usage (v2.0.0)

```typescript
import { ConnectSDK } from '@incedoinc/connect-web-sdk';

const sdk = new ConnectSDK();

// Launch in inline mode
sdk.launch({
  connectUrl: 'https://your-connect-url.com',
  mode: 'inline',
  container: document.getElementById('connect-container'),
  onEvent: (event) => {
    if (event.eventName === 'INSTITUTION_SELECTED') {
      console.log('Selected institution:', event.data);
    } else if (event.eventName === 'ACCOUNTS_SELECTED') {
      console.log('Selected accounts:', event.data);
    }
  },
  onDone: (event) => {
    console.log('Flow completed:', event);
  },
  onLoad: (event) => {
    console.log('Interface loaded at:', event.timestamp);
  },
  onError: (event) => {
    console.error('Error occurred:', event.errorMessage);
  }
});
```

### Dialog Mode

```typescript
sdk.launch({
  connectUrl: 'https://your-connect-url.com',
  mode: 'dialog',
  dialogOptions: {
    title: 'Connect Your Bank Account',
    width: '800px',
    height: '600px',
    closable: true
  },
  onEvent: (event) => {
    console.log('Event received:', event.eventName, event);
    if (event.eventName === 'ACCOUNTS_SELECTED') {
      sdk.cleanup(); // Close the dialog after account selection
    }
  }
});
```

## API Reference

### ConnectSDK

The main SDK class for managing iframe connections.

#### Methods

##### `launch(options: LaunchOptions): void`

Launches the Connect iframe with the specified options.

##### `cleanup(): void`

Cleans up the current iframe and removes all event listeners.

### Types

#### `LaunchOptions`

```typescript
type LaunchOptions = {
  connectUrl: string;                    // Required: URL to load in iframe
  container?: HTMLElement;               // Container for inline mode
  onLoad?: (event: LoadEvent) => void;   // Called when interface loads
  onError?: (event: ErrorEvent) => void; // Called on errors
  onEvent?: (event: ConnectEvent) => void; // Called for domain events (INSTITUTION_SELECTED, ACCOUNTS_SELECTED, TRANSITION)
  onDone?: (event: DoneEvent) => void;   // Called when flow completes
  mode?: 'inline' | 'dialog';          // Display mode (default: 'inline')
  dialogOptions?: DialogOptions;        // Dialog configuration
};
```

#### Event Types

The SDK uses a comprehensive event system with typed events:

##### `LoadEvent`
```typescript
type LoadEvent = {
  eventName: 'LOADED';
  timestamp: number;
  provider: string;
};
```

##### `ErrorEvent`
```typescript
type ErrorEvent = {
  eventName: 'ERROR';
  timestamp: number;
  provider: string;
  errorMessage: string;
};
```

##### `ConnectEvent`
```typescript
type ConnectEvent = 
  | InstitutionSelectedEvent
  | AccountsSelectedEvent
  | TransitionEvent;

type InstitutionSelectedEvent = {
  eventName: 'INSTITUTION_SELECTED';
  timestamp: number;
  provider: string;
  data: InstitutionData;
};

type AccountsSelectedEvent = {
  eventName: 'ACCOUNTS_SELECTED';
  timestamp: number;
  provider: string;
  data: {
    accounts: Account[];
    selectedAccountGuids: string[];
  };
};

type TransitionEvent = {
  eventName: 'TRANSITION';
  timestamp: number;
  provider: string;
  data: {
    from: string;
    to: string;
  };
};
```

##### `DoneEvent`
```typescript
type DoneEvent = {
  eventName: 'DONE';
  timestamp: number;
  provider: string;
  data?: any;
};
```
#### `InstitutionData`

```typescript
type InstitutionData = {
  id: string;
  name: string;
  type: string;
  rating?: number;
  logo?: string;
};
```

#### `Account`

```typescript
type Account = {
  accountId: string;
  accountName: string;
  accountType: string;
  accountNumber: string;
  balance: number;
  currency: string;
};
```

#### `DialogOptions`

```typescript
type DialogOptions = {
  width?: string;          // Dialog width (e.g., '800px', '80%')
  height?: string;         // Dialog height (e.g., '600px', '80vh')
  title?: string;          // Dialog title
  closable?: boolean;      // Whether dialog can be closed
  backdrop?: boolean;      // Whether to show backdrop
  onClose?: () => void;    // Callback when dialog is closed
};
```

## Display Modes

### Inline Mode

Embeds the Connect interface directly into your page within a specified container.

```typescript
sdk.launch({
  connectUrl: 'https://your-connect-url.com',
  mode: 'inline',
  container: document.getElementById('my-container')
});
```

### Dialog Mode

Opens the Connect interface in a modal dialog overlay.

```typescript
sdk.launch({
  connectUrl: 'https://your-connect-url.com',
  mode: 'dialog',
  dialogOptions: {
    title: 'Connect Your Account',
    width: '90%',
    height: '80vh',
    closable: true
  }
});
```

## Event Handling

The SDK v2.0.0 uses a comprehensive event system with typed events:

```typescript
sdk.launch({
  connectUrl: 'https://your-connect-url.com',
  onLoad: (event) => {
    console.log('Connect interface loaded at:', event.timestamp);
  },
  onEvent: (event) => {
    switch (event.eventName) {
      case 'INSTITUTION_SELECTED':
        console.log('Institution selected:', event.data);
        break;
      case 'ACCOUNTS_SELECTED':
        console.log('Accounts selected:', event.data.accounts);
        console.log('Selected GUIDs:', event.data.selectedAccountGuids);
        break;
      case 'TRANSITION':
        console.log('Flow transition:', event.data.from, '->', event.data.to);
        break;
    }
  },
  onDone: (event) => {
    console.log('Flow completed at:', event.timestamp);
    // Handle completion
  },
  onError: (event) => {
    console.error('Error occurred:', event.errorMessage);
    // Handle errors appropriately
  }
});
```

## Migration from v1.x.x

### Breaking Changes in v2.0.0

The callback system has been completely overhauled for better type safety and event handling:

#### Before (v1.x.x)
```typescript
sdk.launch({
  connectUrl: 'https://example.com',
  onInstitutionSelection: (institution) => {
    console.log('Selected:', institution);
  },
  onCancel: () => {
    console.log('User cancelled');
  }
});
```

#### After (v2.0.0)
```typescript
sdk.launch({
  connectUrl: 'https://example.com',
  onEvent: (event) => {
    if (event.eventName === 'INSTITUTION_SELECTED') {
      console.log('Selected:', event.data);
    }
  },
  onDone: (event) => {
    console.log('Flow completed:', event);
  }
});
```

### Key Changes:
- ✅ `onInstitutionSelection` → `onEvent` (with event filtering)
- ✅ `onCancel` → `onDone` 
- ✅ Enhanced `onLoad` and `onError` with event objects
- ✅ New `ACCOUNTS_SELECTED` and `TRANSITION` events
- ✅ Improved type safety with structured events
---

## Examples

### React Integration

```tsx
import React, { useRef, useEffect } from 'react';
import { ConnectSDK } from '@incedoinc/connect-web-sdk';

function ConnectComponent() {
  const containerRef = useRef<HTMLDivElement>(null);
  const sdkRef = useRef<ConnectSDK>();

  useEffect(() => {
    if (containerRef.current) {
      sdkRef.current = new ConnectSDK();
      
      sdkRef.current.launch({
        connectUrl: 'https://your-connect-url.com',
        mode: 'inline',
        container: containerRef.current,
        onEvent: (event) => {
          if (event.eventName === 'INSTITUTION_SELECTED') {
            console.log('Selected:', event.data);
          }
        },
        onDone: (event) => {
          console.log('Flow completed:', event);
        }
      });
    }

    return () => {
      sdkRef.current?.cleanup();
    };
  }, []);

  return <div ref={containerRef} style={{ width: '100%', height: '600px' }} />;
}
```

### Vanilla JavaScript

```html
<!DOCTYPE html>
<html>
<head>
  <title>Connect SDK Example</title>
</head>
<body>
  <div id="connect-container"></div>
  
  <script type="module">
    import { ConnectSDK } from '@incedoinc/connect-web-sdk';
    
    const sdk = new ConnectSDK();
    
    sdk.launch({
      connectUrl: 'https://your-connect-url.com',
      mode: 'inline',
      container: document.getElementById('connect-container'),
      onEvent: (event) => {
        if (event.eventName === 'INSTITUTION_SELECTED') {
          alert(`Selected: ${event.data.name}`);
        }
      }
    });
  </script>
</body>
</html>
```

### Advanced Event Handling

```typescript
import { ConnectSDK } from '@incedoinc/connect-web-sdk';

const sdk = new ConnectSDK();

sdk.launch({
  connectUrl: 'https://your-connect-url.com',
  mode: 'dialog',
  dialogOptions: {
    title: 'Select Your Bank',
    width: '900px',
    height: '700px'
  },
  onLoad: (event) => {
    console.log(`Interface loaded from ${event.provider} at ${new Date(event.timestamp)}`);
  },
  onEvent: (event) => {
    console.log(`Event: ${event.eventName} from ${event.provider}`);
    
    switch (event.eventName) {
      case 'TRANSITION':
        console.log(`Navigating from ${event.data.from} to ${event.data.to}`);
        break;
        
      case 'INSTITUTION_SELECTED':
        console.log(`Selected institution: ${event.data.name} (${event.data.id})`);
        break;
        
      case 'ACCOUNTS_SELECTED':
        console.log(`Selected ${event.data.accounts.length} accounts`);
        event.data.accounts.forEach(account => {
          console.log(`- ${account.accountName}: $${account.balance}`);
        });
        break;
    }
  },
  onDone: (event) => {
    console.log('Connect flow completed successfully');
    sdk.cleanup(); // Clean up resources
  },
  onError: (event) => {
    console.error(`Error from ${event.provider}: ${event.errorMessage}`);
    // Handle error (show user message, retry, etc.)
  }
});
```

## Browser Support

- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Support

For support and questions:

- 📧 Email: npm-admins@incedoinc.com