npm package: @flocomp/flocomp-sdk
Description: Flocomp JavaScript SDK for chatflow execution with automatic OAuth handling
Author: Flocomp
Latest version: 1.0.0

# @flocomp/sdk

Official JavaScript SDK for Flocomp chatflow execution with **automatic OAuth handling**.

[![npm version](https://img.shields.io/npm/v/@flocomp/sdk.svg)](https://www.npmjs.com/package/@flocomp/sdk)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Features

✅ **Simple API** - Just 4 functions to master
✅ **Stateless** - No message/state management
✅ **OAuth Automation** - Seamless tool authentication
✅ **TypeScript First** - Full type safety
✅ **Lightweight** - < 15 KB bundle (gzipped)
✅ **Universal** - Works in browsers and Node.js

---

## Installation

```bash
npm install @flocomp/sdk
```

Or with yarn:

```bash
yarn add @flocomp/sdk
```

Or via CDN (UMD):

```html
<script src="https://unpkg.com/@flocomp/sdk/dist/umd/flocomp-sdk.min.js"></script>
```

---

## Quick Start

```typescript
import { createFlocomp } from '@flocomp/sdk';

// Initialize SDK
const flocomp = createFlocomp({
  apiKey: 'your-api-key',
  flowId: 'your-flow-id', // Optional, can be set per request
});

// Send a message
const result = await flocomp.sendMessage('Send a Slack message to #general');

// Handle response
if (result.status === 'completed') {
  console.log('Response:', result.message);
} else if (result.status === 'oauth_required') {
  // OAuth needed - open auth URL
  window.open(result.authUrl, '_blank');
} else {
  console.error('Error:', result.error);
}
```

---

## API Reference

### Factory Function

```typescript
createFlocomp(config: FlocompConfig): FlocompSDK
```

Creates a new SDK instance.

**Configuration:**

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| `apiKey` | `string` | ✅ | - | API authentication key |
| `baseUrl` | `string` | ❌ | `https://api.flocomp.com` | API base URL |
| `flowId` | `string` | ❌ | - | Default flow ID |
| `debug` | `boolean` | ❌ | `false` | Enable debug logging |
| `timeout` | `number` | ❌ | `30000` | Request timeout (ms) |

---

### Core Methods

#### `sendMessage(message: string, flowId?: string): Promise<FlowResponse>`

Sends a message to execute a chatflow.

**Parameters:**
- `message` - The message to send
- `flowId` - Optional flow ID (overrides config)

**Returns:** Promise with one of:

```typescript
// Success
{ status: 'completed'; message: string; toolUsed?: string }

// OAuth required
{ status: 'oauth_required'; toolName: string; authUrl: string }

// Error
{ status: 'error'; error: string }
```

---

#### `getAuthUrl(toolName: string): Promise<string>`

Gets OAuth authorization URL for a specific tool.

**Parameters:**
- `toolName` - Name of the tool (e.g., 'slack', 'gmail')

**Returns:** Promise with OAuth URL string

**Example:**
```typescript
const slackUrl = await flocomp.getAuthUrl('slack');
window.open(slackUrl, '_blank');
```

---

#### `handleOAuthRedirect(params: string | Record<string, any>): Promise<void>`

Handles OAuth redirect callback after user authorizes.

**Parameters:**
- `params` - Query string or parsed params object

**Example:**
```typescript
// From URL query string
await flocomp.handleOAuthRedirect(window.location.search);

// From object
await flocomp.handleOAuthRedirect({ code: 'abc', state: 'xyz' });
```

---

#### `onOAuthComplete(callback: () => void): void`

Registers a callback to run when OAuth completes.

**Parameters:**
- `callback` - Function to call after OAuth completion

**Example:**
```typescript
flocomp.onOAuthComplete(() => {
  console.log('OAuth completed! Retrying...');
  flocomp.sendMessage('Send Slack message');
});
```

---

## Usage Examples

### Basic React Example

```tsx
import { createFlocomp } from '@flocomp/sdk';
import { useState, useEffect } from 'react';

function ChatApp() {
  const [flocomp] = useState(() => createFlocomp({ apiKey: 'key123' }));
  const [response, setResponse] = useState('');
  const [oauthUrl, setOauthUrl] = useState<string | null>(null);

  // Handle OAuth redirect
  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    if (params.has('code')) {
      flocomp.handleOAuthRedirect(params.toString());
    }
  }, [flocomp]);

  // Register OAuth completion callback
  useEffect(() => {
    flocomp.onOAuthComplete(() => {
      console.log('OAuth completed!');
      setOauthUrl(null);
    });
  }, [flocomp]);

  async function handleSend(message: string) {
    const result = await flocomp.sendMessage(message);

    if (result.status === 'completed') {
      setResponse(result.message);
    } else if (result.status === 'oauth_required') {
      setOauthUrl(result.authUrl);
    } else {
      console.error(result.error);
    }
  }

  return (
    <div>
      <input onSubmit={(e) => handleSend(e.target.value)} />

      {oauthUrl && (
        <button onClick={() => window.open(oauthUrl, '_blank')}>
          Connect Tool
        </button>
      )}

      {response && <div>{response}</div>}
    </div>
  );
}
```

---

### Vanilla JavaScript (Browser)

```html
<!DOCTYPE html>
<html>
<head>
  <title>Flocomp SDK Example</title>
</head>
<body>
  <input id="message" type="text" placeholder="Type your message..." />
  <button id="send">Send</button>
  <div id="response"></div>

  <script src="https://unpkg.com/@flocomp/sdk/dist/umd/flocomp-sdk.min.js"></script>
  <script>
    const flocomp = FlocompSDK.createFlocomp({
      apiKey: 'your-api-key',
      debug: true
    });

    // Handle OAuth redirect
    const params = new URLSearchParams(window.location.search);
    if (params.has('code')) {
      flocomp.handleOAuthRedirect(window.location.search);
    }

    // Send message
    document.getElementById('send').addEventListener('click', async () => {
      const message = document.getElementById('message').value;
      const result = await flocomp.sendMessage(message);

      if (result.status === 'completed') {
        document.getElementById('response').innerText = result.message;
      } else if (result.status === 'oauth_required') {
        window.open(result.authUrl, '_blank');
      }
    });
  </script>
</body>
</html>
```

---

### Next.js App Router

```tsx
'use client';

import { createFlocomp } from '@flocomp/sdk';
import { useEffect, useState } from 'react';

export default function ChatPage() {
  const [flocomp] = useState(() => createFlocomp({
    apiKey: process.env.NEXT_PUBLIC_API_KEY!,
    baseUrl: process.env.NEXT_PUBLIC_API_URL,
  }));

  useEffect(() => {
    // Handle OAuth redirect
    if (typeof window !== 'undefined') {
      const params = new URLSearchParams(window.location.search);
      if (params.has('code')) {
        flocomp.handleOAuthRedirect(params.toString());
      }
    }
  }, [flocomp]);

  async function handleMessage(msg: string) {
    const result = await flocomp.sendMessage(msg);
    // Handle result...
  }

  return <div>...</div>;
}
```

---

### Pre-fetching OAuth URLs

```typescript
import { createFlocomp } from '@flocomp/sdk';

const flocomp = createFlocomp({ apiKey: 'key123' });

// Pre-fetch OAuth URLs for tools
async function showConnectionOptions() {
  const slackUrl = await flocomp.getAuthUrl('slack');
  const gmailUrl = await flocomp.getAuthUrl('gmail');

  // Show "Connect Slack" and "Connect Gmail" buttons
  renderToolButtons([
    { name: 'Slack', url: slackUrl },
    { name: 'Gmail', url: gmailUrl },
  ]);
}
```

---

## Examples

We provide complete working examples for different frameworks:

### 🚀 [React Example](./examples/react)
Complete React + Vite example with OAuth flow
- Vite dev server
- TypeScript
- Full OAuth implementation
- Environment configuration

```bash
cd examples/react
npm install
npm run dev
```

### 📦 [Vanilla JavaScript Example](./examples/vanilla-js)
Pure JavaScript example without frameworks
- ES modules
- No build step required
- Simple and straightforward

```bash
cd examples/vanilla-js
npm install
npm run dev
```

### ⚡ [Next.js Example](./examples/nextjs)
Next.js App Router with client components
- App Router architecture
- Server/client component patterns
- Environment variables
- TypeScript

```bash
cd examples/nextjs
npm install
npm run dev
```

Each example includes:
- ✅ Complete source code
- ✅ README with setup instructions
- ✅ OAuth flow implementation
- ✅ Error handling
- ✅ Type safety

---

## TypeScript Support

Full TypeScript support with exported types:

```typescript
import type {
  FlocompConfig,
  FlowResponse,
  FlowCompletedResponse,
  OAuthRequiredResponse,
  FlowErrorResponse,
} from '@flocomp/sdk';

// Type guards
import { isCompletedResponse, isOAuthRequiredResponse, isErrorResponse } from '@flocomp/sdk';

const result = await flocomp.sendMessage('Hello');

if (isCompletedResponse(result)) {
  console.log(result.message); // TypeScript knows this is FlowCompletedResponse
}
```

---

## Error Handling

The SDK returns errors as part of the `FlowResponse` and never throws for flow execution errors:

```typescript
const result = await flocomp.sendMessage('Hello');

if (result.status === 'error') {
  console.error('Flow error:', result.error);
}
```

Configuration errors and network errors are thrown:

```typescript
try {
  const flocomp = createFlocomp({ apiKey: '' }); // Throws validation error
} catch (error) {
  console.error('Config error:', error);
}

try {
  const result = await flocomp.sendMessage('Hello'); // May throw network error
} catch (error) {
  console.error('Network error:', error);
}
```

---

## Browser Support

- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
- Opera 76+

**Note:** Requires native `fetch` API and ES2020 support. No polyfills included.

---

## License

MIT © Flocomp

---

## Support

- [Documentation](https://docs.flocomp.com)
- [GitHub Issues](https://github.com/flocomp/flocomp-sdk/issues)
- [Discord Community](https://discord.gg/flocomp)