npm package: @fastn-ai/core
Description: Framework-agnostic TypeScript SDK for Fastn AI platform. Provides core functionality for managing connectors, configurations, and integrations.
Author: Fastn AI
Latest version: 1.0.8

# @fastn-ai/core

A framework-agnostic TypeScript SDK for the Fastn AI platform. This package provides the core functionality for managing connectors, configurations, and integrations with full TypeScript support.

## 🚀 Features

- **🔌 Connector Management**: Fetch and manage marketplace connectors
- **⚙️ Configuration Handling**: Create, update, and manage connector configurations
- **📝 Form Management**: Handle dynamic configuration forms
- **🔄 Real-time Updates**: Built-in caching and background refetching
- **📱 TypeScript First**: Complete type safety and IntelliSense support
- **🌐 Framework Agnostic**: Works with any JavaScript/TypeScript framework

## 📦 Installation

```bash
npm install @fastn-ai/core
```

## 🏗️ Quick Start

### Basic Usage

```typescript
import { Fastn } from '@fastn-ai/core';

// Initialize the SDK
const fastn = new Fastn({
  environment: 'LIVE',
  authToken: 'your-auth-token',
  tenantId: 'your-tenant-id',
  spaceId: 'your-space-id',
});

// Fetch connectors
const connectors = await fastn.getConnectors();

// Fetch configurations
const configurations = await fastn.getConfigurations({
  configurationId: 'your-configuration-id',
  status: 'ALL'
});

// Get configuration form
const form = await fastn.getConfigurationForm({
  configurationId: 'your-configuration-id',
  connectorId: 'your-connector-id',
  configuration: configurationData
});
```

## 📚 API Reference

### Fastn Class

The main class for interacting with the Fastn AI platform.

#### Constructor

```typescript
new Fastn(config: Required<FastnConfig>)
```

#### Configuration

```typescript
interface FastnConfig {
  baseUrl?: string;
  environment?: FastnEnvironment;
  authToken: string;
  tenantId: string;
  spaceId: string;
  customAuth?: boolean;
}

type FastnEnvironment = 'LIVE' | 'DRAFT' | string;
```

#### Methods

##### `getConnectors(input?: GetConnectorsInput): Promise<Connector[]>`

Fetches available connectors from the marketplace.

```typescript
interface GetConnectorsInput {
  disabled?: boolean;
  status?: ConnectorStatus;
  refetch?: () => Promise<any>;
}
```

##### `getConfigurations(input: GetConfigurationsInput): Promise<Configuration[]>`

Fetches connector configurations.

```typescript
interface GetConfigurationsInput {
  configurationId: string;
  status?: "ENABLED" | "DISABLED" | "ALL" | "IDLE";
}
```

##### `getConfigurationForm(input: GetConfigurationFormInput): Promise<ConfigurationForm>`

Fetches configuration forms for setting up connectors.

```typescript
interface GetConfigurationFormInput {
  configurationId: string;
  connectorId: string;
  configuration: Configuration;
}
```

##### `registerRefetchFunction(input: RegisterRefetchFunctionInput): void`

Registers a function to be called when data needs to be refetched.

```typescript
interface RegisterRefetchFunctionInput {
  refetchFunction: () => Promise<void>;
  refetchKey: string;
}
```

## 🎯 Type Definitions

### Core Types

```typescript
interface Connector {
  readonly id: string;
  readonly name: string;
  readonly description: string;
  readonly imageUri?: string;
  readonly status: ConnectorStatus;
  readonly actions: readonly ConnectorAction[];
}

interface Configuration {
  readonly id: string;
  readonly connectorId: string;
  readonly configurationId: string;
  readonly name: string;
  readonly flowId: string;
  readonly description: string;
  readonly imageUri: string;
  readonly status: string;
  readonly actions: readonly ConfigurationAction[];
  readonly metadata?: Record<string, Record<string, Primitive>> |  Record<string, Record<string, Primitive>>[] | undefined | null;
}

interface ConfigurationForm {
  readonly name: string;
  readonly description: string;
  readonly imageUri: string;
  readonly fields: readonly ConnectorField[];
  readonly submitButtonLabel?: string;
  readonly loading?: boolean;
  readonly error?: string;
  readonly submitHandler?: (args: { formData: FormData }) => Promise<void>;
}
```

### Enums

```typescript
enum ConnectorStatus {
  ACTIVE = "ACTIVE",
  INACTIVE = "INACTIVE",
  ALL = "ALL",
}

enum ConnectorActionType {
  ACTIVATION = "ACTIVATION",
  DEACTIVATION = "DEACTIVATION",
  NONE = "NONE",
  ENABLE = "ENABLE",
  DISABLE = "DISABLE",
  DELETE = "DELETE",
}

enum ConnectorFieldType {
  TEXT = "text",
  NUMBER = "number",
  CHECKBOX = "checkbox",
  DATE = "date",
  DATETIME = "datetime",
  TIME = "time",
  DATETIME_LOCAL = "datetime-local",
  MULTI_SELECT = "multi-select",
  SELECT = "select",
  GOOGLE_FILES_PICKER_SELECT = "google-files-picker-select",
  GOOGLE_FILES_PICKER_MULTI_SELECT = "google-files-picker-multi-select",
}
```

### Configuration Types

```typescript
type Primitive = string | number | boolean | null | undefined;
interface ConnectorField {
  readonly name: string;
  readonly key: string;
  readonly label: string;
  readonly type: ConnectorFieldType | string;
  readonly required: boolean;
  readonly placeholder: string;
  readonly description: string;
  readonly hidden?: boolean;
  readonly disabled?: boolean;
  readonly initialValue?:
    | Record<string, Primitive>
    | Record<string, Primitive>[]
    | Primitive
    | Primitive[];
  readonly optionsSource?: SelectOptionSource;
  readonly configs?: ConnectorFieldConfig;
}

interface ConnectorFieldConfig {
  readonly selection?: SelectionConfig;
  readonly disable?: boolean;
  readonly label?: string;
  readonly hideOption?: HideOptionConfig;
}

interface SelectionConfig {
  readonly enable: boolean;
  readonly flowId: string;
  readonly sameProject: boolean;
  readonly list: readonly any[];
  readonly type: "OFFSET" | "CURSOR";
  readonly offset: number;
  readonly isIndependent: boolean;
  readonly fileTypes: readonly string[];
  readonly source: FlowConfig;
  readonly destination: FlowConfig;
  readonly isEditKeys: boolean;
  readonly isAddFields: boolean;
}

interface FlowConfig {
  readonly flowId: string;
  readonly isSameProject: boolean;
}

interface HideOptionConfig {
  readonly enable: boolean;
  readonly hideBasedOnValue: boolean;
  readonly key: string;
  readonly operation: "!=" | "==" | ">" | "<" | ">=" | "<=" | "contains" | "not_contains";
  readonly value: string;
}
```

### Configuration Usage Example

Here's an example of how the configuration types work with connector fields:

```typescript
// Example configuration structure
const fieldConfig: ConnectorFieldConfig = {
  selection: {
    enable: true,
    flowId: "asanaGetWorkspaces",
    sameProject: false,
    list: [],
    type: "OFFSET",
    offset: 10,
    isIndependent: false,
    fileTypes: [],
    source: {
      flowId: "",
      isSameProject: false
    },
    destination: {
      flowId: "",
      isSameProject: false
    },
    isEditKeys: false,
    isAddFields: false
  },
  disable: false,
  label: "Select Workspace",
  hideOption: {
    enable: false,
    hideBasedOnValue: false,
    key: "",
    operation: "!=",
    value: ""
  }
};

// Example connector field with configuration
const connectorField: ConnectorField = {
  name: "workspace",
  key: "workspace",
  label: "Workspace",
  type: "select",
  required: true,
  placeholder: "Select a workspace",
  description: "Choose the workspace to connect to",
  configs: fieldConfig
};
```

## 🛠️ Error Handling

The SDK provides comprehensive error handling with custom error classes:

```typescript
import {
  FastnError,
  MissingConfigError,
  AuthenticationError,
  MissingAuthTokenError,
  MissingSpaceIdError,
  MissingTenantIdError,
} from '@fastn-ai/core';

try {
  const connectors = await fastn.getConnectors();
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Authentication failed:', error.message);
  } else if (error instanceof MissingConfigError) {
    console.error('Configuration missing:', error.message);
  }
}
```

## 🔧 Advanced Usage

### Custom Authentication

```typescript
const fastn = new Fastn({
  baseUrl: 'https://api.fastn.ai',
  environment: 'LIVE',
  authToken: 'your-auth-token',
  tenantId: 'your-tenant-id',
  spaceId: 'your-space-id',
  customAuth: true, // Enable custom authentication
});
```

### Error Boundaries

```typescript
class FastnErrorHandler {
  static handle(error: FastnError) {
    switch (error.code) {
      case 'AUTH_ERROR':
        // Handle authentication errors
        break;
      case 'MISSING_CONFIG':
        // Handle configuration errors
        break;
      default:
        // Handle other errors
        console.error('Fastn error:', error.message);
    }
  }
}
```

## 🎯 Best Practices

### 1. Configuration Management

```typescript
// Store configuration securely
const config = {
  baseUrl: FASTN_BASE_URL || 'https://api.fastn.ai',
  environment: FASTN_ENVIRONMENT || 'LIVE',
  authToken: FASTN_AUTH_TOKEN!,
  tenantId: FASTN_TENANT_ID!,
  spaceId: FASTN_SPACE_ID!,
  customAuth: FASTN_CUSTOM_AUTH === 'true',
};

const fastn = new Fastn(config);
```

### 2. Error Handling

```typescript
async function fetchConnectors() {
  try {
    return await fastn.getConnectors();
  } catch (error) {
    if (error instanceof FastnError) {
      // Handle Fastn-specific errors
      console.error(`Fastn error (${error.code}):`, error.message);
    } else {
      // Handle other errors
      console.error('Unexpected error:', error);
    }
    throw error;
  }
}
```

### 3. Type Safety

```typescript
import type {
  Connector,
  Configuration,
  ConnectorAction,
  ConfigurationAction,
} from '@fastn-ai/core';

function handleConnectorAction(connector: Connector, action: ConnectorAction) {
  if (action.actionType === ConnectorActionType.ACTIVATION) {
    // Handle activation
  } else if (action.actionType === ConnectorActionType.DEACTIVATION) {
    // Handle deactivation
  }
}
```

## 🐛 Troubleshooting

### Common Issues

#### 1. Authentication Errors

**Error**: `AuthenticationError: Authentication failed`

**Solution**: Verify your `authToken` is valid and not expired.

#### 2. Configuration Errors

**Error**: `MissingConfigError: Config is missing`

**Solution**: Ensure all required configuration properties are provided.

#### 3. Network Errors

**Error**: `Network Error` or `Failed to fetch`

**Solution**: Check your `baseUrl` and network connectivity.

### Debug Mode

Enable debug logging to troubleshoot issues:

```typescript
if (NODE_ENV === 'development') {
  console.log('Fastn Config:', config);
}
```

## 📚 Additional Resources

- [Fastn AI Documentation](https://docs.fastn.ai)
- [TypeScript Handbook](https://www.typescriptlang.org/docs/)
- [GitHub Repository](https://github.com/fastn-ai/core)

## 🤝 Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 🆘 Support

If you need help or have questions:

- 📧 Email: [support@fastn.ai](mailto:support@fastn.ai)
- 📖 Documentation: [docs.fastn.ai](https://docs.fastn.ai)
- 🐛 Issues: [GitHub Issues](https://github.com/fastn-ai/core/issues)

---

Made with ❤️ by the Fastn AI team