ofself-sdk
v0.1.1
Published
Official JavaScript/TypeScript SDK for the OfSelf API - Personal data sovereignty platform
Maintainers
Readme
ofself-sdk
Official JavaScript/TypeScript SDK for the OfSelf API - Personal data sovereignty platform.
Installation
npm install ofself-sdk
# or
yarn add ofself-sdk
# or
pnpm add ofself-sdkQuick Start
import { OfSelfClient } from 'ofself-sdk';
// Initialize the client
const client = new OfSelfClient({
apiKey: 'your-api-key',
});
// Create a node
const node = await client.nodes.create({
userId: 'user-123',
title: 'Meeting Notes',
value: 'Discussed project timeline and milestones.',
nodeType: 'note',
tagIds: ['tag-work'],
});
console.log(`Created node: ${node.id}`);
// List nodes
const { items, total } = await client.nodes.list({
userId: 'user-123',
nodeType: 'note',
perPage: 10,
});
console.log(`Found ${total} notes`);Features
- Full API coverage: All endpoints supported
- TypeScript first: Full type definitions with autocomplete
- Works everywhere: Browser and Node.js
- Error handling: Typed exceptions for different error cases
- Zero dependencies: Uses native
fetch
API Resources
Nodes
// Create
const node = await client.nodes.create({
userId: 'user-123',
title: 'My Note',
value: 'Content here',
nodeType: 'note',
tagIds: ['tag-1'],
});
// List with filters
const { items } = await client.nodes.list({
userId: 'user-123',
nodeType: 'note',
search: 'meeting',
});
// Get, update, delete
const node = await client.nodes.get('user-123', 'node-id');
await client.nodes.update({ userId: 'user-123', nodeId: 'node-id', title: 'Updated' });
await client.nodes.delete('user-123', 'node-id');
// Vector search
const similar = await client.nodes.vectorSearch('user-123', 'project deadlines');
// Tags
await client.nodes.addTag('user-123', 'node-id', 'tag-id');
await client.nodes.removeTag('user-123', 'node-id', 'tag-id');Tags
// Create
const tag = await client.tags.create({
userId: 'user-123',
name: 'Work',
color: '#4A90D9',
});
// List
const { items } = await client.tags.list('user-123');
// Get nodes/files with tag
const nodes = await client.tags.getNodes('user-123', 'tag-id');
const files = await client.tags.getFiles('user-123', 'tag-id');Files
// Upload (browser)
const file = await client.files.upload({
userId: 'user-123',
file: fileInput.files[0],
tagIds: ['tag-documents'],
});
// Upload (Node.js)
import { readFileSync } from 'fs';
const buffer = readFileSync('document.pdf');
const file = await client.files.upload({
userId: 'user-123',
file: new Blob([buffer]),
filename: 'document.pdf',
});
// Download
const blob = await client.files.download('user-123', 'file-id');Proposals
// Create proposal (Proposals V2)
const proposal = await client.proposals.create({
userId: 'user-123',
title: 'Create note from import',
type: 'CREATE_NODE',
canonicalData: {
entities: [{ title: 'Imported Note', value: 'Content', nodeType: 'note' }],
},
});
// List pending
const { items } = await client.proposals.list('user-123', { status: 'pending' });
// Approve/reject
await client.proposals.approve('user-123', 'proposal-id');
await client.proposals.reject('user-123', 'proposal-id', 'Duplicate');Graph
// Get graph for visualization
const graph = await client.graph.snapshot('user-123', {
includeMetadata: true,
});
// Use with visualization library
graph.nodes.forEach((node) => console.log(node.title));
graph.edges.forEach((edge) => console.log(`${edge.source} → ${edge.target}`));Webhooks
// Subscribe to events
await client.webhooks.subscribe(
'https://myapp.com/webhook',
['node.created', 'node.updated']
);
// Get subscription
const sub = await client.webhooks.getSubscription();
// Unsubscribe
await client.webhooks.unsubscribe();Error Handling
import {
OfSelfError,
AuthenticationError,
PermissionDeniedError,
NotFoundError,
ValidationError,
RateLimitError,
} from 'ofself-sdk';
try {
await client.nodes.get('user-123', 'invalid-id');
} catch (error) {
if (error instanceof NotFoundError) {
console.log('Node not found');
} else if (error instanceof PermissionDeniedError) {
console.log('Access denied');
} else if (error instanceof RateLimitError) {
console.log(`Retry after ${error.retryAfter} seconds`);
} else if (error instanceof ValidationError) {
console.log('Validation errors:', error.errors);
} else if (error instanceof OfSelfError) {
console.log(`API error: ${error.message}`);
}
}Configuration
const client = new OfSelfClient({
apiKey: 'your-api-key',
baseUrl: 'https://api.ofself.ai/api/v1', // Default
timeout: 30000, // 30 seconds (default)
});Browser Usage
The SDK works in modern browsers with native fetch:
<script type="module">
import { OfSelfClient } from 'https://unpkg.com/ofself-sdk';
const client = new OfSelfClient({ apiKey: 'your-key' });
const nodes = await client.nodes.list({ userId: 'user-123' });
</script>React Example
import { useState, useEffect } from 'react';
import { OfSelfClient, Node } from 'ofself-sdk';
const client = new OfSelfClient({ apiKey: process.env.REACT_APP_OFSELF_KEY! });
function NodeList({ userId }: { userId: string }) {
const [nodes, setNodes] = useState<Node[]>([]);
useEffect(() => {
client.nodes.list({ userId }).then((res) => setNodes(res.items));
}, [userId]);
return (
<ul>
{nodes.map((node) => (
<li key={node.id}>{node.title}</li>
))}
</ul>
);
}Development
# Install dependencies
npm install
# Build
npm run build
# Run tests
npm test
# Lint
npm run lint
# Type check
npm run typecheckLicense
MIT License - see LICENSE for details.
