npm package: @od-canvas/sdk
Description: Canvas SDK for TypeScript/JavaScript
Latest version: 1.0.0

# Canvas SDK

A TypeScript SDK for integrating Canvas CMS into your applications.

## Installation

```bash
npm install @canvas/sdk
```

## Quick Start

```typescript
import { CanvasClient } from '@canvas/sdk'

const canvas = new CanvasClient({
  baseUrl: 'http://localhost:8080/api',
  apiKey: 'your_api_key_here',
})

// Get all projects
const projects = await canvas.getProjects()

// Get documents in a project
const documents = await canvas.getDocuments(1)

// Get a single document
const post = await canvas.getDocument(42)
```

## Configuration

Initialize the client with configuration:

```typescript
const canvas = new CanvasClient({
  baseUrl: 'http://localhost:8080/api',  // Optional, defaults to http://localhost:8080/api
  apiKey: 'your_api_key_here',           // Optional, defaults to CANVAS_API_KEY env var
})
```

Or use environment variables:

```typescript
// Reads from CANVAS_API_URL and CANVAS_API_KEY
const canvas = new CanvasClient()
```

## API Reference

### Projects

#### getProjects()
Get all projects you own.

```typescript
const projects = await canvas.getProjects()
// Returns: Project[]
```

#### getProject(id)
Get a specific project.

```typescript
const project = await canvas.getProject(1)
// Returns: Project
```

#### createProject(name, documentLimit?)
Create a new project.

```typescript
const project = await canvas.createProject('My Blog', 100)
// Returns: Project
```

#### updateProject(id, data)
Update project settings.

```typescript
const project = await canvas.updateProject(1, {
  name: 'Updated Blog Name',
  document_limit: 200,
})
// Returns: Project
```

#### deleteProject(id)
Delete a project.

```typescript
await canvas.deleteProject(1)
```

### Documents

#### getDocuments(projectId)
Get all documents in a project.

```typescript
const documents = await canvas.getDocuments(1)
// Returns: Document[]
```

#### getDocument(id)
Get a specific document.

```typescript
const document = await canvas.getDocument(42)
// Returns: Document
```

#### createDocument(data)
Create a new document.

```typescript
const document = await canvas.createDocument({
  project_id: 1,
  type_id: 1,
  title: 'My Blog Post',
  content: '<h1>Hello World</h1>',
  published: false,
})
// Returns: Document
```

#### updateDocument(id, data)
Update a document.

```typescript
const document = await canvas.updateDocument(42, {
  title: 'Updated Title',
  content: '<h1>Updated Content</h1>',
  published: true,
})
// Returns: Document
```

#### deleteDocument(id)
Delete a document.

```typescript
await canvas.deleteDocument(42)
```

### Document Types

#### getDocumentTypes(projectId)
Get all document types in a project.

```typescript
const types = await canvas.getDocumentTypes(1)
// Returns: DocumentType[]
```

#### createDocumentType(data)
Create a document type.

```typescript
const type = await canvas.createDocumentType({
  project_id: 1,
  name: 'Blog Post',
  schema: JSON.stringify({ fields: { ... } }),
})
// Returns: DocumentType
```

#### updateDocumentType(id, data)
Update a document type.

```typescript
const type = await canvas.updateDocumentType(1, {
  name: 'Article',
  schema: JSON.stringify({ fields: { ... } }),
})
// Returns: DocumentType
```

#### deleteDocumentType(id)
Delete a document type.

```typescript
await canvas.deleteDocumentType(1)
```

### API Keys

#### getAPIKeys(projectId)
Get all API keys for a project.

```typescript
const keys = await canvas.getAPIKeys(1)
// Returns: APIKey[]
```

#### createAPIKey(projectId, name)
Generate a new API key.

```typescript
const key = await canvas.createAPIKey(1, 'Astro Blog')
// Returns: APIKey
```

#### deleteAPIKey(id)
Revoke an API key.

```typescript
await canvas.deleteAPIKey(1)
```

## Types

### Project
```typescript
interface Project {
  id: number
  name: string
  owner_id: string
  document_count: number
  document_limit: number
  created_at: string
  updated_at: string
}
```

### Document
```typescript
interface Document {
  id: number
  project_id: number
  type_id: number
  title: string
  content: string
  author_id: string
  published: boolean
  created_at: string
  updated_at: string
  deleted_at?: string
}
```

### DocumentType
```typescript
interface DocumentType {
  id: number
  project_id: number
  name: string
  schema: string
  created_at: string
  updated_at: string
}
```

### APIKey
```typescript
interface APIKey {
  id: number
  project_id: number
  key: string
  name: string
  created_at: string
  last_used?: string
}
```

## Examples

### Next.js
```typescript
import { CanvasClient } from '@canvas/sdk'

export async function getStaticProps() {
  const canvas = new CanvasClient({
    apiKey: process.env.CANVAS_API_KEY,
  })

  const documents = await canvas.getDocuments(1)

  return {
    props: { documents },
    revalidate: 60, // ISR: revalidate every 60 seconds
  }
}
```

### Astro
```astro
---
import { CanvasClient } from '@canvas/sdk'

const canvas = new CanvasClient({
  apiKey: import.meta.env.CANVAS_API_KEY,
})

const posts = await canvas.getDocuments(parseInt(import.meta.env.CANVAS_PROJECT_ID))
  .then(docs => docs.filter(d => d.published))
  .then(docs => docs.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()))
---
```

### Node.js Script
```typescript
import { CanvasClient } from '@canvas/sdk'

const canvas = new CanvasClient()

async function main() {
  const projects = await canvas.getProjects()
  console.log('My projects:', projects)

  for (const project of projects) {
    const docs = await canvas.getDocuments(project.id)
    console.log(`Project "${project.name}" has ${docs.length} documents`)
  }
}

main().catch(console.error)
```

## Error Handling

The SDK throws errors for failed requests. Always wrap calls in try-catch:

```typescript
try {
  const document = await canvas.getDocument(999)
} catch (error) {
  console.error('Failed to fetch document:', error.message)
}
```

## Authentication

All requests to Canvas require an API key. Generate one in the admin panel:

1. Go to your Project → Settings
2. Find "API Keys" section
3. Click "Generate New Key"
4. Use the key with the SDK via environment variable or config

```bash
export CANVAS_API_KEY=your_key_here
```

## License

MIT