@elmapicms/js-sdk
v0.4.1
Published
JavaScript SDK for ElmapiCMS Content API
Downloads
224
Maintainers
Readme
ElmapiCMS JavaScript SDK
A JavaScript SDK for interacting with the ElmapiCMS Content API. This SDK provides type-safe access to all API endpoints for managing content, assets, and collections in your ElmapiCMS instance.
Installation
npm install @elmapicms/js-sdkQuick Start
import { createClient } from '@elmapicms/js-sdk';
// Create a client instance
const client = createClient(
'https://your-instance.elmapi.com/api',
'your-api-token',
'550e8400-e29b-41d4-a716-446655440000' // Your project UUID
);
// Get project
const project = await client.getProject();
console.log('Project Info:', projectInfo);
// Get collections for the project
const collections = await client.getCollections();
console.log('Collections:', collections);
// Get entries for a collection
const entries = await client.getEntries('blog-posts');
console.log('Entries:', entries);Features
- Type Safety: Full TypeScript support with comprehensive type definitions
- Promise-based: Modern async/await support
- Comprehensive: Covers all API endpoints in a single client
- Well-documented: JSDoc comments for all methods
- Simplified API: All methods available directly on the client instance
Error Handling
The SDK provides comprehensive error handling with specific error types, detailed error messages, and debugging information. All errors extend from the base ElmapiError class.
Error Types
The SDK throws specific error types based on the HTTP status code or error condition:
AuthenticationError(401): Invalid or missing API tokenAuthorizationError(403): Insufficient permissionsNotFoundError(404): Resource not foundValidationError(422): Invalid request dataRateLimitError(429): Rate limit exceededServerError(5xx): Server-side errorsNetworkError: Network connectivity issuesTimeoutError: Request timeout
Basic Error Handling
import {
createClient,
AuthenticationError,
NotFoundError,
ValidationError
} from '@elmapicms/js-sdk';
const client = createClient(
'https://your-instance.elmapi.com/api',
'your-api-token',
'your-project-id'
);
try {
const project = await client.getProject();
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Authentication failed:', error.message);
console.log('Please check your API token');
} else if (error instanceof NotFoundError) {
console.error('Resource not found:', error.message);
} else if (error instanceof ValidationError) {
console.error('Validation failed:', error.message);
console.error('Details:', error.details);
} else {
console.error('Unexpected error:', error.message);
}
}Advanced Error Handling
Each error includes detailed information for debugging:
try {
const collection = await client.getCollection('non-existent');
} catch (error) {
console.error('Error details:', {
name: error.name,
message: error.message,
statusCode: error.statusCode,
code: error.code,
details: error.details
});
// Request information for debugging
if (error.requestInfo) {
console.error('Request details:', {
method: error.requestInfo.method,
url: error.requestInfo.url,
params: error.requestInfo.params
});
}
}Retry Logic with Error Handling
async function retryWithBackoff(operation, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
// Don't retry on certain errors
if (error instanceof AuthenticationError ||
error instanceof NotFoundError ||
error instanceof ValidationError) {
throw error;
}
// Retry on rate limit, server errors, and network errors
if (attempt === maxRetries) {
throw error;
}
const delay = Math.pow(2, attempt) * 1000;
console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
// Usage
try {
const result = await retryWithBackoff(() => client.getCollections());
console.log('Success:', result);
} catch (error) {
console.error('All retry attempts failed:', error.message);
}Client Configuration Validation
// Validate client configuration
try {
client.validateConfiguration();
console.log('✓ Configuration is valid');
} catch (error) {
console.error('Configuration Error:', error.message);
}
// Get debug information
const debugInfo = client.getDebugInfo();
console.log('Client Configuration:', debugInfo);See the error handling examples for more detailed patterns.
API Reference
Client Methods
getProject(params?)
Get project including name, description, default locale, and available locales. Optional params:
with: Comma-separated list for collections and fields (e.g.with=collections,fields)
const project = await client.getProject();
// Returns: { uuid, name, description, default_locale, locales }getCollections()
Get all collections for the current project.
const collections = await client.getCollections();
// Returns: Array of collection objectsgetCollection(collectionSlug)
Get detailed information about a specific collection including its fields.
const collection = await client.getCollection('blog-posts');
// Returns: Collection object with fields arraygetEntries(collectionSlug, params?)
Get entries for a collection with optional filtering and pagination.
const posts = await client.getEntries('blog-posts', {
state: 'with_draft', // 'only_draft' | 'with_draft'
locale: 'en', // Filter by locale
exclude: 'content,excerpt', // Comma-separated fields to exclude
where: { state: 'published' }, // Advanced filtering
sort: 'created_at:desc', // Sorting
limit: 20, // Number of items
offset: 0, // Pagination offset
timestamps: true // Include created_at/updated_at
});getEntry(collectionSlug, uuid, params?)
Get a specific entry by UUID with optional query parameters.
// Basic usage
const post = await client.getEntry('blog-posts', '550e8400-e29b-41d4-a716-446655440000');
// Get entry for a specific locale
const post = await client.getEntry('blog-posts', 'uuid', {
locale: 'en'
});
// Get translation of an entry
const translation = await client.getEntry('blog-posts', 'uuid', {
translation_locale: 'fr'
});
// Get entry with additional options
const post = await client.getEntry('blog-posts', 'uuid', {
locale: 'en',
state: 'published', // 'only_draft' | 'with_draft' | 'published'
exclude: ['content', 'excerpt'], // Array of field names to exclude
timestamps: true // Include created_at and updated_at
});Parameters:
collectionSlug(string, required): The collection sluguuid(string, required): The entry UUIDparams(object, optional): Query parameterslocale(string): Fetch entry for a specific locale code (e.g., 'en-US')translation_locale(string): Get the translation of this entry in the specified locale. Returns the linked translation entry instead of the original.state(string): Controls the publication state. Options:'only_draft','with_draft','published'exclude(string[]): An array of field names to exclude from the responsetimestamps(boolean): If true, includescreated_atandupdated_atin the response
createEntry(collectionSlug, data)
Create a new entry.
const newPost = await client.createEntry('blog-posts', {
locale: 'en',
state: 'draft',
published_at: '2024-01-01T00:00:00Z',
data: {
title: 'My New Post',
content: 'Post content here...'
}
});updateEntry(collectionSlug, uuid, data)
Update an existing entry (PUT).
const updatedPost = await client.updateEntry('blog-posts', 'uuid', {
state: 'published',
data: { title: 'Updated Title' }
});patchEntry(collectionSlug, uuid, data)
Partially update an entry (PATCH).
const patchedPost = await client.patchEntry('blog-posts', 'uuid', {
data: { title: 'Patched Title' }
});deleteEntry(collectionSlug, uuid, force?)
Delete an entry. If force is set to true or 1, the entry is permanently deleted. If not set, the entry is moved to trash.
await client.deleteEntry('blog-posts', 'uuid'); // Move to trash
await client.deleteEntry('blog-posts', 'uuid', true); // Permanently deletegetAssets(params?)
Get all assets for the current project with optional filtering.
const assets = await client.getAssets({
search: 'image', // Search by filename, original filename, or mime type
type: 'image', // 'image' | 'video' | 'audio' | 'document'
paginate: 20 // Number of items per page
});getAsset(identifier)
Get a specific asset by ID or UUID.
const asset = await client.getAsset('550e8400-e29b-41d4-a716-446655440000');getAssetByFilename(filename)
Get a specific asset by original filename.
const asset = await client.getAssetByFilename('my-image.jpg');uploadAsset(file, metadata?)
Upload a new file asset.
const uploadedAsset = await client.uploadAsset(file, {
alt: 'Image description',
category: 'blog'
});deleteAsset(identifier, force?)
Delete an asset (soft delete by default, or permanent with force parameter).
await client.deleteAsset('uuid'); // Soft delete
await client.deleteAsset('uuid', true); // Permanent deleteLicense
See LICENSE file for details.
Support
For support, please contact [email protected] or visit our documentation at https://docs.elmapicms.com.
