{"_id":"@ameenhub/mongoose-versioned","name":"@ameenhub/mongoose-versioned","dist-tags":{"latest":"1.3.0"},"versions":{"1.3.0":{"name":"@ameenhub/mongoose-versioned","version":"1.3.0","description":"Versioning module for MongoDB based in mongoose. It uses a main collection for the current data and a shadow collection for the old versions.","main":"source/versioning.js","repository":{"type":"git","url":"git+https://github.com/pier4all/mongoose-versioned.git"},"bugs":{"url":"https://github.com/pier4all/mongoose-versioned/issues"},"homepage":"https://github.com/pier4all/mongoose-versioned#readme","keywords":["mongoose","mongodb","versioning"],"scripts":{"test":"tap test/*.test.js","preinstall":"npm install --package-lock-only --ignore-scripts && npx npm-force-resolutions"},"author":{"name":"Lucía de Espona Pernas","url":"https://github.com/espona"},"contributors":[{"name":"Lucía de Espona Pernas","url":"https://github.com/espona"},{"name":"Jean-Claude Schmidig","url":"https://github.com/jcschmidig"}],"license":"MIT","dependencies":{"immutable":"^4.0.0-rc.12","mongoose":"^6.2.2"},"devDependencies":{"chalk":"^4.1.1","mongodb-memory-server":"^8.0.4","tap":"^16.3.0"},"resolutions":{"minimist":"^1.2.6"},"gitHead":"5f911ffa084b3f73fec8e25e868b5ce61241eb36","_id":"@ameenhub/mongoose-versioned@1.3.0","_nodeVersion":"20.1.0","_npmVersion":"9.6.4","dist":{"integrity":"sha512-9OiklGxcsy7wHZv6U30k7UOgMBjte05XYChAEM9JZLQXkIEQQGaVbthueVdZNyECBZHXiNhovfGYB7AS/ach6w==","shasum":"2f64ce689ff637261bc64c902494949969d9b467","tarball":"https://registry.npmjs.org/@ameenhub/mongoose-versioned/-/mongoose-versioned-1.3.0.tgz","fileCount":12,"unpackedSize":66480,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGmL+PBNY6DEQXGaotQSzQE6/nztLsjn9QEQ6ul2IdS5AiEAkc/b8xX8x0qeykTn7iUOPnXqwbvji3KJrch0K0Bf6iQ="}]},"_npmUser":{"name":"ameenhub","email":"alameen.h@hubspire.com"},"directories":{},"maintainers":[{"name":"ameenhub","email":"alameen.h@hubspire.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mongoose-versioned_1.3.0_1689659823924_0.48676128850230227"},"_hasShrinkwrap":false}},"time":{"created":"2023-07-18T05:57:03.823Z","1.3.0":"2023-07-18T05:57:04.116Z","modified":"2023-07-18T05:57:04.366Z"},"maintainers":[{"name":"ameenhub","email":"alameen.h@hubspire.com"}],"description":"Versioning module for MongoDB based in mongoose. It uses a main collection for the current data and a shadow collection for the old versions.","homepage":"https://github.com/pier4all/mongoose-versioned#readme","keywords":["mongoose","mongodb","versioning"],"repository":{"type":"git","url":"git+https://github.com/pier4all/mongoose-versioned.git"},"contributors":[{"name":"Lucía de Espona Pernas","url":"https://github.com/espona"},{"name":"Jean-Claude Schmidig","url":"https://github.com/jcschmidig"}],"author":{"name":"Lucía de Espona Pernas","url":"https://github.com/espona"},"bugs":{"url":"https://github.com/pier4all/mongoose-versioned/issues"},"license":"MIT","readme":"# Versioning Module MongoDB\nModule for versioning in MongoDB, inspired by Vermongo (https://www.npmjs.com/package/mongoose-vermongo, https://github.com/codela/mongoose-vermongo and https://github.com/thiloplanz/v7files/wiki/Vermongo).\n\nIt includes support for transactions to avoid inconsistency when performing an update or deletion since this operations involve the main and the shadow collection (see instructions below).\n\nThis module allows to keep the change history of every document and the deleted documents. The idea is to have a \"main collection\" storing the current document versions and a different collection called \"shadow collection\" to keep all the past versions and deleted documents.\n\nSee Basic Usage.\n\n### Use\nIn order to use the package just install it as a dependency\n```\nnpm install mongoose-versioned\n```\n\n### Basic usage\nThis package requires mongoose and it is added as a plugin to each individual model that will be versioned. Get familiar with mongoose before using this package (https://mongoosejs.com/docs/index.html).\n\n```javascript\n// import versioning and mongoose related dependencies\nconst versioning = require('mongoose-versioned')\nconst constants = require('mongoose-versioned/source/constants')\n\nconst mongoose = require('mongoose')\nmongoose.Promise = require('bluebird')\nlet Schema = mongoose.Schema\n\n// connect to the database following mongoose instructions, for example:\nlet mongodb_uri = 'mongodb://localhost/test'\n\nconst versionItems = async(mongodb_uri) => {\n  try {\n      await mongoose.connect(mongodb_uri, { useUnifiedTopology: true, useNewUrlParser: true, useFindAndModify: false })\n      console.log(\"Database.connect: DB connected \")\n  } catch (err) {\n      console.error(`Database.connect: MongoDB connection error. Please make sure MongoDB is running:` + err.message)\n      throw new Error(err)\n  }\n\n  const db = mongoose.connection\n\n  // create the model\n  let itemSchema = new Schema({\n    code: { type: Number, required: true, unique: true },\n    name: { type: String, required: true, unique: false }\n  })\n\n  // add the versioning plugin to the schema and specify\n  // the name of the shadow collection\n  const name = 'item'\n  itemSchema.plugin(versioning, {collection: name + \"s.versioning\", mongoose})\n\n  // instantiate the model\n  let Item = mongoose.model(name, itemSchema)\n  // at this point a collection named 'tests'\n\n  // add a new document\n  const newItem = {\n    code: 1,\n    name: \"first item\"\n  }\n\n  let savedItem = await new Item(newItem).save()\n  console.log(`saved item with id: ${savedItem._id}, version: ${savedItem._version}`)\n\n  let id = savedItem._id\n\n  // update document info\n  savedItem.name = \"modified item\"\n\n  // add edition information\n  savedItem[constants.EDITOR] = \"editing user\"\n  \n  // perform the update\n  let updatedItem = await savedItem.save()\n  console.log(`updated item with name: ${updatedItem.name}, version: ${updatedItem._version}`)\n\n  // find current version\n  let foundCurrent = await Item.findVersion(id, 2, Item)\n  console.log(`found current version ${foundCurrent._version}, name = ${foundCurrent.name}`)\n\n  // find old version\n  let foundOld = await Item.findVersion(id, 1, Item)\n  console.log(`found current version ${foundOld._version}, name = ${foundOld.name}`)\n\n  await db.close()\n}\n\nversionItems(mongodb_uri)\n\n```\n\n### Using transactions\nTransactions\n\nTransactions can be used to ensure the database remains in a consistent state even if the operation fails. Update and delete operations involve changes in both main and shadow collections and therefore need to be wrapped in a transaction to ensure serialization.\n\nThe transaction should be stated before calling the update/delete operation and in addition the session should be stored in a reserved \"_session\" inside the document and passed as an option to save/delete method.\n\n```javascript\nconst versioning = require('mongoose-versioned')\nconst constants = require('mongoose-versioned/source/constants')\n\nconst mongoose = require('mongoose')\nmongoose.Promise = require('bluebird')\n\n[...]\n\ntry {\n  // start transaction\n  session = await mongoose.startSession()\n  session.startTransaction()\n\n  // store session in the document\n  document[constants.SESSION] = session\n\n  // save sending the session as option\n  await document.save({session})\n\n  // commit transaction\n  await session.commitTransaction()\n  session.endSession()\n\n} catch(error) {\n  if (session) session.endSession()\n  const message = `Error updating document ${id} in the collection ${collection}.`\n  processError(res, error, message)\n}\n\n```\n","readmeFilename":"README.md"}