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

sequelize-history

v1.4.0

Published

Creates a revision history for instances of a given Sequelize model.

Downloads

327

Readme

100% test coverage

sequelize-history

Creates a revision history for instances of a given Sequelize model.

This module will setup automatic revision tracking for any Sequelize model. This is effectively a re-write of sequelize-temporal, which deserves any and all due credit. More specifically...

  • re-written in ES6-ish code
  • addition of a couple of factory methods to make instantiation simpler (this is especially true if you're going to track revisions on all of your models)
  • optionally tracks revision author
  • a few new instantiation options
  • up-to-date dependencies
  • tests re-written in tape
  • linted against xo
  • less lodash magic

Installation

Install via npm:

$ npm i sequelize-history --save

Usage

Create your Sequelize instance and models per usual.

const Sequelize = require('sequelize');
const sequelizeHistory = require('sequelize-history');

// Create a sequelize instance
const sequelize = new Sequelize('', '', '', {
  dialect: 'sqlite',
  operatorsAliases: false,
  storage: path.join(__dirname, 'test.sqlite')
});

// Create the model class to be tracked
const Model = sequelize.define('Model', {name: Sequelize.TEXT});

By default, the module exports a factory method to avoid having to deal with the constructor. All options are passed transparently as they would be to the constructor if called directly. To begin tracking a model's revisions:

// If you want a reference to the tracking model...
const ModelHistory = sequelizeHistory(Model, sequelize);

// Otherwise...
sequelizeHistory(Model, sequelize);

// You're done. 
// A record of all changes to instances of 
// `Model` will be recorded in the modelHistory table via the
// `ModelHistory` collection.

If you need to access the constructor for some reason, it is exported as SequelizeHistory.

// Require the constructor instead of the factory
const sequelizeHistory = require('sequelize-history').SequelizeHistory;

// Create an instance
const history = new SequelizeHistory(Model, sequelize);

// If you want a reference to the tracking model...
const modelHistory = history.modelHistory;

Finally, if you want to track all of your models, an all method is exported. Just pass it your sequelize instance and you're done.

const trackAll = require('sequelize-history').all;

trackAll(sequelize);

Tracking revision author

If you pass an authorFieldName option, the tracking model gets a field of the same name added to its table. It also results in your original model getting a new setRevisionAuthor static method.

Use this method by passing in any appropriate value before updating your original model instances, and the passed value will be written to the authorFieldName column of the tracking table. The value is reset immediately after the next update is written to the history model.

This functionality is available to both single instance updates and static bulk updates.

const Sequelize = require('sequelize');
const sequelizeHistory = require('sequelize-history');

// Create a sequelize instance
const sequelize = new Sequelize('', '', '', {
  dialect: 'sqlite',
  operatorsAliases: false,
  storage: path.join(__dirname, 'test.sqlite')
});

// Create the model class to be tracked
const Model = sequelize.define('Model', {name: Sequelize.TEXT});

// Create some instances of the model
Model
  .create({name: 'test-1'})
  .then(() => Model.create({name: 'test-2'}))
  .then(() => {
    // Now we update our instances
    // First, set the revision author
    Model.setRevisingAuthor(100);
    // Then update the instances
    // Both bulk updates and instance updates are supported
    return Model.update({name: 'same'}, {where: {}});
  })
  // Get all of our recent revisions
  .then(() => sequelize.models.ModelHistory.findAll({where: {name: 'same'}}))
  .then(revisions => {
    revisions.forEach(revision => {
      // Should output 100 for each returned row
      console.log(revision.authorId);
    });
  })
  .catch(err => console.error.bind(console));

There are more examples in the tests.

Options

The constructor and factory methods accept the following instantiation object properties:

  • authorFieldName string|null - string to indicate a field name to store author of the revisions, or null to disable
  • modelSuffix string - string to append to tracked model's name when creating name of tracking model
  • excludedAttributes array - collection of model attributes to be excluded when creating history model from the target model
  • excludedAttributeProperties array - collection of attribute properties to ignore when duplicating the target model's attributes

NOTE - if authorFieldName is set, hasMany and belongsTo relationships will be created between the history model and the target model. This is to ensure that constraints are not enforced in creating the associations.

Defaults

SequelizeHistory.DEFAULTS = {
    // String to indicate a field name to use to store the
    // author of the revisions to the model, or null if you
    // don't want to track revision authors
    authorFieldName: null,
    // String to append to tracked model's name in creating
    // name of model's history model
    modelSuffix: 'History',
    // Array of attributes to be ignored and excluded when
    // recording a change to the target model
    excludedAttributes: [],
    // Array of attribute properties to ignore when duplicating
    // the target model's attributes - this is mostly to prevent
    // the use of constraints that may be in place on the target
    excludedAttributeProperties: [
        'Model',
        'unique',
        'primaryKey',
        'references',
        'onUpdate',
        'onDelete',
        'autoIncrement',
        'set',
        'get',
        '_modelAttribute'
    ]
};

Tests and coverage

Written with tape and Istanbul respectively.

To run the tests:

$ npm test

To generate a coverage report:

$ npm run coverage

To build JSDoc docs from in-line documentation:

$ npm run docs && open docs/index.html