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 🙏

© 2025 – Pkg Stats / Ryan Hefner

hami-express

v1.0.14

Published

Hami ( to give ) is a module that uses mongoose models to create CRUD rest endpoints as well as socket events using express.js. This creates endpoints such as

Readme

Hami Express 🔨

Hami ( to give ) is a module that uses mongoose models to create CRUD rest endpoints as well as socket events using express.js. This creates endpoints such as

  • Get one record ✔️
  • Get many records ✔️
  • Get record by ID ✔️
  • Get records count 🧪
  • Create One record ✔️
  • Create Many records ✔️
  • Update One record ✔️
  • Update many records ✔️
  • Delete one record ✔️
  • Delete many records ✔️
  • Live events [ onUpdate, onCreate, onDelete ] ✔️🧪
  • hooks [ pre, post ]
  • custom routes
  • sync

Getting started

We first pass in the express app into createHami like so const hami = createHami(app). This will setup hami up so that can be ready to start generating routes and live events for your mongoose models hami(routes)

Creating Models

/models/record-model.js

const {model} = require('mongoose')
const {hamiSchema} = require('hami-express')

const RecordSchema = hamiSchema({
	displayName: String,
	group: { type:String, enum: ['average', 'awesome'], default: '' }
})

exports.RecordModel = model('record', RecordSchema)

Note hamiSchema({...}) is a helper function that adds timestamps for createdAt, updatedAt and deletedAt. eg.

const record = hamiSchema({...})

is the same as

const record = new Schema({
    ...,
   deletedAt: {type: Date}
}, {timestamp: true})

Creating Routes

/routes.js

const {RecordModel} = require('./models/record-model')

module.exports = [
   {model: RecordModel},
]

Using HamiExpress

const express = require('express')
const {connect} = require('mongoose')
const bodyParser = require('body-parser')
const {createHami} = require('hami-express')
const routes = require('./routes')

const startTestServer = async () => {
	// connecting to mongodb URI
	await connect(MONGODB_URI, {
		useCreateIndex: true,
		useFindAndModify: true,
		useNewUrlParser: true,
		useUnifiedTopology: true
	})

	const app = express()
   
    // required to parse json payload
	app.use(bodyParser.json())

	// creating routes on hami
	// returns http server
	const hami = createHami(app)
	const server = hami(routes)
	return server
}

startTestServer()
	.then(server => {
		server.listen(SERVER_PORT, () => {
			console.log('Server started on port', SERVER_PORT)
		})
	})
	.catch(err => {
		console.error(err)
	})

Generated routes

Get records

1. records/one

  • Method - GET
  • Query - { filter: MongoDbQuery }

2. records/count

  • Method - GET
  • Query - { filter: MongoDbQuery }

3. records/many

  • Method - GET
  • Query - { filter: MongoDbQuery, sort: MongooseSortObject, limit: Number }

4. records/:id

  • Method - GET
  • Param - RecordID

Create records

5. records/one

  • Method - POST
  • body - Record

6. records/many

  • Method - POST
  • body - [Record]

Update records

7. records/one

  • Method - UPDATE
  • Query - { filter: MongoDbQuery }
  • body - Record

8. records/many

  • Method - UPDATE
  • Query - { filter: MongoDbQuery, sort: MongooseSortObject, limit: Number }
  • body - UpdateRecord

Delete records

9. records/one

  • Method - DELETE
  • Query - { filter: MongoDbQuery }

10. records/many

  • Method - DELETE
  • Query - { filter: MongoDbQuery }

Websocket using Socket.IO

This feature is experimental since I do not know how to achieve this without passing arguments for filtering the events, But if you know of a better way don't hesitate sharing or creating a PR.

Server

First you will need to inject socket.io into hami as a dependency as socketServer.

const socketServer = require('socket.io')
const {createHami} = require('hami-express')

...

const hami = createHami(app)
const server = hami(routes, { socketServer })

...

Client

There are three types of events you can subscribe to. These are

  1. records:create - When a record is created
  2. records:update - When a record is updated
  3. records:delete - When a record is deleted

To listen to events, you must first emit a message to your hami-express server which subscribes you for getting events. The format for the events are the model names in plural and the hook. Example, if the model name is bakery and the hook you want is create, Then the event would be bakeries:create. A MongoDBQuery can be passed as an argument to filter what events to receive.

Now, to listen to the event, calling on records:created, will send you an event when a record is being created. Note to listen to the event, use the past tense of the hook. Bellow is the mapping for the listeners

  1. records:create = records:created
  2. records:update = records:updated
  3. records:delete = records:deleted

Example

const listenToRecords = async (callback) => {
    const socket = io(HAMI_EXPRESS_URL)
    // Subscribe
    socket.on('connect', ()=>{
        socket.emit('records:create', { group: { $eq: 'awesome' } })
    })
    // Listen
    socket.on('records:created', callback)
    // To disconnect when done listening 
    return socket.disconnect
}

const stopListeningToRecords = listenToRecords(({event, data})=>{
	console.log(event) // records:created
    console.log(data) // [ Records ]
})

// disconnect
stopListeningToRecords()

Note, the same version of socket.io used on the server should be the same used on the client. Otherwise, the socket connection won't work.

Javascript Client