Headless CMS plugin for B-Dashboard with content modeling, multi-database support, and auto-generated APIs
npm install b-dashboard-plugin-cmsbash
npm install @b-dashboard/plugin-cms
or
pnpm add @b-dashboard/plugin-cms
or
yarn add @b-dashboard/plugin-cms
`
Quick Start
$3
`typescript
// app/plugins.ts
import { registerPlugin } from '@/lib/plugins';
import cmsPlugin from '@b-dashboard/plugin-cms';
registerPlugin(cmsPlugin);
`
$3
`typescript
import { initializeCMS } from '@b-dashboard/plugin-cms';
// With default SQLite configuration
await initializeCMS({});
// Or with custom configuration
await initializeCMS({
database: {
type: 'sqlite',
sqlite: { filename: './data/cms.db' }
},
media: {
basePath: './uploads',
baseUrl: '/uploads',
maxSize: 10 1024 1024, // 10MB
allowedTypes: ['image/', 'video/', 'application/pdf']
},
content: {
defaultLocale: 'en',
locales: ['en', 'ar', 'es'],
enableDrafts: true,
enableVersioning: false
}
});
`
$3
`typescript
import { contentTypeService } from '@b-dashboard/plugin-cms';
const blogPost = await contentTypeService.create({
name: 'Blog Post',
slug: 'blog-posts',
description: 'Blog articles',
fields: [
{
id: 'title',
name: 'Title',
type: 'text',
required: true
},
{
id: 'content',
name: 'Content',
type: 'richtext',
required: true
},
{
id: 'featured_image',
name: 'Featured Image',
type: 'media'
},
{
id: 'published_date',
name: 'Published Date',
type: 'date'
}
],
titleField: 'title'
});
`
$3
`typescript
import { entryService } from '@b-dashboard/plugin-cms';
const post = await entryService.create({
contentTypeId: blogPost.id,
status: 'draft',
data: {
title: 'My First Blog Post',
content: 'Hello, world!
',
published_date: '2024-01-15'
}
});
// Publish the entry
await entryService.publish('blog-posts', post.id);
`
$3
`typescript
import { entryService } from '@b-dashboard/plugin-cms';
// Get all published posts
const posts = await entryService.getAll('blog-posts', {
status: 'published',
sort: 'published_date',
order: 'desc',
page: 1,
limit: 10
});
`
API Reference
$3
`typescript
import { contentTypeService } from '@b-dashboard/plugin-cms';
// Get all content types
const types = await contentTypeService.getAll();
// Get by ID or slug
const type = await contentTypeService.getById(id);
const type = await contentTypeService.getBySlug('blog-posts');
// Create
const newType = await contentTypeService.create({ ... });
// Update
const updated = await contentTypeService.update(id, { ... });
// Delete
await contentTypeService.delete(id);
`
$3
`typescript
import { entryService } from '@b-dashboard/plugin-cms';
// List entries with pagination
const entries = await entryService.getAll('blog-posts', {
page: 1,
limit: 20,
status: 'published',
search: 'keyword',
sort: 'createdAt',
order: 'desc',
filters: { category: 'tech' }
});
// CRUD operations
const entry = await entryService.getById('blog-posts', id);
const created = await entryService.create({ ... });
const updated = await entryService.update('blog-posts', id, { ... });
await entryService.delete('blog-posts', id);
// Status operations
await entryService.publish('blog-posts', id);
await entryService.unpublish('blog-posts', id);
await entryService.archive('blog-posts', id);
// Bulk operations
await entryService.bulkDelete('blog-posts', [id1, id2, id3]);
await entryService.bulkUpdateStatus('blog-posts', [id1, id2], 'published');
`
$3
`typescript
import { mediaService } from '@b-dashboard/plugin-cms';
// Configure media service
mediaService.configure({
basePath: './uploads',
baseUrl: '/uploads',
maxSize: 10 1024 1024,
allowedTypes: ['image/', 'video/', 'application/pdf']
});
// Upload file
const result = await mediaService.upload(buffer, {
filename: 'image.jpg',
mimeType: 'image/jpeg',
size: buffer.length,
alt: 'My image',
folder: 'blog'
});
// List media
const media = await mediaService.getAll({
page: 1,
limit: 20,
folder: 'blog',
mimeType: 'image/*',
search: 'keyword'
});
// Update metadata
await mediaService.update(id, { alt: 'Updated alt text' });
// Delete
await mediaService.delete(id);
`
$3
`typescript
import { databaseService } from '@b-dashboard/plugin-cms';
// Initialize with configuration
await databaseService.initialize({
type: 'sqlite',
sqlite: { filename: './data/cms.db' }
});
// For MySQL (Pro)
await databaseService.initialize({
type: 'mysql',
mysql: {
host: 'localhost',
port: 3306,
database: 'cms',
user: 'root',
password: 'password'
}
});
// For PostgreSQL (Pro)
await databaseService.initialize({
type: 'postgresql',
postgresql: {
host: 'localhost',
port: 5432,
database: 'cms',
user: 'postgres',
password: 'password'
}
});
// Execute queries
const result = await databaseService.query('SELECT * FROM cms_content_types');
await databaseService.execute('UPDATE cms_media SET alt = ? WHERE id = ?', ['alt', id]);
// Transactions
await databaseService.transaction(async (tx) => {
await tx.execute('INSERT INTO ...');
await tx.execute('UPDATE ...');
});
`
Field Types
| Type | Description | Options |
|------|-------------|---------|
| text | Single/multi-line text | minLength, maxLength, pattern, placeholder, multiline |
| richtext | HTML formatted text | minLength, maxLength, allowedFormats |
| number | Integer or decimal | min, max, step, precision, format |
| boolean | True/false toggle | defaultValue, trueLabel, falseLabel |
| date | Date without time | minDate, maxDate, format |
| datetime | Date with time | minDate, maxDate, format, timezone |
| json | Structured JSON data | schema |
| media | Files, images, videos | allowedTypes, maxSize, multiple, maxFiles |
| relation | Link to other entries | targetType, relationType, displayField, cascade |
| enum | Select from options | options, multiple |
| slug | URL-friendly text | sourceField, prefix, suffix |
| email | Email address | allowedDomains |
| url | Web URL | allowedProtocols |
License Verification
The CMS plugin uses the B-Dashboard license server for premium features:
`typescript
// Check license status
const licenseStatus = await checkLicense('@b-dashboard/plugin-cms');
if (licenseStatus.valid && licenseStatus.features.includes('postgresql_database')) {
// Enable PostgreSQL support
}
`
Directory Structure
`
plugins/cms/
βββ src/
β βββ index.ts # Main exports
β βββ manifest.ts # Plugin manifest
β βββ types.ts # TypeScript types
β βββ schemas.ts # Zod validation schemas
β βββ services/
β βββ index.ts
β βββ database.service.ts
β βββ content-type.service.ts
β βββ entry.service.ts
β βββ media.service.ts
β βββ migration.service.ts
βββ locales/
β βββ en.json
β βββ ar.json
βββ package.json
βββ tsconfig.json
βββ tsup.config.ts
βββ README.md
`
Contributing
1. Fork the repository
2. Create your feature branch (git checkout -b feature/amazing-feature)
3. Commit your changes (git commit -m 'Add some amazing feature')
4. Push to the branch (git push origin feature/amazing-feature`)