当前位置: 首页 > 软件库 > 数据库相关 > >

mongoose-history-plugin

授权协议 Apache-2.0 License
开发语言 Java
所属分类 数据库相关
软件类型 开源软件
地区 不详
投 递 者 章绪
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

mongoose-history-plugin

Mongoose plugin that saves documents history in JsonPatch format and SemVer format.

Table of Contents

Features

  • Multiple history collections or one shared collection for the schemas
  • Reference an account within the saved history
  • Reference the user that performes the event within the saved history
  • Save history for embedded documents
  • Save history for populated fields
  • Get diffs in JsonPatch format
  • Get documents state for each version
  • Compare two different versions

Install

This is a Node.js module available through the npm registry. Installation is done using the npm install command:

If using mongoose 4.x.x remove will only save if calling model.remove.Mongoose 5.x now applies middleware hooks for remove on both schema and model.

See https://mongoosejs.com/docs/middleware.html

$ npm install mongoose-history-plugin

Use

import mongoose from 'mongoose';
import MongooseHistoryPlugin from 'mongoose-history-plugin';

mongoose.connect('mongodb://localhost/Default');

// Default options
let options = {
  mongoose: mongoose, // A mongoose instance
  userCollection: 'users', // Colletcion to ref when you pass an user id
  userCollectionIdType: false, // Type for user collection ref id, defaults to ObjectId
  accountCollection: 'accounts', // Collection to ref when you pass an account id or the item has an account property
  accountCollectionIdType: false, // Type for account collection ref id, defaults to ObjectId
  userFieldName: 'user', // Name of the property for the user
  accountFieldName: 'account', // Name of the property of the account if any
  timestampFieldName: 'timestamp', // Name of the property of the timestamp
  methodFieldName: 'method', // Name of the property of the method
  collectionIdType: false, // Cast type for _id (support for other binary types like uuid) defaults to ObjectId
  ignore: [], // List of fields to ignore when compare changes
  noDiffSave: false, // If true save event even if there are no changes
  noDiffSaveOnMethods: ['delete'], // If a method is in this list, it saves history even if there is no diff.
  noEventSave: true, // If false save only when __history property is passed
  modelName: '__histories', // Name of the collection for the histories
  embeddedDocument: false, // Is this a sub document
  embeddedModelName: '', // Name of model if used with embedded document

  // If true save only the _id of the populated fields
  // If false save the whole object of the populated fields
  // If false and a populated field property changes it triggers a new history
  // You need to populate the field after a change is made on the original document or it will not catch the differences
  ignorePopulatedFields: true
};

// Add the plugin to the schema with default options
let Schema = mongoose.Schema({ name: 'string', size: 'string' });
Schema.plugin(MongooseHistoryPlugin(options));

// Create a model
let Tank = mongoose.model('tank', Schema);

// Create a document
let small = new Tank({
  size: 'small',
  // History property is optional by default
  __history: {
    event: 'created',
    user: undefined, // An object id of the user that generate the event
    reason: undefined,
    data: undefined, // Additional data to save with the event
    type: undefined, // One of 'patch', 'minor', 'major'. If undefined defaults to 'major'
    method: 'newTank' // Optional and intended for method reference
  }
});
small
  .save()
  .then((small) => {
    small.name = 'Small tank';

    // History property is optional by default
    small.__history = {
      event: 'updated',
      user: undefined,
      reason: undefined,
      data: undefined,
      type: undefined,
      method: 'updateTank'
    };

    return small.save();
  })
  .then((small) => {
    // Create another history version
    small.name = 'Smallest tank';

    // History property is optional by default
    small.__history = {
      event: 'updated',
      user: undefined,
      reason: undefined,
      data: undefined,
      type: undefined,
      method: 'updateTank'
    };

    return small.save();
  })
  .then((small) => {
    // All options are optional
    let query = {
      find: {}, // Must be an object
      select: {}, // Must be an object
      sort: '',
      populate: '',
      limit: 20
    };

    // Get the diff histories in JsonDiffPatch format
    small.getDiffs(query).then(console.log);
    /*
    [ 
      { 
        version: '2.0.0',
        diff: { name: ['Small tank', 'Smallest tank'] },
        event: 'updated',
        method: 'updateTank',
        timestamp: 2019-08-24T12:04:15.253Z },
      { 
        version: '1.0.0',
        diff: { name: [ 'Small tank' ] },
        event: 'updated',
        method: 'updateTank',
        timestamp: 2019-08-24T12:04:15.253Z },
      { 
        version: '0.0.0',
        diff: { _id: [ '5d6127bf3a50db72bc8cbed2' ], size: [ 'small' ] },
        event: 'created',
        method: 'newTank',
        timestamp: 2019-08-24T12:04:15.157Z 
      } 
    ]
    */

    // Get a diff history in JsonDiffPatch format
    small.getDiff('1.0.0').then(console.log);

    /*
    { 
      _id: 5d6127bf3a50db72bc8cbed4,
      version: '1.0.0',
      collectionName: 'tank6',
      collectionId: 5d6127bf3a50db72bc8cbed2,
      diff: { name: [ 'Small tank' ] },
      event: 'updated',
      method: 'updateTank',
      timestamp: 2019-08-24T12:04:15.253Z 
    }
    */

    // Get the versions
    small.getVersions(query).then(console.log);
    /*
    [ 
      {
        version: '2.0.0',
        event: 'updated',
        method: 'updateTank',
        timestamp: expect.any(Date),
        object: { name: 'Smallest tank' }
      },
      { 
        version: '1.0.0',
        event: 'updated',
        method: 'updateTank',
        timestamp: 2019-08-24T12:04:15.253Z,
        object: { name: 'Small tank' } 
      },
      { 
        version: '0.0.0',
        event: 'created',
        method: 'newTank',
        timestamp: 2019-08-24T12:04:15.157Z,
        object: { 
          name: 'Small tank',
          _id: '5d6127bf3a50db72bc8cbed2',
          size: 'small' 
        } 
      } 
    ]
    */

    // Get a version
    small.getVersion('1.0.0').then(console.log);
    /*
    { 
      _id: 5d6127bf3a50db72bc8cbed4,
      version: '1.0.0',
      collectionName: 'tank6',
      collectionId: 5d6127bf3a50db72bc8cbed2,
      event: 'updated',
      method: 'updateTank',
      timestamp: 2019-08-24T12:04:15.253Z,
      object: { 
        _id: '5d6127bf3a50db72bc8cbed2',
        size: 'small',
        name: 'Small tank' 
      } 
    }
    */

    // Compare two versions
    small.compareVersions('0.0.0', '1.0.0').then(console.log);
    /*
    { 
      diff: { name: [ 'Small tank' ] },
      left: { _id: '5d6127bf3a50db72bc8cbed2', size: 'small' },
      right: { 
        _id: '5d6127bf3a50db72bc8cbed2',
        size: 'small',
        name: 'Small tank' 
      } 
    }
    */
  });

small
  .remove()
  .then((small) => {
    small.__history = {
      event: 'removed',
      user: undefined,
      reason: undefined,
      data: undefined,
      type: undefined,
      method: 'delete'
    };

    return small.remove();
  })
  .then((small) => {
    // All options are optional
    let query = {
      find: {}, // Must be an object
      select: {}, // Must be an object
      sort: '',
      populate: '',
      limit: 20
    };

    // Get the diff histories in JsonDiffPatch format
    small.getDiffs(query).then(console.log);

    // Get a diff history in JsonDiffPatch format
    small.getDiff('2.0.0').then(console.log);

    // Get the versions
    small.getVersions(query).then(console.log);

    // Get a version
    small.getVersion('2.0.0').then(console.log);

    // Compare two versions
    // In the case of delete, the diff is empty because the object is not changed.
    small.compareVersions('1.0.0', '2.0.0').then(console.log);
  });

// Add the plugin to many schemas with a single history collection
let plugin = MongooseHistoryPlugin(options);
Schema.plugin(plugin);
AnotherSchema.plugin(plugin);

// Add the plugin with a dedicated history collection for every schema
Schema.plugin(
  MongooseHistoryPlugin(
    Object.assign({}, options, { modelName: 'collectionName_versions' })
  )
);
AnotherSchema.plugin(
  MongooseHistoryPlugin(
    Object.assign({}, options, { modelName: 'anotherCollectionName_versions' })
  )
);

Document Methods

document.getDiffs([findQuery])

Returns an array of all the histories of the document. You can pass a options object that will be passed to a collection find method.

The returned objects within the array have the next shape:

{ 
    version, // The version of the document according to the SemVer format 
    diff, // Changes made in this version diffed against the previous version and according to the JsonPatch format
    event, // The event that create this version if any
    method, // The name of the method that create this version if any
    timestamp // The timestamp in which this version was created
  }

document.getDiff(version)

Returns the version history for this document.

The returned object has the next shape:

{ 
    _id, // ObjectId for this history
    version, // The version of the document according to the SemVer format 
    collectionName, // Name of the collection that belongs to this document
    collectionId, // ObjectId of the document
    diff, // Changes made in this version diffed against the previous version and according to the JsonPatch format
    event, // The event that create this version if any
    method, // The name of the method that create this version if any
    timestamp // The timestamp in which this version was created
  }

document.getVersions([findQuery])

Returns an array of all the versions of the document. You can pass a options object that will be passed to a collection find method.

The returned objects within the array have the next shape:

{ 
  version, // The version of the document according to the SemVer format 
  event, // The event that create this version if any
  method, // The name of the method that create this version if any
  timestamp // The timestamp in which this version was created
  object // Object with the properties changed in this version diffed against the previous version 
}

document.getVersion(version)

Returns the document as it was at the time of this version.

The returned object has the next shape:

{ 
    _id, // ObjectId for this history
    version, // The version of the document according to the SemVer format 
    collectionName, // Name of the collection that belongs to this document
    collectionId, // ObjectId of the document
    event, // The event that create this version if any
    method, // The name of the method that create this version if any
    timestamp, // The timestamp in which this version was created
    object // The complete object as it was at this version
  }

document.compareVersions(versionLeft, versionRight)

Returns the differences between two versions of the document.

The returned object has the next shape:

{ 
  diff, // The differences between the two versions according to the JsonPatch format
  left, // The document as it was at the left version
  right // The document as it was at the right version
}

Tests

npm test

For development use npm dev:test

Contributing

  • Use prettify and eslint to lint your code.
  • Add tests for any new or changed functionality.
  • Update the readme with an example if you add or change any functionality.

Legal

Author: Masquerade Circus. License Apache-2.0

 相关资料
  • Burp Proxy History The Proxy history maintains a full record of all messages that have passed through the Proxy. You can filter and annotate this information to help manage it, and also use the Proxy

  • history 用法 Usage: docker history [OPTIONS] IMAGE Show the history of an image -H, --human=true Print sizes and dates in human readable format --help=false Print usage --no-trunc=false

  • Apart from various contributions, WinSCP is mostly a one-man project. The man is me, Martin Prikryl. The following is a list of project milestones. See also version history. I started the first work o

  • I worked a lot on the Dojo Loader. The normal dojo loader used to use synchronous XMLHttpRequest (XHR) calls. However, the XHR loader couldn't load Dojo modules from other domains because of the same-

  • 封装了对历史记录的操作,实现浏览器页面间前进后退的功能。 标题 内容 类型 动态内容 支持布局 responsive, fixed-height, fill, container, fixed 所需脚本 https://c.mipcdn.com/static/v2/mip-history/mip-history.js 示例 基本用法 <mip-history history="go, -1" cl

  • Shell History Inspired by bamos/zsh-history-analysis. Visualize your usage of Bash/Zsh through a web appthanks to Flask and Highcharts! Duration Length Type Exit code Hourly Daily Over time Markov cha