Skip to main content

Node.js SDK

Official Node.js/TypeScript SDK for building applications with the Workspace Platform.

Overview

The Workspace Node.js SDK provides a comprehensive, type-safe interface for integrating workspace functionality into your Node.js and TypeScript applications. With 26+ modules covering all platform APIs, it offers full TypeScript support, async/await patterns, and production-ready error handling.

Repository: /workspaces-sdk-node

Key Features

Comprehensive API Coverage

  • 26+ Modules covering all platform features
  • Full TypeScript support with type definitions
  • GraphQL and REST API integration
  • Async/await for all operations
  • Promise-based architecture

Developer Experience

  • IntelliSense and autocomplete
  • Comprehensive documentation
  • Code examples for all features
  • Error handling with custom exceptions
  • Built-in request retry logic

Production-Ready

  • Extensive testing with Vitest
  • Pagination support
  • Rate limiting handling
  • Connection pooling
  • Request caching
  • Webhook integration

Technology Stack

  • Language: TypeScript 5.9.2
  • Runtime: Node.js 20.x+
  • Package Manager: npm
  • API: GraphQL, REST
  • Testing: Vitest
  • Build: TSC (TypeScript Compiler)

Installation

Using npm

npm install @workspace-platform/sdk

Using yarn

yarn add @workspace-platform/sdk

Using pnpm

pnpm add @workspace-platform/sdk

Quick Start

Basic Setup

import { WorkspaceClient } from '@workspace-platform/sdk';

// Initialize client
const client = new WorkspaceClient({
apiKey: 'your_api_key_here',
endpoint: 'https://api.workspace-platform.ai' // optional
});

// Create workspace
const workspace = await client.workspaces.create({
name: 'My Workspace',
description: 'A new workspace'
});

console.log(`Created workspace: ${workspace.id}`);

TypeScript Configuration

// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true
}
}

Core Modules

Workspace Management

import { WorkspaceClient } from '@workspace-platform/sdk';

const client = new WorkspaceClient({ apiKey: 'your_key' });

// Create workspace
const workspace = await client.workspaces.create({
name: 'Engineering Team',
description: 'Engineering department workspace',
settings: {
visibility: 'private',
memberLimit: 50
}
});

// Get workspace
const ws = await client.workspaces.get('ws_abc123');

// Update workspace
await client.workspaces.update('ws_abc123', {
name: 'Engineering Department',
settings: { visibility: 'internal' }
});

// List workspaces
const workspaces = await client.workspaces.list({
limit: 20,
status: 'active'
});

// Delete workspace
await client.workspaces.delete('ws_abc123');

Member Management

// Add member
const member = await client.members.add({
workspaceId: 'ws_abc123',
email: '[email protected]',
role: 'admin',
teamIds: ['team_1', 'team_2']
});

// Get member
const mem = await client.members.get('mem_abc123');

// Update member
await client.members.update('mem_abc123', {
role: 'editor',
permissions: ['read', 'write', 'comment']
});

// List members
const members = await client.members.list({
workspaceId: 'ws_abc123',
role: 'admin',
limit: 50
});

// Remove member
await client.members.remove('mem_abc123');

// Bulk invite
const invited = await client.members.bulkInvite({
workspaceId: 'ws_abc123',
emails: ['[email protected]', '[email protected]'],
role: 'viewer'
});

Team Operations

// Create team
const team = await client.teams.create({
workspaceId: 'ws_abc123',
name: 'Frontend Team',
description: 'Frontend developers',
memberIds: ['mem_1', 'mem_2']
});

// Get team
const tm = await client.teams.get('team_abc123');

// Update team
await client.teams.update('team_abc123', {
name: 'Frontend Engineering',
settings: { maxMembers: 20 }
});

// Add members to team
await client.teams.addMembers('team_abc123', {
memberIds: ['mem_3', 'mem_4']
});

// Remove members from team
await client.teams.removeMembers('team_abc123', {
memberIds: ['mem_1']
});

// List teams
const teams = await client.teams.list({
workspaceId: 'ws_abc123',
limit: 20
});

// Delete team
await client.teams.delete('team_abc123');

Project Management

// Create project
const project = await client.projects.create({
workspaceId: 'ws_abc123',
name: 'Mobile App Redesign',
description: 'Q4 mobile app redesign project',
teamId: 'team_abc123',
status: 'active',
settings: {
visibility: 'team',
dueDate: '2025-12-31'
}
});

// Get project
const proj = await client.projects.get('proj_abc123');

// Update project
await client.projects.update('proj_abc123', {
status: 'in_progress',
progress: 45
});

// List projects
const projects = await client.projects.list({
workspaceId: 'ws_abc123',
status: 'active',
teamId: 'team_abc123'
});

// Assign project to team
await client.projects.assignTeam('proj_abc123', 'team_xyz789');

// Delete project
await client.projects.delete('proj_abc123');

RBAC (Role-Based Access Control)

// List roles
const roles = await client.rbac.roles.list();

// Get role
const role = await client.rbac.roles.get('role_abc123');

// Create custom role
const customRole = await client.rbac.roles.create({
name: 'Contractor',
description: 'External contractor access',
permissions: ['read', 'comment']
});

// Assign role to member
await client.rbac.assign({
memberId: 'mem_abc123',
roleId: 'role_abc123',
resourceId: 'ws_abc123',
resourceType: 'workspace'
});

// Check permission
const hasPermission = await client.rbac.checkPermission({
memberId: 'mem_abc123',
action: 'edit',
resourceId: 'proj_abc123',
resourceType: 'project'
});

console.log(`Has edit permission: ${hasPermission}`);

// Get member permissions
const permissions = await client.rbac.getPermissions('mem_abc123');

Advanced Features

Pagination

// Manual pagination
const page1 = await client.workspaces.list({ limit: 10 });
const page2 = await client.workspaces.list({
limit: 10,
cursor: page1.nextCursor
});

// Auto-pagination iterator
for await (const workspace of client.workspaces.iterate({ limit: 10 })) {
console.log(workspace.name);
}

// Get all (with auto-pagination)
const allWorkspaces = await client.workspaces.listAll();

Error Handling

import {
WorkspaceClient,
WorkspaceError,
NotFoundError,
ValidationError,
AuthenticationError,
RateLimitError
} from '@workspace-platform/sdk';

const client = new WorkspaceClient({ apiKey: 'your_key' });

try {
const workspace = await client.workspaces.get('ws_invalid');
} catch (error) {
if (error instanceof NotFoundError) {
console.error('Workspace not found');
} else if (error instanceof ValidationError) {
console.error('Validation failed:', error.errors);
} else if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof RateLimitError) {
console.error('Rate limit exceeded, retry after:', error.retryAfter);
} else if (error instanceof WorkspaceError) {
console.error('Workspace error:', error.message);
} else {
console.error('Unexpected error:', error);
}
}

Webhooks

import { WebhookClient } from '@workspace-platform/sdk';

const webhooks = new WebhookClient({
apiKey: 'your_key'
});

// Create webhook
const webhook = await webhooks.create({
url: 'https://myapp.com/webhooks/workspace',
events: [
'workspace.created',
'workspace.updated',
'member.added',
'team.created'
],
secret: 'webhook_secret_key'
});

// List webhooks
const allWebhooks = await webhooks.list();

// Update webhook
await webhooks.update('webhook_abc123', {
events: ['workspace.created', 'workspace.deleted']
});

// Delete webhook
await webhooks.delete('webhook_abc123');

// Verify webhook signature (in your server)
import { verifyWebhookSignature } from '@workspace-platform/sdk';

app.post('/webhooks/workspace', (req, res) => {
const signature = req.headers['x-workspace-signature'];
const isValid = verifyWebhookSignature(
req.body,
signature,
'webhook_secret_key'
);

if (!isValid) {
return res.status(401).send('Invalid signature');
}

// Process webhook
const event = req.body;
console.log(`Received event: ${event.type}`);

res.status(200).send('OK');
});

File Uploads

import { FileClient } from '@workspace-platform/sdk';
import fs from 'fs';

const files = new FileClient({ apiKey: 'your_key' });

// Upload file
const file = await files.upload({
workspaceId: 'ws_abc123',
file: fs.createReadStream('/path/to/file.pdf'),
filename: 'document.pdf',
metadata: {
projectId: 'proj_abc123',
tags: ['important', 'q4']
}
});

// Download file
const stream = await files.download('file_abc123');
stream.pipe(fs.createWriteStream('/path/to/download.pdf'));

// List files
const fileList = await files.list({
workspaceId: 'ws_abc123',
projectId: 'proj_abc123'
});

// Delete file
await files.delete('file_abc123');

Activity and Audit

// Get activity log
const activities = await client.activity.list({
workspaceId: 'ws_abc123',
startDate: '2025-01-01',
endDate: '2025-01-31',
actorId: 'mem_abc123',
limit: 100
});

// Get workspace statistics
const stats = await client.analytics.getWorkspaceStats('ws_abc123');
console.log(`Total members: ${stats.totalMembers}`);
console.log(`Active projects: ${stats.activeProjects}`);

// Export audit trail
const auditData = await client.audit.export({
workspaceId: 'ws_abc123',
startDate: '2025-01-01',
endDate: '2025-01-31',
format: 'json'
});

Configuration

Client Options

const client = new WorkspaceClient({
// Required
apiKey: 'your_api_key',

// Optional
endpoint: 'https://api.workspace-platform.ai',
timeout: 30000, // 30 seconds
retries: 3,
retryDelay: 1000, // 1 second

// Custom headers
headers: {
'X-Custom-Header': 'value'
},

// Proxy
proxy: {
host: 'proxy.example.com',
port: 8080
},

// Logging
logger: console,
logLevel: 'debug' // 'error' | 'warn' | 'info' | 'debug'
});

Environment Variables

WORKSPACE_API_KEY=your_api_key
WORKSPACE_API_ENDPOINT=https://api.workspace-platform.ai
WORKSPACE_TIMEOUT=30000
WORKSPACE_LOG_LEVEL=info

Load automatically:

import { WorkspaceClient } from '@workspace-platform/sdk';

// Automatically uses WORKSPACE_API_KEY env var
const client = new WorkspaceClient();

Testing

Unit Tests

// workspace.test.ts
import { describe, it, expect, beforeEach } from 'vitest';
import { WorkspaceClient } from '@workspace-platform/sdk';

describe('Workspace Operations', () => {
let client: WorkspaceClient;

beforeEach(() => {
client = new WorkspaceClient({
apiKey: 'test_key'
});
});

it('should create workspace', async () => {
const workspace = await client.workspaces.create({
name: 'Test Workspace'
});

expect(workspace.id).toBeDefined();
expect(workspace.name).toBe('Test Workspace');
});

it('should list workspaces', async () => {
const workspaces = await client.workspaces.list();
expect(Array.isArray(workspaces.data)).toBe(true);
});
});

Mock Client

import { createMockClient } from '@workspace-platform/sdk/testing';

const mockClient = createMockClient();

// Mock responses
mockClient.workspaces.create.mockResolvedValue({
id: 'ws_mock',
name: 'Mock Workspace',
createdAt: new Date()
});

// Use in tests
const workspace = await mockClient.workspaces.create({ name: 'Test' });
expect(workspace.id).toBe('ws_mock');

TypeScript Support

Type Definitions

import {
Workspace,
Member,
Team,
Project,
Role,
Permission,
WorkspaceStatus,
MemberRole
} from '@workspace-platform/sdk';

// Fully typed
const workspace: Workspace = {
id: 'ws_abc123',
name: 'Engineering',
description: 'Engineering team',
status: WorkspaceStatus.Active,
createdAt: new Date(),
updatedAt: new Date()
};

// Type inference
const member = await client.members.get('mem_abc123');
// member is typed as Member

// Generic types
const workspaces = await client.workspaces.list();
// workspaces is typed as PaginatedResponse<Workspace>

Custom Types

import { WorkspaceClient } from '@workspace-platform/sdk';

interface CustomWorkspaceSettings {
theme: 'light' | 'dark';
notifications: boolean;
language: string;
}

const workspace = await client.workspaces.create<CustomWorkspaceSettings>({
name: 'Custom Workspace',
settings: {
theme: 'dark',
notifications: true,
language: 'en'
}
});

Best Practices

✅ Use environment variables for API keys ✅ Implement proper error handling ✅ Use TypeScript for type safety ✅ Enable request retries for production ✅ Implement pagination for large datasets ✅ Use async/await over callbacks ✅ Cache responses when appropriate ✅ Monitor API usage and rate limits ✅ Validate input before API calls ✅ Use webhooks for real-time updates

Performance

  • Request Latency: 100-300ms (API dependent)
  • Throughput: 100+ requests/second
  • Memory Usage: ~50MB base
  • Connection Pooling: Automatic
  • Request Caching: Configurable

Troubleshooting

Common Issues

Issue: Authentication errors

// Solution: Verify API key
const client = new WorkspaceClient({
apiKey: process.env.WORKSPACE_API_KEY,
logLevel: 'debug' // Enable debug logging
});

Issue: Rate limiting

// Solution: Implement retry logic
const client = new WorkspaceClient({
apiKey: 'your_key',
retries: 5,
retryDelay: 2000
});

Issue: Type errors

# Solution: Ensure TypeScript version compatibility
npm install typescript@^5.0.0 --save-dev

Migration Guide

From v1.x to v2.x

// v1.x (deprecated)
const workspace = await client.createWorkspace('ws_abc123', { name: 'Test' });

// v2.x (current)
const workspace = await client.workspaces.create({ name: 'Test' });

Framework Integration

Express.js

import express from 'express';
import { WorkspaceClient } from '@workspace-platform/sdk';

const app = express();
const client = new WorkspaceClient({ apiKey: process.env.WORKSPACE_API_KEY });

app.get('/workspaces', async (req, res) => {
try {
const workspaces = await client.workspaces.list();
res.json(workspaces);
} catch (error) {
res.status(500).json({ error: error.message });
}
});

app.listen(3000);

Next.js

// pages/api/workspaces.ts
import { WorkspaceClient } from '@workspace-platform/sdk';
import type { NextApiRequest, NextApiResponse } from 'next';

const client = new WorkspaceClient({ apiKey: process.env.WORKSPACE_API_KEY });

export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method === 'GET') {
const workspaces = await client.workspaces.list();
res.status(200).json(workspaces);
} else {
res.status(405).json({ error: 'Method not allowed' });
}
}

NestJS

// workspace.service.ts
import { Injectable } from '@nestjs/common';
import { WorkspaceClient } from '@workspace-platform/sdk';

@Injectable()
export class WorkspaceService {
private client: WorkspaceClient;

constructor() {
this.client = new WorkspaceClient({
apiKey: process.env.WORKSPACE_API_KEY
});
}

async listWorkspaces() {
return await this.client.workspaces.list();
}

async createWorkspace(data: { name: string; description?: string }) {
return await this.client.workspaces.create(data);
}
}

Support