npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@bernierllc/content-management-suite-client

v0.2.0

Published

Browser-safe HTTP client for @bernierllc/content-management-suite - use this in frontend applications

Downloads

64

Readme

@bernierllc/content-management-suite-client

Browser-safe HTTP client for @bernierllc/content-management-suite.

Overview

This package provides a browser-compatible HTTP client that mirrors the full API of @bernierllc/content-management-suite. Use this package in frontend applications (React, Vue, Angular, etc.) instead of importing the suite directly, which contains Node.js-only dependencies.

Why This Package Exists

The @bernierllc/content-management-suite contains dependencies that break in browser environments:

  • Database clients (Supabase, PostgreSQL)
  • File system access (fs, path)
  • Node.js crypto modules
  • Server-side AI SDK integrations

This client package provides the same API surface but makes HTTP calls to a backend server running the suite.

Installation

npm install @bernierllc/content-management-suite-client

Quick Start

import { ContentManagementClient } from '@bernierllc/content-management-suite-client';

const client = new ContentManagementClient({
  baseUrl: 'https://api.example.com/content',
  apiKey: 'your-api-key'
});

// Create content
const result = await client.content.createContent({
  title: 'My Blog Post',
  body: '# Hello World\n\nThis is my first post.',
  type: 'blog-post',
  status: 'draft'
});

console.log(result.content.id); // 'uuid-...'

Configuration

interface ContentManagementClientConfig {
  baseUrl: string;              // Required: API base URL
  apiKey?: string;              // Optional: API key or bearer token
  timeout?: number;             // Optional: Request timeout (default: 30000ms)
  headers?: Record<string, string>; // Optional: Custom headers
  onTokenRefresh?: () => Promise<string>; // Optional: Token refresh callback
}

Token Refresh Example

const client = new ContentManagementClient({
  baseUrl: 'https://api.example.com/content',
  apiKey: 'initial-token',
  onTokenRefresh: async () => {
    // Refresh logic here
    const response = await fetch('/auth/refresh');
    const { token } = await response.json();
    return token;
  }
});

API Modules

The client exposes the following API modules:

Content Management (client.content)

Primary content CRUD operations.

// Create content
await client.content.createContent({
  title: 'Article Title',
  body: 'Article content...',
  type: 'blog-post'
});

// Get content
const content = await client.content.getContent('content-id');

// Update content
await client.content.updateContent('content-id', {
  title: 'Updated Title'
});

// List content
const list = await client.content.listContent({
  status: 'published',
  page: 1,
  pageSize: 20
});

// Search content
const results = await client.content.searchContent('search query', {
  page: 1
});

// Publish content
await client.content.publishContent('content-id');

// Archive content
await client.content.archiveContent('content-id');

// Version management
const versions = await client.content.getContentVersions('content-id');
await client.content.restoreVersion('content-id', 'version-id');

Workflow Management (client.workflow)

Editorial workflow and approval operations.

// Get workflows
const workflows = await client.workflow.getWorkflows();

// Check content workflow status
const status = await client.workflow.getContentWorkflowStatus('content-id');

// Advance to next stage
await client.workflow.advanceWorkflowStage('content-id', {
  comment: 'Looks good!'
});

// Reject current stage
await client.workflow.rejectWorkflowStage('content-id', 'Needs more work');

// Assign content
await client.workflow.assignContent('content-id', 'user-id');

// Get my assignments
const assignments = await client.workflow.getMyAssignments();

// Request approval
await client.workflow.requestApproval('content-id', ['approver-1', 'approver-2']);

// Approve/reject
await client.workflow.approveContent('content-id');
await client.workflow.rejectContent('content-id', 'Not ready');

AI Operations (client.ai)

AI-powered content operations.

// Request AI review
const review = await client.ai.requestAIReview('content-id', {
  checkGrammar: true,
  checkSEO: true,
  checkReadability: true
});

console.log(review.score); // 8.5
console.log(review.suggestions); // Array of suggestions

// Generate content
const generated = await client.ai.generateContent({
  prompt: 'Write about renewable energy',
  tone: 'professional',
  length: 'medium'
});

// Enhance existing content
const enhanced = await client.ai.enhanceContent('content-id', {
  improveTone: true,
  improveSEO: true
});

// Generate social posts
const socialPosts = await client.ai.generateSocialPosts('content-id', [
  'twitter',
  'linkedin',
  'facebook'
]);

// Get AI suggestions
const suggestions = await client.ai.getSuggestions('content-id');

// Apply a suggestion
await client.ai.applySuggestion('content-id', 'suggestion-id');

Social Media (client.social)

Social media publishing operations.

// Get connected accounts
const accounts = await client.social.getConnectedAccounts();

// Get social posts
const posts = await client.social.getSocialPosts('content-id');

// Update post
await client.social.updateSocialPost('post-id', {
  body: 'Updated post text'
});

// Publish to social
await client.social.publishToSocial('content-id', ['twitter', 'linkedin']);

// Get publishing status
const status = await client.social.getPublishingStatus('content-id');

// Get previews
const previews = await client.social.getSocialPreviews('content-id');

Scheduling (client.scheduler)

Content scheduling operations.

// Schedule content
await client.scheduler.scheduleContent(
  'content-id',
  new Date('2025-01-15T10:00:00Z')
);

// Reschedule
await client.scheduler.rescheduleContent(
  'content-id',
  new Date('2025-01-16T10:00:00Z')
);

// Cancel schedule
await client.scheduler.cancelSchedule('content-id');

// Get scheduled content
const scheduled = await client.scheduler.getScheduledContent({
  startDate: '2025-01-01',
  endDate: '2025-01-31',
  platform: 'twitter'
});

// Get calendar view
const calendar = await client.scheduler.getScheduleCalendar(
  new Date('2025-01-01'),
  new Date('2025-01-31')
);

// Multi-platform scheduling
await client.scheduler.scheduleMultiPlatform('content-id', {
  baseTime: new Date('2025-01-15T10:00:00Z'),
  platforms: [
    { platform: 'website', delay: 0 },
    { platform: 'twitter', delay: 5 },   // 5 minutes after
    { platform: 'linkedin', delay: 10 }  // 10 minutes after
  ],
  jitter: {
    enabled: true,
    maxMinutes: 3
  }
});

Media Management (client.media)

Media upload and management.

// Get upload URL
const upload = await client.media.getUploadUrl('image.jpg', 'image/jpeg');

// Upload file to presigned URL (using browser's File API)
const file = document.getElementById('file-input').files[0];
await fetch(upload.uploadUrl, {
  method: 'PUT',
  body: file,
  headers: { 'Content-Type': file.type }
});

// Confirm upload
const media = await client.media.confirmUpload(upload.uploadId);

// List media
const mediaList = await client.media.listMedia({
  page: 1,
  contentType: 'image/jpeg'
});

// Attach to content
await client.media.attachMedia('content-id', 'media-id');

// Get content media
const contentMedia = await client.media.getContentMedia('content-id');

// Delete media
await client.media.deleteMedia('media-id');

Analytics (client.analytics)

Content analytics and performance tracking.

// Get content analytics
const analytics = await client.analytics.getContentAnalytics('content-id');
console.log(analytics.views, analytics.engagement);

// Get performance data
const performance = await client.analytics.getContentPerformance('content-id', '7d');

// Get social analytics
const social = await client.analytics.getSocialAnalytics('content-id');

// Get platform breakdown
const breakdown = await client.analytics.getPlatformBreakdown('content-id');

// Get dashboard stats
const dashboard = await client.analytics.getDashboardStats('30d');

// Get top content
const topContent = await client.analytics.getTopContent('7d', 10);

Content Types (client.contentTypes)

Content type registry and validation.

// Get all content types
const types = await client.contentTypes.getContentTypes();

// Get specific type
const type = await client.contentTypes.getContentType('blog-post');

// Validate content
const validation = await client.contentTypes.validateContent('blog-post', {
  title: 'Test Article',
  body: 'Content...'
});

if (!validation.isValid) {
  console.error(validation.errors);
}

Error Handling

import { ContentManagementClientError } from '@bernierllc/content-management-suite-client';

try {
  await client.content.getContent('nonexistent');
} catch (error) {
  if (error instanceof ContentManagementClientError) {
    console.log(error.statusCode); // 404
    console.log(error.error); // 'NotFound'
    console.log(error.message); // 'Content not found'
    console.log(error.details); // Additional error details
  }
}

TypeScript Support

The package is written in TypeScript and provides complete type definitions:

import type {
  Content,
  ContentResult,
  ContentList,
  AIReviewResult,
  WorkflowStatus,
  Platform,
  Period
} from '@bernierllc/content-management-suite-client';

const handleContent = (content: Content) => {
  console.log(content.title, content.status);
};

Browser Compatibility

This package uses native browser APIs:

  • fetch() for HTTP requests
  • AbortController for request cancellation
  • No Node.js dependencies

Supports all modern browsers (Chrome, Firefox, Safari, Edge).

Testing

The package includes comprehensive tests with 97%+ coverage:

npm test              # Run tests
npm run test:coverage # Run with coverage
npm run test:watch    # Watch mode

Related Packages

  • @bernierllc/content-management-suite - Backend suite (Node.js only)
  • @bernierllc/email-manager-client - Similar client pattern for email manager

License

Copyright (c) 2025 Bernier LLC. All rights reserved.