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);
}
}
Related Documentation
Support
- Repository:
/workspaces-sdk-node - npm Package: https://www.npmjs.com/package/@workspace-platform/sdk
- Documentation: https://docs.workspace-platform.ai
- Issues: GitHub Issues
- Email: [email protected]