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

git-like-audit-trail

v1.0.1

Published

Git like audit trail

Downloads

17

Readme

A library that handling audit trail like git. Using Elasticsearch (allow using custom client later) to store audit-trail data.

Installation

yarn add git-like-audit-trail

Screenshot

Demo

Usage:

import auditTrail from "git-like-audit-trail"

// content of below 3 function depends on database type
const databaseAddOneRowFunction = async ({
    data,
    auditTrail = true,
    parentTrail
}) => {
    ...
}

const databaseDeleteOneRowFunction = async ({
    data,
    auditTrail = true,
    parentTrail
}) => {
    ...
}

const databaseUpdateOneRowFunction = async ({
    data,
    changedObj,
    addChangedObj,
    deleteChangedObj,
    revert = true,
    auditTrail = true,
    parentTrail
}) => {
    ...
}

const _auditTrail = new auditTrail({
    DBType: "elasticsearch", // default
    host: "http://localhost:9200", //default
    ESinfo: { //default
        indexName: "audit-trail",
    },
    databaseAddOneRowFunction,
    databaseDeleteOneRowFunction,
    databaseUpdateOneRowFunction,
    // databaseCustomActionFunction, // custom action function
})

Function available:

Function usage

await need to execute in async function

createData:

const trail = await _auditTrail.createData({
    categoryId: "testTable", // target table name
    userId: "awcjack", // user id
    dataId: "1", // changes target data id
    name: "1", // extra info
    before: {}, // data before change
    after: {
        id: "1",
        name: "test1"
    }, // data after change
    parent, // parent commit id (for large trail that change multiple data)
    action: "CREATE", // "CREATE" || "UPDATE" || "DELETE" (allow extra action type but have to handled in databaseCustomActionFunction)
    ignore: [], // ignore in diff
    ...otherArgs // other args that want to log into this audit trail
})
console.log(trail)

/*
{
    categoryId: "testTable",
    userId: "awcjack",
    dataId: "1",
    name: "1",
    parent,
    action: "CREATE",
    ...otherArgs,
    change: "{\"added\":{\"id\":{\"after\":\"1\"},\"name\":{\"after\":\"test\"}},\"deleted\":{},\"updated\":{}}",
    time: 1613749903586,
    parentTrail: "04353794-da94-468d-abd9-1080426007a4",
    commitHash: "834cb604b1ce6ae0eb77b8a52aab60d913e4ede2
}
// commitHash work as index
*/

appendCommitMap:

const { commitHash } = trail // trail object from createData
const commitMap = _auditTrail.appendCommitMap({
    currentCommitMap: "{}", // existing commit map ("{}" for init)
    currentCommitHash: "", // current commit hash in category
    newCommitHash: commitHash //new commit hash from createData
})
console.log(commitMap)
/*
"{^0_834cb604b1ce6ae0eb77b8a52aab60d913e4ede2:834cb604b1ce6ae0eb77b8a52aab60d913e4ede2}"
// string type for storing into db
*/

query:

const tree = _auditTrail.query({
    commitHashMap: "{}", // existing commit map
    commitHash: "", // query from hash (user current commit)
    before: 5, // include 5 commit (level) before
    after: 5,// include 5 commit (level) after
    onlyCurrentBranch: false, //only reveal current branch
    getCommitInfo: false // query commit info
})
console.log(tree)
/*
[{"834cb604b1ce6ae0eb77b8a52aab60d913e4ede2":{"3e4c25f224e435372b9c1f92bc050fd3a9840d91":{},"34fc46d4e871605dcf1f3519f5f4ee0124dac4ed":{}}}]
// removed commit info prevent too long
*/

queryD3:

const tree = _auditTrail.queryD3({
    commitHashMap: "{}", // existing commit map
    commitHash: "", // query from hash (user current commit)
    before: 5, // include 5 commit (level) before
    after: 5,// include 5 commit (level) after
    onlyCurrentBranch: false, //only reveal current branch
    getCommitInfo: false, // query commit info
    ignore: [], // ignore array of commit info object (delete from object)
    format, // commit info format, "test" (commit info parse to key: value pair and concat with \n), "object" (commit info)
})
console.log(tree)
/*
[{"children":[{"children":{"name":"da498b3a30a06db903cc25cfac07517e3e08216c", "info": {...}, "currentCommit": true})],"name":"2a599a5d724d659b8ebb6565a626de40d52db10a","info":{"categoryId":"testTable","userId":"awcjack","dataId":"1","name":"test","action":"CREATE","change":"{\"added\":{\"id\":{\"after\":\"1\"},\"name\":{\"after\":\"test\"}},\"deleted\":{},\"updated\":{}}","time":1614433429834,"parentTrail":"b343ac62-7807-4d68-8518-f4d18e59e781","commitHash":"2a599a5d724d659b8ebb6565a626de40d52db10a"}}]
*/

queryByCommitHash:

const commit = _auditTrail.queryByCommitHash({
    commitHash: "b11b50b366f8477e8e9f5dea5344fc42eac63b06",
})
console.log(commit)
/*
{
    "categoryId": "testTable",
    "userId": "awcjack",
    "dataId": "3",
    "name": "test3",
    "action": "CREATE",
    "ignore": [],
    "change": "{\"added\":{\"id\":{\"after\":\"3\"},\"name\":{\"after\":\"test3\"}},\"deleted\":{},\"updated\":{}}",
    "time": 1613815197218,
    "parentTrail": "9aaf9a1c-7ccc-453a-9d3f-bd70a5e49c58",
    "commitHash": "b11b50b366f8477e8e9f5dea5344fc42eac63b06"
}
*/

batchQueryByCommitHash:

const commits = _auditTrail.batchQueryByCommitHash({
    commitHashArray: ["b11b50b366f8477e8e9f5dea5344fc42eac63b06"],
})
console.log(commits)
/*
[{
    "categoryId": "testTable",
    "userId": "awcjack",
    "dataId": "3",
    "name": "test3",
    "action": "CREATE",
    "ignore": [],
    "change": "{\"added\":{\"id\":{\"after\":\"3\"},\"name\":{\"after\":\"test3\"}},\"deleted\":{},\"updated\":{}}",
    "time": 1613815197218,
    "parentTrail": "9aaf9a1c-7ccc-453a-9d3f-bd70a5e49c58",
    "commitHash": "b11b50b366f8477e8e9f5dea5344fc42eac63b06"
}]
*/

revertCommit:

const result = await _auditTrail.revertCommit({
    commitHash: req.params.hash,
})
console.log(result)
/*
{
    "added": {
        "error": false,
        "content": {
            "id": "1",
            "name": "test"
        },
        "commitHash": "834cb604b1ce6ae0eb77b8a52aab60d913e4ede2"
    }
}
*/

cherryPick:

const result = await _auditTrail.cherryPick({
    commitHash: req.params.hash,
})
console.log(result)
/*
{
    "added": {
        "error": false,
        "content": {
            "id": "1",
            "name": "test"
        },
        "commitHash": "834cb604b1ce6ae0eb77b8a52aab60d913e4ede2"
    }
}
*/

checkout:

const result = await _auditTrail.checkout({
    commitHashMap: commitHashMap.commitMap,
    currentCommit: currentCommit.commitHash,
    commitHash: req.params.hash,
})
console.log(result)
/*
[{"deleted":{"error":false,"content":{"id":"23","name":"test23"}}}]
*/

To do

  • verify tree structure & logic
  • ~~handle checkout~~
  • handle merge (may or may not implement)
  • custom client
  • ~~provide frontend demo~~
  • handle batch CUD in demo