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

ubermind

v1.6.1

Published

an open source firebase clone that mounts to an express endpoint and uses mongoDB as a persistence layer.

Downloads

6

Readme

ubermind

an out of the box, build-your-own Firebase-like implementation that can be bound to any express server at a customizeable endpoint or booted up on its own with node or docker.

  • free & open source (AGPL-3.0 licensed)
  • webhook events for document and collection events
  • REST API out of the box
  • can be started from the command line
  • docker container for out of the box deploys
  • connects to any existing mongo, and can utilize existing data
  • easily extensible / reusable

why?

Don't reinvent the wheel. When you need a simple backend persistence layer, you don't need to write an endpoint and controller for everything. 99% of CRUD tasks can be accomplished with a REST interface. Instead, focus on the other difficult parts of your application.

Since each method is exposed on the root, you can pick and choose what methods you want to use, or you can just mount everything to a custom endpoint and go from there.

use cases

  • Easy analytics capture
  • Quick CRUD backend to use
  • Any project requiring a fairly simple REST API

getting started with docker

npm install -g ubermind

If you want to use Docker, the CLI exposes a quick command for you. Then you can run ubermind docker and it will boot up a Mongo and Ubermind container for you and link them together.

If you want to configure the Docker containers more, you can use the docker-compose.override.yml to override the docker-compose environment.

getting started with an existing app

If you have an existing app and you just want the CRUD functionality from Ubermind, you can install it as an Express route handler.

First, install ubermind and save it

npm install --save ubermind

mount the middleware to express

Then mount Ubermind to your app

const express = require('express')
const ubermind = require('ubermind')

const app = express()
// mount it to an endpoint
app.use('/ubermind', ubermind({
  timestamps: true, // adds timestamps to every object, defaults to true
  webhook: 'localhost:3000', // where it will post events to, defaults to this
  db: 'localhost:27017/ubermind' // specify the database connection string, defaults to this
}));

app.listen(3000, () => {
  console.log('listening on port 3000')
});

This will expose the ubermind middleware on to /ubermind of your server. If you want to change that URL, simply adjust what route you mount it to.

If you do a GET request to the root /ubermind URL, you'll see a specification of your ubermind endpoint, version, etc...

Create documents

To create a document, you can simply send a POST request to the /ubermind endpoint.

POST request to /ubermind takes a data paylaod of

{
  model: 'todos', // the name of the collection
  data: {
    // any fucking data you want   
  }
}

You can also send the model as a url parameter, like this

/ubermind/todos

and then in the body of the request, you'd put the data

  data: {
    // any other data
  }

You don't need to define the models anywhere. Mongo doesn't enforce schemas, so why would we?

Query Documents

If you want to query collections, you can query them with query params on the model. This is the endpoin that will be doing most of the heavy lifting for querying. You can query by any key on your documents using this endpoint, as well as add pagination with skip, limit, and offset query params.

GET /ubermind/todos?limit=50?skip=5 will return all the todos collection.

GET /ubermind?model=todos?limit=50 will return the first 50 documents in the todos collection.

Both endpoints allow you to add query params.

Complex Queries

If you want to use complex queries with Mongoose, e.g. use aggregations, etc... You can use the /query endpoint to do just that.

POST /query will allow you to send a request body of any object.


{
  "model": "projects",
  "query": {
    // your query goes here 
  }
}

This allows you to do anything that you can do with the mongoose find() method.

Update documents

PUT /ubermind

{
  model: 'todos',
  id: '1234',
  data: {
    // data to update document with
  }
}

or you can do a similar URL parameter request

PUT /ubermind/todos

{
  id: '1234',
  data: {
    // data to update document with
  }
}

or PUT /ubermind/todos/1234 and this will accept an updated document

{
  // any data goes here 
}

Delete documents

You can also delete documents with a DELETE request.

Delete single document

DELETE /ubermind

{
  model: 'todos',
  id: '1234'
}

Delete All

Delete all documents in a collection.

Since this is a dangerous operation, it requires the deleteAll property to be set.

You can turn this action off in the configs object (see configs section)

DELETE request

{
  model: 'todos',
}

deleteAll: true must be set in the config

Delete by query

You can delete by parameter as well

{
  model: 'todos',
  query: {
    // add any query params. anything that matches will be deleted 
  }
}

Response Objects

The server sends back a response object for every request that has the following format:

{
  status: xxx,
  message: <success or error message>,
  data: {
    // your response data 
  }
}

Authentication & Middleware

You can add any authentication middleware in front of the ubermind middleware to lock down the endpoint.

To do this, you use the auth field on the config object.

Here's an example that locks down creation but allows public read access.

{
  auth: {
    create: function(req, res, next) {
      let token
      if (req.token || req.query.token || req.cookies.token) {
        const error = validateToken(token)
        if (error) return res.status(404).send('Not Authorized')
        return next()
      }
    }
  }
}

In this example, validateToken would be your own function (This is neither the time nor place to conver an auth tutorial) but you get the general idea.

The supported config functions that you can specify are

  getRoot
  query
  create
  update
  delete
  find
  findOne
  findOneBy
  updatedOne
  deleteOne
  all

If you use all that middleware will be applied to every request. This is a good solution if you want to lock down your entire service, add authentication, add logging, add rate limiting, etc...

Configuration Options

The middleware takes an optional configuration option

deleteAll // not implemented timestamps logger // not implemented

Databse string

Must be a valid connection string. Follows mongojs connection string formatting. You can read more about that here.

Timestamps

If timestamps is set to true in the configuration, then each object will be created with a created_at key. On update, each object will have a updated_at key either added or updated, depending on if the document has been updated before.

Command Line Deployment

Out of the box, ubermind can start a server from the command line that will listen on port 1337.

If you want to start it up by the command line`

npm install -g ubermind

Then you can run

ubermind --help for a print out of all the available commands.

Docker Deployment

You can also start a docker container that will host the hivmeind server.

docker run -p 1337:1337 --link mongo:mongo -e MONGO_URI=<your_mongo_db_uri> -d --name ubermind ubermindapps/ubermind

Or there's a docker-compose file that you can curl down and docker-compose up

Admin interface

Ubermind will mount a dashboard to /dashboard/ from whatever URL you configured as your base. From there, you will be prompted with a username and password box.

The defaults are

username: admin 
password: pass

If you want to change these, add fields to the ubermind config for each of these values.

i.e.

ubermind({
..., // other properties of your config
username: 'exampleusername', 
password: 'examplepassword'
})

Events

Database events

db_connected - Emitted on database successful connection db_error - Emitted on database error

Collection Events

These are fired when actions on a collection happen. Events are fired in the EventEmitter (Node lifecycle), to the Webhook URL, and to the Socket.io URL. They all have the same naming convention and payloads.

<collection>:created - Emitted when a model is created. They payload of this event is the object that was created. <collection>:updated - Emitted when a model is updated. The payload this event is the <key>:<value> pairs that were changed. <collection>:deleted - Emitted when a model is deleted. The payload of this event is the id(s) of the documents that were deleted.

Roadmap

2.0 Goals

  • [X] Configurable but simple authentication setup
    • [X] Expose each endpoint for different authentication / authorization
  • [ ] Socket.io introduction (currently only supports webhook)
  • [ ] Sharding / replication setup
  • [X] Docker container
  • [X] Command line startup via ubermind run
  • [X] Improved querying capabilities
  • [X] Database admin panel

Contributing

Development

I use nodemon to detect changes in local development. You can run example.js with this and it loads in the library.

nodemon example.js

Got an improvement? Fixed a bug? Make a PR, I'll check it out.

License

AGPL-3.0 licensed