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

tsbean-orm

v3.0.0

Published

Typescript bean-like object relational mapping framework.

Downloads

224

Readme

Typescript bean-like ORM

npm version

This is a generic object relational mapping framework for Typescript and NodeJS.

  • Easy to use
  • No dependencies
  • Pluggable drivers
  • Promise-based

Installation

To install into your project using npm, type:

npm install --save tsbean-orm

Data sources and drivers

To connect with a data source, you need a driver. Here is a list of available ones:

If you want to write your own driver, check this template: Data Source Driver Template

With the driver you can create a data source for your application.

  • You can create one or multiple based on your needs
  • Each data source must have an unique name
  • If you are only using a single data source, you can use DataSource.DEFAULT as the name for it.

To set a data source use DataSource.set

Example:

import { DataSourceDriver, DataSource } from "tsbean-orm";
import { MyDriver } from "tsbean-orm-driver-mydriver"

const mySource = MyDriver.createDataSource({} /* Options */);

DataSource.set(DataSource.DEFAULT, mySource);

Data Models

The recommended architecture when using this project is to create a models folder with a class file for each entity of your relational data model.

Check out this tool to automatically generate the model classes: https://agustinsrg.github.io/tsbean-codegen/

The data models must extend DataModel

import { DataModel } from "tsbean-orm";

export class MyModel extends DataModel {

}

Data models must have a constructor receiving the data from the data source. The constructor must:

  • Call DataModel class super constructor, wih the name of the data source, the table and the primary key.
  • Set the properties of the model from the data.
  • Call this.init() for the orm to start checking for changes.

Example:

import { DataModel, TypedRow, DataSource, enforceType } from "tsbean-orm";

export class Person extends DataModel {

    public name: string;
    public age: number;

    constructor(data: TypedRow<Person>) {
        // First, we call DataModel constructor 
        super(
            DataSource.DEFAULT, // The data source
            "persons", // The table or collection name
            "name" // The primary key. Leave blank if no primary key
        );

        // Second, we set the class properties
        // The recommended way is to set one by one to prevent prototype pollution
        // You can also enforce the types if you do not trust the data source
        // In that case you can use the enforceType utility function

        this.name = enforceType(data.name, "string");
        this.age = enforceType(data.age, "int");

        // Finally, we must call init()
        this.init();
    }
}

Finders

Finders are used to execute queries over multiple documents, based on a data model.

To create one, you have to specify the name of the data source, the table, the primary key (if any) and a callback to instantiate your custom data model.

import { DataModel, TypedRow, DataSource, DataFinder, enforceType } from "tsbean-orm";

export class Person extends DataModel {

    public static finder = new DataFinder<Person, string>(
            DataSource.DEFAULT, // The data source
            "persons", // The table or collection name
            "name" // The primary key. Leave blank if no primary key
            (data: TypedRow<Person>) => {
                return new Person(data);
            },
    );

    public name: string;
    public age: number;

    constructor(data: TypedRow<Person>) {
        // First, we call DataModel constructor 
        super(
            DataSource.DEFAULT, // The data source
            "persons", // The table or collection name
            "name" // The primary key. Leave blank if no primary key
        );

        // Second, we set the class properties
        // The recommended way is to set one by one to prevent prototype pollution
        // You can also enforce the types if you do not trust the data source
        // In that case you can use the enforceType utility function

        this.name = enforceType(data.name, "string");
        this.age = enforceType(data.age, "int");

        // Finally, we must call init()
        this.init();
    }
}

Main finder classes:

  • DataFinder: The finder for a data model. It's a generic with 2 parameters: The data model class and the primary key type (optional).
  • DataFilter: Allows setting filters for the data
  • OrderBy: Sets the order of the received data
  • SelectOptions: Sets options like the max number of rows or the projection.

You can use the finder to find instances of your data model, or apply updates or deletions to many of them.

Here are some examples using the Person model:

import { DataModel, TypedRow, DataSource, DataFinder, DataFilter, OrderBy, SelectOptions } from "tsbean-orm";

async function main() {
    // Find person with name "person1"
    const person1 = await Person.finder.findByKey("person1");

    // Find persons with age = 20
    const personsAge20 = await Person.finder.find(DataFilter.equals("age", 20));

    // Find persons with age >= 20 && age <= 50, ordered by age, limit of 10
    const personsAge20To50 = await Person.finder.find(
        DataFilter.and(
            DataFilter.greaterOrEquals("age", 20),
            DataFilter.lessOrEquals("age", 50)
        ),
        OrderBy.asc("age"),
        SelectOptions.configure().setMaxRows(10),
    );

    // Update persons with age = 20, set age = 21
    const rowsAffected = await Person.finder.update({ age: 21 }, DataFilter.equals("age", 20));

    // Delete persons with age = 30
    const rowsAffected2 = await Person.finder.delete(DataFilter.equals("age", 30));
}

Insert

In order to insert a new instance of you data model into the data source, you have to create it using the new keyword and then call the insert method:

import { DataModel, TypedRow, DataSource, DataFinder, DataFilter, OrderBy, SelectOptions } from "tsbean-orm";

async function main() {
    const person = new Person({
        name: "example",
        age: 40,
    });

    try {
        await person.insert();
    } catch (ex) {
        // The most common error may be duplicated primary key
    }
}

Update

Once you find a model using a finder object, you can update its properties and then save it, to apply the changes to the data source. In order to do that, use the save method.

import { DataModel, TypedRow, DataSource, DataFinder, DataFilter, OrderBy, SelectOptions } from "tsbean-orm";

async function main() {
    const person = await Person.finder.findByKey("example");

    if (person) {
        person.age = 60;
        await person.save();
    }
}

Delete

Once you find a model using a finder object, you can also delete it, using the delete method.

import { DataModel, TypedRow, DataSource, DataFinder, DataFilter, OrderBy, SelectOptions } from "tsbean-orm";

async function main() {
    const person = await Person.finder.findByKey("example");

    if (person) {
        await person.delete();
    }
}

Serialize

Since the DataModel objects are circular structures, you cannot simply serialize them with JSON.stringify. Instead, DataModel class offers 2 method to serialize it:

  • toObject: Turns the DataModel instance into a plain key-values object.
  • ToJSON: Turns the DataModel instance into a JSON string
import { DataModel, TypedRow, DataSource, DataFinder, DataFilter, OrderBy, SelectOptions } from "tsbean-orm";

async function main() {
    const person = await Person.finder.findByKey("example");

    if (person) {
        console.log("Person Found: " + person.toJSON());
    }

    const people = await Person.finder.find(DataFilter.any());

    console.log("People Found: " + JSON.stringify(people.map(p => p.toObject())));
}