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

@mybe/sdk

v1.1.2

Published

A TypeScript SDK for fetching content from Mybe CMS.

Downloads

131

Readme

Mybe CMS SDK

A TypeScript SDK for fetching content from Mybe CMS.

Installation

npm install @mybe/sdk

Features

  • Zero Dependencies - Uses native fetch API
  • TypeScript Support - Full type safety with TypeScript
  • Environment Support - Query content from different environments (master, staging, development)
  • Error Handling - Custom error classes for better error handling
  • Pagination Support - Built-in pagination for large datasets
  • Status Filtering - Filter content by status (draft, published, archived)
  • Locale Filtering - Filter content by locale for multi-language support
  • GraphQL Support - Powerful GraphQL API for flexible data querying

Quick Start

import { MybeSDK } from '@mybe/sdk';

// Initialize the SDK
const sdk = new MybeSDK({
  apiKey: 'your-api-key'
});

// Fetch a single content entry
const content = await sdk.getContent('content-id');

// Fetch content by type with filters
const contentList = await sdk.getContentByType('content-type-id', {
  status: 'published',
  limit: 10
});

Configuration

Basic Configuration

const sdk = new MybeSDK({
  apiKey: 'your-api-key'
  // Defaults to 'master' environment
});

Environment Configuration

Mybe CMS supports multiple environments for content isolation. Each SDK instance is locked to a specific environment.

// Production environment (default)
const prodClient = new MybeSDK({
  apiKey: 'your-api-key',
  environment: 'master' // or omit for default
});

// Staging environment
const stagingClient = new MybeSDK({
  apiKey: 'your-api-key',
  environment: 'staging'
});

// Development environment
const devClient = new MybeSDK({
  apiKey: 'your-api-key',
  environment: 'development'
});

// Custom environment (by slug or UUID)
const customClient = new MybeSDK({
  apiKey: 'your-api-key',
  environment: 'my-custom-env'
});

Environment Best Practices:

  1. Master Environment - Your production content (default)
  2. Staging Environment - Test changes before production
  3. Development Environment - Active development work
  4. Custom Environments - Feature branches, testing, etc.

Important: Each client instance is locked to its environment. To query different environments, create separate client instances.

// ✅ Correct: Separate clients for different environments
const prodPosts = await prodClient.getContentByType('blog-post-id');
const stagingPosts = await stagingClient.getContentByType('blog-post-id');

// ❌ Incorrect: Cannot switch environments on the same client
// You must create a new client instance

Custom Base URL (Optional)

const sdk = new MybeSDK({
  apiKey: 'your-api-key',
  baseUrl: 'https://custom-api.example.com/api/v1',
  environment: 'staging'
});

Getting Current Environment

const sdk = new MybeSDK({
  apiKey: 'your-api-key',
  environment: 'staging'
});

console.log(sdk.getEnvironment()); // 'staging'

API Reference

Content Models (Content Types)

getContentModels(projectId: string)

Get all content models for a project.

const contentModels = await sdk.getContentModels('project-id');

Returns: Promise<ContentType[]>

getContentModel(contentTypeId: string)

Get a specific content model by ID.

const contentModel = await sdk.getContentModel('content-type-id');

Returns: Promise<ContentType>

Content Entries

getContent(contentId: string)

Get a single content entry by ID.

const content = await sdk.getContent('content-id');

Returns: Promise<ContentEntry>

getContentByType(contentTypeId: string, options?: ContentFilterOptions)

Get all content entries for a specific content type.

const result = await sdk.getContentByType('content-type-id', {
  status: 'published',
  limit: 20,
  lastKey: 'pagination-key' // For pagination
});

console.log(result.data); // Array of content entries
console.log(result.pagination.hasMore); // Boolean
console.log(result.pagination.lastEvaluatedKey); // For next page

Options:

  • status?: 'draft' | 'published' | 'archived' - Filter by status
  • locale?: string - Filter by locale (e.g., 'en-US', 'bn-BD', 'fr-FR', 'es-ES')
  • limit?: number - Number of items per page
  • lastKey?: string - Pagination key from previous response

Returns: Promise<ContentListResponse>

getContentByProject(projectId: string, options?: ContentFilterOptions)

Get all content entries for a project.

const result = await sdk.getContentByProject('project-id', {
  status: 'published',
  limit: 20
});

Options:

  • status?: 'draft' | 'published' | 'archived' - Filter by status
  • locale?: string - Filter by locale (e.g., 'en-US', 'bn-BD', 'fr-FR', 'es-ES')
  • limit?: number - Number of items per page
  • lastKey?: string - Pagination key from previous response

Returns: Promise<ContentListResponse>

Pagination Example

let lastKey: string | undefined;
let allContent: ContentEntry[] = [];

do {
  const result = await sdk.getContentByType('content-type-id', {
    status: 'published',
    limit: 50,
    lastKey: lastKey ? JSON.stringify(result.pagination.lastEvaluatedKey) : undefined
  });

  allContent = [...allContent, ...result.data];
  lastKey = result.pagination.hasMore 
    ? JSON.stringify(result.pagination.lastEvaluatedKey) 
    : undefined;

} while (lastKey);

console.log(`Fetched ${allContent.length} total items`);

Error Handling

The SDK provides custom error classes for better error handling:

import { 
  MybeSDK, 
  NotFoundError, 
  UnauthorizedError,
  ValidationError,
  ServerError 
} from '@mybe/sdk';

try {
  const content = await sdk.getContent('content-id');
} catch (error) {
  if (error instanceof NotFoundError) {
    console.error('Content not found');
  } else if (error instanceof UnauthorizedError) {
    console.error('Invalid API key');
  } else if (error instanceof ValidationError) {
    console.error('Validation error:', error.message);
  } else if (error instanceof ServerError) {
    console.error('Server error:', error.message);
  } else {
    console.error('Unknown error:', error);
  }
}

Error Types

  • MybeSDKError - Base error class
  • NotFoundError - Resource not found (404)
  • UnauthorizedError - Invalid API key (401)
  • ForbiddenError - Insufficient permissions (403)
  • ValidationError - Validation failed (400)
  • ServerError - Internal server error (500)

TypeScript Types

The SDK exports all TypeScript types for your convenience:

import type {
  ContentType,
  ContentEntry,
  ContentFilterOptions,
  PaginationResponse,
  APIResponse,
  ContentListResponse
} from '@mybe/sdk';

ContentType

interface ContentType {
  id: string;
  project_id: string;
  name: string;
  slug: string;
  description?: string;
  created_at: string;
  updated_at: string;
}

ContentEntry

interface ContentEntry {
  id: string;
  content_type_id: string;
  project_id: string;
  slug?: string;
  status: 'draft' | 'published' | 'archived';
  data: Record<string, any>;
  locale?: string;
  created_by: string;
  updated_by?: string;
  published_at?: string;
  created_at: string;
  updated_at: string;
}

Examples

Environment-based Workflows

Development → Staging → Production

import { MybeSDK } from '@mybe/sdk';

// Create separate clients for each environment
const devClient = new MybeSDK({
  apiKey: 'your-api-key',
  environment: 'development'
});

const stagingClient = new MybeSDK({
  apiKey: 'your-api-key',
  environment: 'staging'
});

const prodClient = new MybeSDK({
  apiKey: 'your-api-key',
  environment: 'master'
});

// Development: Work with draft content
const draftPosts = await devClient.getContentByType('blog-post-id', {
  status: 'draft',
  limit: 10
});

// Staging: Test published content
const stagingPosts = await stagingClient.getContentByType('blog-post-id', {
  status: 'published',
  limit: 10
});

// Production: Serve live content
const livePosts = await prodClient.getContentByType('blog-post-id', {
  status: 'published',
  limit: 10
});

Environment-aware Application

// Automatically select environment based on NODE_ENV
const getSDKClient = () => {
  const apiKey = process.env.MYBE_API_KEY!;
  
  switch (process.env.NODE_ENV) {
    case 'production':
      return new MybeSDK({ apiKey, environment: 'master' });
    case 'staging':
      return new MybeSDK({ apiKey, environment: 'staging' });
    case 'development':
    default:
      return new MybeSDK({ apiKey, environment: 'development' });
  }
};

const sdk = getSDKClient();
console.log(`Using environment: ${sdk.getEnvironment()}`);

Preview Mode (Staging vs Production)

// Next.js example: Preview mode with environments
export async function getStaticProps({ preview = false }) {
  const sdk = new MybeSDK({
    apiKey: process.env.MYBE_API_KEY!,
    environment: preview ? 'staging' : 'master'
  });
  
  const posts = await sdk.getContentByType('blog-post-id', {
    status: preview ? 'draft' : 'published',
    limit: 20
  });
  
  return {
    props: {
      posts: posts.data,
      preview
    },
    revalidate: 60
  };
}

Fetch Published Blog Posts

const sdk = new MybeSDK({
  apiKey: 'your-api-key',
  environment: 'master' // Production content
});

const posts = await sdk.getContentByType('blog-post-type-id', {
  status: 'published',
  limit: 10
});

posts.data.forEach(post => {
  console.log(post.data.title);
  console.log(post.data.content);
});

Fetch All Content Models

const sdk = new MybeSDK({ apiKey: 'your-api-key' });

const contentModels = await sdk.getContentModels('project-id');

contentModels.forEach(model => {
  console.log(`${model.name} (${model.slug})`);
});

Fetch Single Content Entry

const sdk = new MybeSDK({ apiKey: 'your-api-key' });

const content = await sdk.getContent('content-entry-id');

console.log(content.data); // Your content data
console.log(content.status); // draft | published | archived

Compare Content Across Environments

const masterClient = new MybeSDK({
  apiKey: 'your-api-key',
  environment: 'master'
});

const stagingClient = new MybeSDK({
  apiKey: 'your-api-key',
  environment: 'staging'
});

// Fetch from both environments in parallel
const [masterContent, stagingContent] = await Promise.all([
  masterClient.getContentByType('blog-post-id', { limit: 10 }),
  stagingClient.getContentByType('blog-post-id', { limit: 10 })
]);

console.log(`Master has ${masterContent.data.length} posts`);
console.log(`Staging has ${stagingContent.data.length} posts`);

// Find differences
const masterIds = new Set(masterContent.data.map(p => p.id));
const stagingOnly = stagingContent.data.filter(p => !masterIds.has(p.id));
console.log(`${stagingOnly.length} posts only in staging`);

Multi-locale Content

Fetch content in different languages using the locale filter. TypeScript will autocomplete all supported locale codes when you type locale: '':

const sdk = new MybeSDK({ apiKey: 'your-api-key' });

// Fetch English content
// TypeScript autocompletes: 'en-US', 'en-GB', 'en-CA', 'en-AU'
const englishPosts = await sdk.getContentByType('blog-post-type-id', {
  status: 'published',
  locale: 'en-US', // ✨ Autocomplete suggests all 31 supported locales!
  limit: 10
});

// Fetch Bangla content
const banglaPosts = await sdk.getContentByType('blog-post-type-id', {
  status: 'published',
  locale: 'bn-BD', // ✨ Type-safe locale codes
  limit: 10
});

// Fetch French content
const frenchPosts = await sdk.getContentByType('blog-post-type-id', {
  status: 'published',
  locale: 'fr-FR',
  limit: 10
});

// Fetch Spanish content
const spanishPosts = await sdk.getContentByType('blog-post-type-id', {
  status: 'published',
  locale: 'es-ES',
  limit: 10
});

TypeScript Autocomplete Support:

The SDK provides full TypeScript autocomplete for all 31 supported locales:

import { SUPPORTED_LOCALES, type SupportedLocale } from '@mybe/sdk';

// View all supported locales
console.log(SUPPORTED_LOCALES);
// ['en-US', 'bn-BD', 'fr-FR', 'es-ES', 'de-DE', 'it-IT', ...]

// Use the type for type-safe locale handling
const userLocale: SupportedLocale = 'ja-JP'; // ✅ Valid
const invalidLocale: SupportedLocale = 'invalid'; // ❌ TypeScript error!

Building a Multi-language Website:

// Get user's preferred language
const userLocale = getUserPreferredLocale(); // e.g., 'bn-BD'

// Fetch content in user's language
const localizedContent = await sdk.getContentByType('content-type-id', {
  status: 'published',
  locale: userLocale,
  limit: 20
});

// Display localized content
localizedContent.data.forEach(item => {
  console.log(item.data.title); // Title in user's language
  console.log(item.metadata.locale); // e.g., 'bn-BD'
});

All Supported Locales:

The SDK supports 31 locales with full TypeScript autocomplete:

  • English: en-US, en-GB, en-CA, en-AU
  • European: fr-FR, es-ES, de-DE, it-IT, pt-PT, nl-NL, sv-SE, pl-PL, ru-RU
  • Americas: pt-BR, es-MX, es-AR, fr-CA
  • Asia-Pacific: ja-JP, ko-KR, zh-CN, zh-TW, hi-IN, th-TH, vi-VN, id-ID, ms-MY, fil-PH, bn-BD
  • Middle East & Africa: ar-SA, tr-TR, he-IL

Note: When you type locale: '' in your IDE, TypeScript will show all available options!

GraphQL API

Mybe CMS provides a powerful GraphQL API for flexible data querying. Use GraphQL when you need advanced filtering, want to request specific fields only, or prefer the GraphQL query language.

Quick Start with GraphQL

import { MybeSDK } from '@mybe/sdk';

const sdk = new MybeSDK({ apiKey: 'your-api-key' });
const PROJECT_ID = 'your-project-id';

// Execute a GraphQL query
const result = await sdk.graphql(PROJECT_ID, `
  query {
    blogPostCollection(limit: 10, where: { status: "published" }) {
      items {
        id
        slug
        data
      }
      total
    }
  }
`);

console.log(result.blogPostCollection.items);

GraphQL Method

graphql<T>(projectId: string, query: string, variables?: Record<string, any>)

Execute a GraphQL query against your project.

Parameters:

  • projectId - Your project ID
  • query - GraphQL query string
  • variables - Optional query variables (recommended for dynamic queries)

Returns: Promise<T> - The data from your GraphQL query

GraphQL Examples

Basic Collection Query

const { blogPostCollection } = await sdk.graphql(PROJECT_ID, `
  query {
    blogPostCollection(limit: 5) {
      items {
        id
        slug
        status
        data
        published_at
      }
      total
    }
  }
`);

console.log(`Total posts: ${blogPostCollection.total}`);
blogPostCollection.items.forEach(post => {
  console.log(post.data.title);
});

Filter by Status

const { blogPostCollection } = await sdk.graphql(PROJECT_ID, `
  query {
    blogPostCollection(where: { status: "published" }) {
      items {
        id
        slug
        data
      }
    }
  }
`);

Get Single Entry by ID

const { blogPost } = await sdk.graphql(PROJECT_ID, `
  query {
    blogPost(id: "entry-123") {
      id
      slug
      status
      data
      created_at
      published_at
    }
  }
`);

Using Variables (Recommended)

const result = await sdk.graphql(
  PROJECT_ID,
  `
    query GetPostBySlug($slug: String!) {
      blogPostCollection(where: { slug: $slug }) {
        items {
          id
          slug
          data
        }
      }
    }
  `,
  { slug: 'my-blog-post' }
);

const post = result.blogPostCollection.items[0];

Pagination with GraphQL

// Page 1
const page1 = await sdk.graphql(PROJECT_ID, `
  query {
    blogPostCollection(limit: 10, skip: 0) {
      items { id slug }
      total
    }
  }
`);

// Page 2
const page2 = await sdk.graphql(PROJECT_ID, `
  query {
    blogPostCollection(limit: 10, skip: 10) {
      items { id slug }
      total
    }
  }
`);

REST vs GraphQL - When to Use

Use REST When:

  • ✅ Simple queries (get by ID, get all)
  • ✅ You want straightforward API calls
  • ✅ You prefer SDK helper methods
  • ✅ You need full object responses

Use GraphQL When:

  • ✅ Complex filtering requirements
  • ✅ You need specific fields only (reduce payload size)
  • ✅ Multiple queries in one request
  • ✅ You want flexible, ad-hoc queries
  • ✅ Your frontend uses Apollo Client or similar

Complete GraphQL Guide

For comprehensive GraphQL documentation, examples, and best practices, see:

GraphQL Schema

Your GraphQL schema is automatically generated from your content types. For example:

Content Type: "Blog Post"
Generates:

  • blogPost(id: ID!) - Get single entry
  • blogPostCollection(limit, skip, where) - Get collection

Naming: Content type names are converted to camelCase (e.g., "Blog Post" → blogPost)

Requirements

  • Node.js 18+ (for native fetch support)
  • TypeScript 5.0+ (for development)

License

MIT

Support

For issues and questions, please visit the GitHub repository.