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

reduquelize

v1.0.2

Published

**Use at your own risk.**

Downloads

2

Readme

Reduquelize (Alpha)

Use at your own risk.

A convenient reduction of the Sequelize API.

Sequelize is a crazy powerful ORM. But it can often be unintuitive to reason about. Reduquelize takes a pre-authenticated Sequelize database connection and returns a simpler set of functionality where the results of your queries are more intuitive and universal and your ability to control database records is made easier.

How does it work?

Start by defining your Sequelize models. No need to re-invent that part of the wheel. Once the models are defined on the connection, pass that connection to Reduquelize's reduce function.

import Sequelize from 'sequelize';
import reduce from 'reduquelize';

const connection = new Sequelize({ <DB CONFIG HERE> });

connection.authenticate().then(() => {

  connection.define('user', {
    id:   { type: Sequelize.STRING, primaryKey: true, unique: true },
    name: { type: Sequelize.STRING },
    age:  { type: Sequelize.INTEGER }
  });

  // And now we make it simpler!
  const db = reduce(connection);

});

"Reducing" your Sequelize connection gives you a set of functionality that makes things very simple. For example, if you wanted to retrieve a user with the id of 1. You'd do this:

db.Users.get(1)

Each of the models you've defined with Sequelize now exists as a capitalized, pluralized, class representing its associated database table. Because we defined a "user" Sequelize model, we now have a Users class.

These classes can do lots of things. To find out what all of those things are, check out the API at the bottom of this doc. For now, let's explore what happens after performing that Users.get(1) call from above.

One thing to keep in mind is that each model method returns a promise. When .get resolves, it'll hand you a record object representing the retrieved data. The record object is nice because you can modify it directly and call save on it to save your changes in the database!

Let's illustrate by retrieving a user and updating its name.

db.Users.get(1)

.then(user => {
  user.name = 'Sally';
  return user.save();
})

.then(user => {
  console.log(user.name); // <- Sally
})

The promises are nice for async/await as well.

const user = await db.Users.get(1);
user.name = 'Sally';
await user.save();
console.log(user.name); // <- Sally

Now let's say you wanted to create a new user. When you call the create method, your new record isn't saved to the database automatically. You'll have to call save to get it in there. This allows you to spin up a new record and then mess around with it before it actually gets stored anywhere.

db.Users.create({name: 'Billy', age: 34}).then(billy => {
  if (billy.age > 30) {
    billy.save(); // Store it!
  }
})

You can check out more record methods in the API reference further down. But before we get there, let's try retrieving a bunch of records at once.

db.Users.getMany({age: { $gt: 20 }}).then(users => {
  console.log(users, '<- Found all records where age is greater than 20!');
});

When you want to grab multiple records by some criteria, you'll call the getMany method and pass in a query object that gets passed directly to Sequelize's where parameter. This way you can make use of the raw power of Sequelize with a little bit less verbosity.

Augmenting models

By now you already know that when you reduce a Sequelize connection, you get a collection of models that provide simple methods for working with database tables. However, it's likely you'll want to build on this functionality. You can add new static methods to a class by calling the augment method on a model, like so:

const Users = db.Users.augment({

  getAdults() {
    return Users.getMany({age: {$gte: 18}});
  },

  countChildren() {
    return Users.count({age: {$lt: 18}});
  }

});

It's true that you could just assign new methods with an equals sign (i.e. db.Users.getAdults = () => {}) but augment is nice because it allows you to add multiple methods at once, returns the class, and also checks to make sure you're not overwriting a method that already exists on the class.

One other useful trick you can use when augmenting your models is to call the createReduction method on a record. This method will generate a copy of the record, but with its fields reduced down to only the fields you specify. Consider this example for how that might be useful:

const Users = db.Users.augment({

  // User records have passwords on them!
  // We don't want that!
  getSafe(id) {

    // Return a new record with only the speficied fields
    return Users.get(id).then(user => user.createReduction(
      'username',
      'createdAt',
      'lastLogin',
      'isAdmin'
    ))
  }

})

API

Model API

static augment(Object methods)

Adds new static methods to the model and throws an error if a method by the same name already exists.

Returns the model.

static count([Object where])

Counts how many database records exist for this model. If where is provided, counts only those records conforming to the conditions.

Returns a promise resolving with an integer.

static create(Object fields)

Creates a new record object from the provided fields. Does not save the record to the database.

Returns a promise resolving with the new record.

static saveCreate(Object fields)

Creates a new record object from the provided fields and saves it to the database.

Returns a promise resolving with the new record.

static get(AnyType primaryKey)

Retrieves a record from the database where the primary key value matches primaryKey.

Returns a promise resolving with the record.

static getOne(Object where)

Retrieves a single record matching the provided criteria.

static getMany([Object where, Number limit])

Retrieves an array of records for this model. If where is provided, retrieves only those records conforming to the conditions. If limit is provided, will return a number of items up to the limit.

Returns a promise resolving with an array.

static update(AnyType primaryKey)

Updates a record by primary key in the database.

Returns a promise. If you're using Postgres, resolves with the updated record.

static updateMany(Object fields, [Object where])

Updates many records for this model using the new values provided in the fields object. If where is provided, updates only those records conforming to the conditions.

Returns a promise. If you're using Postgres, resolves with an array of the updated records.

static destroy(AnyTime primaryKey)

Deletes a record from the database where the primary key values matches primaryKey.

Returns a promise resolving with undefined.

static destroyMany([Object where, Number limit])

Deletes many records for this model. If where is provided, deletes only those records conforming to the conditions. If limit is provided, will return an amount of items up to the limit.

Returns a promise resolving with undefined.

Record API

isNull()

Returns true if the result returned from the database was null. Returns false if not.

raw(...fields)

Returns a plain object containing only the values that directly correspond to database values. If fields are provided, only those fields will be included in the output.

createReduction(...fields)

Returns a new record object as a clone of the current record but reduced down to only the specified fields.

diff()

For when you have been updating fields on your record object, calling diff will return a plain object containing all the fields that have been updated along with their new values.

toJSON(...fields)

Returns a JSON serialized string of the record. If fields are provided, only those fields will be included in the output.

save()

If the record currently exists in the database, updates the existing record. If the record does not exist in the database, creates a new database entry.

Returns a promise resolving with the record.

destroy()

Deletes the record from the database.

Returns a promise resolving with the record.

reload()

Resets the values of the record to what they were at the time of its initial creation/retrieval. Does not save the changes in the database.

Returns the record.

clone()

Creates a copy of the record object with the primary key field set to null. It will be up to you to populate that field.

Returns a promise resolving with the record.

Database API

getSQModels()

Returns the raw Sequelize models.

getSQConnection()

Returns the raw Sequelize database connection.