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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@becomes/cms

v1.0.177

Published

Simple CMS for building APIs.

Downloads

1,218

Readme

Becomes CMS - In Development

Get Started

  • Instal CMS CLI package globally: npm i -g @becomes/cms-cli
  • Setup MongoDB database:
  • Navigate to project and run npm run dev
  • Open browser, goto localhost:1280 and create Admin user.

Introduction

This is a small CMS developed by company Becomes that is specialized for building APIs. It was created because of project needs in our company and we decided to make it Open-Source since it solved a lot of problems that we had with other CMS solutions. We hope that you will find it useful in your next project.

  • What Becomes CMS is not?
    • It is not replacement for WordPress - WordPress is used for creating websites while Becomes CMS is used for creating APIs that will be consumed by other services. In this regard, they are completely different.
    • It is not Website generator - As said in previous point, Becomes CMS is used for creating APIs that will be consumed by some other service. You cannot create web pages publicly accessible over Becomes CMS.
    • It is not replacement for highly specialized APIs - Altho you can create any data model using Becomes CMS and manage them thru interactive dashboard, it is not designed to replace an API where very high performance is required.
  • What is Becomes CMS?
    • In one sentence, it is highly flexible and interactive tool for creating APIs that will be consumed by other services.

Terminology

In this document, few "special" words will be used and they have specific meaning.

  • Template - It is a container that holds information about how new Entry should be created, it structure and how it should behave. In addition to that, Template is holding pointers to all available Entries. By itself, Template is nothing more then a template for creating Entries and keeping them in sync with each other, therefore the name is as it is. Template also dictates type of an Entry that can be created by it:
    • Data Modal - This type defines that Entry is a "primitive" object, like plane JSON object (not actually but close enough). Example is a web store item, order, subscription or any other object that can be represented using key-value pairs.
    • Rich Content - This type defines that Entry is a "complex" object and it extends Data Model type. This means that in addition to key-value pairs, it also has User editable rich content. Some examples are: blog post, case study post or any other type of content that will be consumed by humans in readable form.
  • Entry - It is an object that holds actual data in structured way that is useful to a consumer of the CMS API. The structure is defined by Template.
  • Group - It is a placeholder object for creating complex and nested properties in Entry. For example, if it is required for Entry to have object property (non primitive one, like string, number...) Group is used to achieve this.
  • User - It is an entity which is authorized to access CMS dashboard. User can have roles: ADMIN or USER (more information in Users section).
  • Widget - It is a special placeholder object that can be only used in Entries of type Rich Content.
  • Webhook - It is a special object that can be configured to trigger CMS API function called webhook.
  • Function -

By showing some examples this terminology might be easier to understand.

Short Examples

Example 1 - Using CMS to create a Blog website.

The core function of a blog website is a Blog Post. Every blog post on a website follows the same structure: title, cover image, author and content. Only thing that is different between 2 blog posts is the content. Therefore, in this example, Template is defining blog post structure (title property is of type string, cover image is of type string, author is of type Group and so one) while Entry is a single Blog Post and this means that it is holding values for properties defined in Template (title is "My first blog", cover image is "/image.png", author is "{name: "Tom", position: "CEO"}" and so one).

Example 2 - Using CMS to create a simple web store.

The core function of a web store is an Item. To make it as simple as possible this online store is selling 2 Item types: Books and Makers. Books will be defined by creating a Template with properties: name <string>, title <string> and author <string> while Markers will be defined by creating a new Template with properties: name <string>, price <number> and quantity <number>. With this done Book Entry and Marker Entry can be added since structure is defined by Books Template and Markers Template respectively.

Back-end

Becomes CMS can be split into 2 parts, Back-end part that is built using Purple Cheetah framework and Front-end part that is built using Svelte.

User

It is a special model used to describe a CMS user which is a person. If it is required for service or robot to be able to access CMS content, it is highly recommended to use API Key for that since its access level can be restricted. Every User must have unique email and strong password. Email does not have to be valid but it has to be unique.

Security

Back-end uses 2 types of security:

JWT

JWTs are used for dashboard and for other services that want to take full control over Core CMS API. If full access to Core API is not required for consumer, it is recommended to use Key Security.

To obtain JWT Access Token and Refresh Token for a User (created using dashboard), Basic Authorization flow is used with User email and password for endpoint /auth/user. If authorization is successful, API will respond with token

  Response {
    accessToken: string,
    refreshToken: string,
  }

API Key

API Key is created using dashboard, while HTTP Signature is used for authentication when calling Core API. Function below can be used to create HTTP Signature for a request using API Key.

const crypto = require('crypto');

exports.sign = (payload) => {
  const data = {
    key: process.env.API_KEY,
    timestamp: Date.now(),
    nonce: crypto.randomBytes(3).toString("hex"),
    signature: ""
  };
  let payloadAsString = "";
  if (typeof payload === "object") {
    payloadAsString = Buffer.from(JSON.stringify(payload)).toString(
      "base64"
    );
  } else {
    payloadAsString = "" + payload;
  }
  data.signature = crypto
    .createHmac("sha256", process.env.API_SECRET)
    .update(data.nonce + data.timestamp + data.key + payloadAsString)
    .digest('hex');
  return data;
};

Generated parameters are parsed in a query with same name.