Coder Social home page Coder Social logo

typeorm-versions's Introduction

TypeORM-Versions

A paper_trail inspired versioning plugin for TypeORM to track changes in entities.

Usage

Define your entity and annotate it with the @VersionedEntity() decorator.

import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
import { VersionedEntity } from "typeorm-versions";

@Entity()
@VersionedEntity()
class Post {

    @PrimaryGeneratedColumn()
    id!: number;

    @Column()    
    title!: string;

    @Column()
    content!: string;

}

At any other point in your code use it like

// Repository pattern
const postRepository = connection.getRepository(Post);

// Store a post
let post = new Post();
post.title = "hello";
post.content = "World";
post = await postRepository.save(post);

// Change the post and store the change
post.content = "there!";
post = await postRepository.save(post);

// Retrieve all stored versions for this post
const versionRepository = connection.getCustomRepository(VersionRepository);
const versions = await versionRepository.allForEntity(post);
console.log(versions);

// returns
[
  Version {
    id: 2,
    itemType: 'Post',
    itemId: '1',
    event: 'UPDATE',
    owner: 'system',
    object: { title: 'hello', content: 'there!', id: 1 },
    timestamp: 2021-03-18T16:56:49.996Z
  },
  Version {
    id: 1,
    itemType: 'Post',
    itemId: '1',
    event: 'INSERT',
    owner: 'system',
    object: { title: 'hello', content: 'World', id: 1 },
    timestamp: 2021-03-18T16:56:49.986Z
  }
]

// To recover a previous version
const previousVersion = await versionRepository.previousForEntity(post);

post = previousVersion!.getObject<Post>();
await postRepository.save(post);

// All navigaton options
const versionRepository = connection.getCustomRepository(VersionRepository);
const previousVersion = await versionRepository.previousForEntity(post);
const latestVersion = await versionRepository.latestForEntity(post)
const previousPost = await versionRepository.previousObjectForEntity(post); // Get the entity object directly instead of the version
const latestPost = await versionRepository.latestObjectForEntity(post);

TypeORM-Versions also works with the active record pattern

import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
import { VersionedEntity, VersionedBaseEntity } from "typeorm-versions";

// Instead of TypeORM's BaseEntity, use VersionedBaseEntity
@Entity()
@VersionedEntity()
class Post extends VersionedBaseEntity{

    @PrimaryGeneratedColumn()
    id!: number;

    @Column()    
    title!: string;

    @Column()
    content!: string;

}

// Which provides helper methods like...
let post = Post.find(1);
post.versions().list(); // List all all versions
post.versions().previous();
post.versions().latest();
post.versions().previousObject(); // Get the object instead of version
post.versions().latestObject();

Installation

npm install typeorm-versions

You need to register TypeORM-Vsersions' own Version entity and VersionSubscriber within your connection.

In your ormconfig.json add

{
    ...
    "entities": [
        "entity/*.js",
        "./node_modules/typeorm-version/dist/entity/Version.js" 
    ],
    "subscribers": [
        "subscriber/*.js",
        "./node_modules/typeorm-version/dist/subscribers/VersionSubscriber.js"
    ],
    ...
}

Alternatively, TypeORM-Versions provides a convenience function versionsConfig, which can be used in code and injects the settings:

import { ConnectionOptions } from 'typeorm';
import { versionsConfig } from 'typeorm-versions';

const connectionOptions: ConnectionOptions = {
    ...
}

connectionOptions = versionsConfig(connctionOptions);

Lastly, create an empty migration in your migration directory and make sure it looks like:

class Version1000000000001 extends AddVersionMigration { tableName = "Version1000000000001" }
// 1000000000001 should be a timestamp that fits your migration order

Future To-Dos

  • More tests
  • More / improve docs
  • More navigation and recovery features
  • More examples

typeorm-versions's People

Contributors

dependabot[bot] avatar frane avatar oktapodia avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.