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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bernierllc/contentful-suite

v1.0.9

Published

Complete Contentful integration suite with ML training pipeline, headless CMS proxy, and content syndication

Downloads

503

Readme

@bernierllc/contentful-suite

Complete Contentful integration suite with ML training pipeline, headless CMS proxy, and content syndication.

Features

  • ML Training Pipeline: Full content export + incremental sync to local database
  • Headless CMS Proxy: API gateway with OAuth management and response caching
  • Content Syndication: Real-time webhook processing and event routing
  • Multi-Space Management: Centralized credential management for multiple spaces
  • Migration Support: Content model migrations with history tracking
  • NeverHub Integration: Service mesh integration for distributed systems

Installation

npm install @bernierllc/contentful-suite

Usage

Quick Start

Basic Setup

import {
  ContentfulSuite,
  InMemoryContentStorage,
  InMemorySyncStateStorage,
  InMemoryMigrationStorage
} from '@bernierllc/contentful-suite';

const suite = new ContentfulSuite({
  oauth: {
    clientId: process.env.CONTENTFUL_CLIENT_ID!,
    clientSecret: process.env.CONTENTFUL_CLIENT_SECRET!,
    redirectUri: 'http://localhost:3000/oauth/callback'
  },
  gateway: {
    enabled: true,
    port: 3000,
    apiKeys: ['your-internal-api-key']
  },
  sync: {
    enabled: true,
    interval: 300000, // 5 minutes
    spaces: [
      {
        spaceId: 'your-space-id',
        environmentId: 'master',
        accessToken: 'your-cda-token'
      }
    ]
  },
  webhooks: {
    enabled: true,
    port: 3001,
    secret: 'your-webhook-secret'
  },
  cache: {
    enabled: true,
    backend: 'memory',
    ttl: 300
  },
  migration: {
    enabled: true
  },
  storage: {
    contentStorage: new InMemoryContentStorage(),
    syncStateStorage: new InMemorySyncStateStorage(),
    migrationStorage: new InMemoryMigrationStorage()
  }
});

await suite.initialize();
await suite.start();

Use Cases

1. ML Training Pipeline

Export all content from Contentful to a local database for machine learning model training:

import { ContentfulSuite } from '@bernierllc/contentful-suite';

// Initialize suite with sync enabled
const suite = new ContentfulSuite({
  sync: {
    enabled: true,
    spaces: [
      {
        spaceId: 'your-space-id',
        environmentId: 'master',
        accessToken: 'your-cda-token'
      }
    ]
  },
  storage: {
    contentStorage: new InMemoryContentStorage(),
    syncStateStorage: new InMemorySyncStateStorage()
  },
  // ... other config
});

await suite.initialize();

// Get all content for training
const trainingData = await suite.getMLTrainingData('your-space-id');

// Filter by content type
const articles = await suite.getMLTrainingData('your-space-id', 'article');

// Train your ML model with the data
trainModel(trainingData);

Benefits:

  • No API rate limits during training (data is local)
  • Automatic incremental updates via webhooks + Sync API
  • Full content history and relationships preserved

2. Headless CMS Proxy

Create an API gateway that manages OAuth tokens and caches responses:

import { ContentfulSuite } from '@bernierllc/contentful-suite';

const suite = new ContentfulSuite({
  oauth: {
    clientId: process.env.CONTENTFUL_CLIENT_ID!,
    clientSecret: process.env.CONTENTFUL_CLIENT_SECRET!,
    redirectUri: 'http://localhost:3000/oauth/callback'
  },
  gateway: {
    enabled: true,
    port: 3000,
    apiKeys: ['internal-api-key-1', 'internal-api-key-2']
  },
  cache: {
    enabled: true,
    backend: 'redis',
    ttl: 300
  },
  webhooks: {
    enabled: true,
    port: 3001,
    secret: 'webhook-secret'
  },
  // ... storage config
});

await suite.initialize();
await suite.start();

// Gateway is now running at http://localhost:3000
// Use internal API key to make requests:
// GET http://localhost:3000/cda/space-id/master/entries
// Header: X-API-Key: internal-api-key-1

Benefits:

  • Centralized OAuth token management (no token refresh in clients)
  • Response caching for better performance
  • Webhook-based cache invalidation
  • Rate limiting per client
  • Multi-space routing

3. Content Syndication

Process webhooks in real-time and route content changes to subscribers:

import { ContentfulSuite } from '@bernierllc/contentful-suite';

const suite = new ContentfulSuite({
  webhooks: {
    enabled: true,
    port: 3001,
    secret: 'your-webhook-secret'
  },
  sync: {
    enabled: true,
    spaces: [{ spaceId: 'your-space-id', environmentId: 'master', accessToken: 'token' }]
  },
  // ... storage config
});

await suite.initialize();

// Subscribe to content events
const webhookService = suite.getWebhookService();
webhookService?.on('webhook.received', async (data) => {
  console.log('Content changed:', data);
  // Syndicate to other platforms
  await publishToTwitter(data);
  await publishToLinkedIn(data);
});

await suite.start();

// Configure Contentful webhook to POST to:
// http://your-domain:3001/webhooks/contentful

Benefits:

  • Real-time content propagation
  • Reliable delivery with retry logic
  • Dead letter queue for failed events
  • Event filtering and routing

4. Multi-Space Management

Manage multiple Contentful spaces from a single suite instance:

import { ContentfulSuite } from '@bernierllc/contentful-suite';

const suite = new ContentfulSuite({
  sync: {
    enabled: true,
    spaces: [
      {
        spaceId: 'space-1',
        environmentId: 'master',
        accessToken: 'token-1'
      },
      {
        spaceId: 'space-2',
        environmentId: 'staging',
        accessToken: 'token-2'
      }
    ]
  },
  migration: {
    enabled: true
  },
  // ... storage config
});

await suite.initialize();

// Run migration on specific space
await suite.runMigration('space-1', migrationScript, {
  id: 'migration-1',
  name: 'Add author field'
});

// Get sync service for specific space
const syncService = suite.getSyncService('space-1');
await syncService?.initialSync();

Storage Implementations

The suite uses abstract storage interfaces, allowing you to provide your own implementations:

In-Memory Storage (Included)

For testing and simple use cases:

import {
  InMemoryContentStorage,
  InMemorySyncStateStorage,
  InMemoryMigrationStorage
} from '@bernierllc/contentful-suite';

const config = {
  storage: {
    contentStorage: new InMemoryContentStorage(),
    syncStateStorage: new InMemorySyncStateStorage(),
    migrationStorage: new InMemoryMigrationStorage()
  }
};

Custom Storage Implementation

Implement the storage interfaces for your database:

import { ContentStorage, SyncStateStorage, MigrationStorage } from '@bernierllc/contentful-suite';

class PostgresContentStorage implements ContentStorage {
  async storeEntries(entries: ContentfulEntry[]): Promise<void> {
    // Store entries in PostgreSQL
  }

  async storeAssets(assets: ContentfulAsset[]): Promise<void> {
    // Store assets in PostgreSQL
  }

  // ... implement other methods
}

const suite = new ContentfulSuite({
  storage: {
    contentStorage: new PostgresContentStorage(),
    syncStateStorage: new PostgresSyncStateStorage(),
    migrationStorage: new PostgresMigrationStorage()
  }
});

Configuration

OAuth Configuration

Required for gateway service:

{
  oauth: {
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret',
    redirectUri: 'http://localhost:3000/oauth/callback'
  }
}

Gateway Configuration

API gateway with internal authentication:

{
  gateway: {
    enabled: true,
    port: 3000,
    apiKeys: ['key1', 'key2'] // Internal API keys for authentication
  }
}

Sync Configuration

Content sync with local storage:

{
  sync: {
    enabled: true,
    interval: 300000, // Polling interval in ms (default: 5 minutes)
    spaces: [
      {
        spaceId: 'space-id',
        environmentId: 'master',
        accessToken: 'cda-token'
      }
    ]
  }
}

Webhooks Configuration

Webhook receiving and processing:

{
  webhooks: {
    enabled: true,
    port: 3001,
    secret: 'webhook-secret' // For signature validation
  }
}

Cache Configuration

Response caching:

{
  cache: {
    enabled: true,
    backend: 'memory' | 'redis',
    ttl: 300 // Time to live in seconds
  }
}

Migration Configuration

Content model migrations:

{
  migration: {
    enabled: true
  }
}

API Reference

ContentfulSuite

Main orchestrator class.

Methods

initialize(): Promise<void>

Initialize all enabled services.

start(): Promise<void>

Start all services (gateway, webhooks, sync polling).

stop(): Promise<void>

Stop all services gracefully.

getMLTrainingData(spaceId: string, contentType?: string): Promise<any[]>

Get content from local storage for ML training.

runMigration(spaceId: string, script: string, options: MigrationOptions): Promise<void>

Run a migration on a specific space.

getHealth(): SuiteHealth

Get health status of all services.

Service Getters
  • getGateway(): ContentfulGatewayService | undefined
  • getSyncService(spaceId: string): ContentfulSyncService | undefined
  • getWebhookService(): ContentfulWebhookService | undefined
  • getCacheService(): ContentfulCacheService | undefined
  • getMigrationService(spaceId: string): ContentfulMigrationService | undefined

Integration Status

This package integrates with the following BernierLLC services:

  • Logger: Integrated - Uses @bernierllc/logger for structured logging across all services
  • NeverHub: Optional - Automatically detects and integrates with NeverHub service mesh when available

Logger Integration

The suite uses @bernierllc/logger for consistent structured logging across all services:

  • Gateway service logs API requests and OAuth events
  • Sync service logs content synchronization operations
  • Webhook service logs incoming webhook events
  • Migration service logs schema changes

NeverHub Integration

The suite automatically integrates with NeverHub if available:

// NeverHub events published:
- contentful.suite.started
- contentful.suite.stopped

// NeverHub events subscribed:
- system.shutdown (graceful shutdown)
- config.updated (reload configuration)

Dependencies

This suite bundles all Contentful packages:

Core Packages

  • @bernierllc/contentful-types
  • @bernierllc/contentful-client-core
  • @bernierllc/contentful-auth
  • @bernierllc/contentful-cma-client
  • @bernierllc/contentful-cda-client
  • @bernierllc/contentful-graphql-client
  • @bernierllc/contentful-webhook-handler
  • @bernierllc/contentful-export-adapter
  • @bernierllc/contentful-rich-text

Service Packages

  • @bernierllc/contentful-gateway-service
  • @bernierllc/contentful-sync-service
  • @bernierllc/contentful-webhook-service
  • @bernierllc/contentful-cache-service
  • @bernierllc/contentful-migration-service

Infrastructure

  • @bernierllc/config-manager
  • @bernierllc/logger
  • @bernierllc/neverhub-adapter

License

Copyright (c) 2025 Bernier LLC. See LICENSE file for details.