npm package: @runmorph/cloud
Description: A powerful TypeScript SDK for seamlessly integrating Morph's unified API into your backend services and fronted apps. Built with TypeScript for type safety and modern development practices.
Latest version: 0.0.14

# @runmorph/cloud

A powerful TypeScript SDK for seamlessly integrating Morph's unified API into your backend services and fronted apps. Built with TypeScript for type safety and modern development practices.

## Features

- 🔐 Built-in authentication handling (only OAuth2 for now)
- 🔌 Unified connector interface for any platforms
- 📦 Modular architecture with pluggable connectors
- 🔄 Standardized CRUD operations for resources
- 🌐 Proxy capabilities for direct API access
- 📝 Type-safe operations with full TypeScript support

## Installation

```bash
yarn add @runmorph/cloud
```

## Quick Start

### 1. Initialize the Client

```typescript
import { Morph } from "@runmorph/cloud";

const morph = new Morph({
  publicKey: process.env.MORPH_PUBLIC_KEY!,
  secretKey: process.env.MORPH_SECRET_KEY!,
});
```

```env
# .env.local
MORPH_PUBLIC_KEY=pk_demo_xxxxxxxxxxxxxxx
MORPH_API_SECRET=sk_demo_xxxxxxxxxxxxxxx
```

Note: You can use these demo credentials to quickly test the SDK. For production use, replace them with your own API keys from the [Morph dashboard](https://runmorph.dev).

### 2. Create and Authorize Connections

Use the `<Connect />` React component from `@runmorph/atoms` ([see documentation](https://docs.runmorph.dev/api-reference/atoms)) or build your own custom authorization flow:

```typescript
// Initialize a connection
const connection = morph.connections({
  connectorId: "hubspot",
  ownerId: "demo", // A unique identifier for your end-user (e.g. "user_123"). Use "demo" with demo credentials
});

// Create connection with required operations
const { error } = await connection.create({
  operations: ["genericContact::list"],
});

// Get authorization URL
const { authorizationUrl } = await connection.authorize();

// Redirect your user to authorizationUrl for OAuth flow
```

### 3. Work with Resources

```typescript
// Access the contacts resource
const contacts = connection.resources("genericContact");

// Create a contact
const { data: newContact } = await contacts.create({
  firstName: "John",
  lastName: "Doe",
  email: "john.doe@example.com",
});

// List contacts with pagination
const { data: contactsList, next } = await contacts.list({
  limit: 10,
  cursor: "next-page-cursor",
});

// Retrieve a specific contact
const { data: contact } = await contacts.retrieve("contact-123", {
  fields: ["email", "firstName", "lastName"],
});

// Update a contact
const { data: updatedContact } = await contacts.update("contact-123", {
  firstName: "Jane",
});
```

## Advanced Usage

### Type-Safe Connector Access

```typescript
// Type-check the connector
const hubspotConnection = connection.isConnector("hubspot");
if (!hubspotConnection) return;

// Access HubSpot-specific endpoints
const { data } = await hubspotConnection.proxy({
  path: "/v3/objects/contacts",
  method: "GET",
  query: { limit: 10 },
});
```

### Session Token Generation

Create a session token to interact with the Morph API from your client-facing app

```typescript
// Generate a session token for frontend use
const { sessionToken } = await morph.sessions().create({
  connection: {
    connectorId: "hubspot",
    ownerId: "demo",
  },
  expiresIn: 30 * 60 * 60,
});

// Use this token with @runmorph/atoms in your frontend
// See: https://docs.runmorph.dev/api-reference/atoms
```

### Error Handling

```typescript
try {
  const { data, error } = await contacts.create({
    firstName: "John",
    email: "invalid-email",
  });

  if (error) {
    // Handle operation-specific error
    console.error("Operation failed:", error.message);
    return;
  }

  // Process successful response
  console.log("Contact created:", data);
} catch (e) {
  // Handle unexpected errors
  console.error("Unexpected error:", e);
}
```

## Resource Operations

The SDK provides consistent CRUD operations across all supported connectors:

- `create`: Create new resources
- `retrieve`: Fetch specific resources
- `list`: List resources with pagination
- `update`: Update existing resources
- `delete`: Remove resources

Each operation returns a typed response with the following structure:

```typescript
interface Response<T> {
  data?: T;
  error?: {
    message: string;
    code: string;
  };
  next?: string; // Pagination cursor (list operations only)
}
```

## TypeScript Support

The SDK is written in TypeScript and provides comprehensive type definitions. Enable strict mode in your `tsconfig.json` for the best development experience:

```json
{
  "compilerOptions": {
    "strict": true
  }
}
```

## Security Best Practices

1. Never expose your secret key in client-side code
2. Store API credentials securely using environment variables
3. Generate session tokens server-side only
4. Implement proper error handling
5. Validate all input data before making API calls

## Frontend Integration

For frontend integration, we recommend using [@runmorph/atoms](https://docs.runmorph.dev/api-reference/atoms), our React SDK that provides pre-built components and hooks for a seamless user experience.

## API Reference

For detailed API documentation, visit our [official documentation](https://docs.runmorph.dev/api-reference/intro).