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 🙏

© 2026 – Pkg Stats / Ryan Hefner

autoscriptorm

v1.0.7

Published

A Typescript ORM for PostgreSQL

Readme

Autoscript ORM

Description

Autoscript is a lite TypeScript ORM for PostgreSQL. NPM Link: https://www.npmjs.com/package/autoscriptorm

Installation

npm i autoscriptorm

Prerequisite & Rules

  • Every table must have the following fields:
    • id [uuid, generated, not null]
    • is_deleted [boolean, default = false, not null]
    • create_date [timestamp, default = now(), not null]
    • update_date [timestamp]
  • The orm does not keep track of table relationships(Foraign Key).
  • The orm does not hard delete any row it sets is_deleted = false for the deleted row.

Supported MySQL functions

  • CREATE
  • UPDATE
  • DELETE
  • READ
  • WHERE = != <> < > <= >= like in not in is null is not null
  • ORDER BY ASC DESC
  • OFFSET
  • LIMIT
  • INNER JOIN
  • LEFT JOIN
  • RIGHT JOIN
  • VIRTUAL COLUMN

How To Use

For raw sql query you can use query() function

import { query, configureDB } from 'autoscript'

// 1. Set credentials once at startup
configureDB({
    user: 'my_user',
    host: 'localhost',
    database: 'my_db',
    password: 'password123',
    port: 1234
})

async function main() {
    console.log(await query("SELECT * FROM user"))
}

main()

A DTO class represents a table and its columns. Every TableDTO should extend DTO class and implement functions

  • setChildFromObject(obj: any): void : setter for column data from a object
  • setChildFromDBObject(obj: any): void : setter for column data from a db response object
  • getChildAsObject(): Omit<T, keyof DTOType> : getter for column data of the class

Also every TableDTO should implement object

  • childVarToCol:{[key in keyof Omit<T, keyof DTOType>]:string} : mapping of db column to class column variables

For virtual columns computedVarToCol can be used to map column and expression

Here is an example of how to create a DTO:

export type DummyDTOType = DTOType & {
    firstName: string, // Actual Column
    calculatedCol: string //Virtual Column
}

export class DummyDTO extends DTO<DummyDTOType> {

    public firstName: string = "" // Variable for actual Column
    public calculatedCol: string = "" // Variable for virtual Column
    
    public childVarToCol = {
        firstName: "first_name", // Actual column name in the database
        calculatedCol: "calculated_col", // Virtual column name
    }

    public override computedVarToCol = {
        // Virtual column expression
        calculatedCol: "CONCAT(first_name, 'potato')" 
    }

    constructor() {
        // Must pass database table name
        super("dummy")
    }

    // Since `calculatedCol` is a virtual column we won't set it in the setter
    // You can use the helper function (assignIfTypeMatches) to enforce typecheck
    protected setChildFromObject(obj: any): void {
        obj ??= {}
        this.firstName = DTO.assignIfTypeMatches(this.firstName, obj["firstName"], "string") as string
    }

    // We will set both properties because this is used for db serialization
    protected setChildFromDBObject(obj: any): void {
        obj ??= {}
        this.firstName = obj[this.varToCol["firstName"]]
        this.calculatedCol = obj[this.varToCol["calculatedCol"]]
    }

    // Getter for table data
    protected getChildAsObject() {
        return {
            firstName: this.firstName,
            calculatedCol: this.calculatedCol
        }
    }

}

TableDAO class is responsible for crud operation. So, after creating the DTO class it is recommanded to create a DAO class for that table.

Here is an example of how to create a DAO:

import { DummyDTO, type DummyDTOType } from "./Dummy1DTO.ts"
import { DAO } from "autoscript"

export class DummyDAO extends DAO<DummyDTOType, DummyDTO> {
    public constructor() {
        super(Dummy1DTO)
    }
}

Here is an example of how to use the DAO class:

import { configureDB } from 'autoscript'
import DummyDAO from 'DummyDAO.ts'

// 1. Set credentials once at startup
configureDB({
    user: 'my_user',
    host: 'localhost',
    database: 'my_db',
    password: 'password123',
    port: 1234
})

async function main() {

    let dummyDAO = new DummyDAO()

    // Gets all rows
    let dtos = await dummyDAO.execute() 
    if(dtos != null) {
        console.log(dtos.map(e => e.getAsObject()))
    }

    //  [
    //      {
    //          id: 04e45af8-bd52-495a-93e5-3cd09c29ea63,
    //          isDeleted: false,
    //          createDate: '2025-02-28T06:05:20.380Z',
    //          updateDate: '',
    //          firstName: 'Jhon',
    //          calculatedCol: 'Jhonpotato'
    //      },
    //      {
    //          id: 0e9e0d4f-f390-40dc-b675-91a704e58658,
    //          isDeleted: false,
    //          createDate: '2025-02-28T06:05:20.380Z',
    //          updateDate: '',
    //          firstName: 'Doe',
    //          calculatedCol: 'Doepotato'
    //      }
    //  ]

    // Gets rows that satisfies where clause
    dtos = await dummyDAO.where("firstName", "=", "Jhon").execute() 
    if(dtos != null) {
        console.log(dtos.map(e => e.getAsObject()))
    }
    //  [
    //      {
    //          id: 04e45af8-bd52-495a-93e5-3cd09c29ea63,
    //          isDeleted: false,
    //          createDate: '2025-02-28T06:05:20.380Z',
    //          updateDate: '',
    //          firstName: 'Jhon',
    //          calculatedCol: 'Jhonpotato'
    //      }
    //  ]

    // Gets rows that satisfies chained where clause
    dtos = await dummyDAO
        .where("firstName", "=", "Jhon")
        .or()
        .where("firstName", "=", "Doe")
        .execute() 
    if(dtos != null) {
        console.log(dtos.map(e => e.getAsObject()))
    }
    
    //  [
    //      {
    //          id: 04e45af8-bd52-495a-93e5-3cd09c29ea63,
    //          isDeleted: false,
    //          createDate: '2025-02-28T06:05:20.380Z',
    //          updateDate: '',
    //          firstName: 'Jhon',
    //          calculatedCol: 'Jhonpotato'
    //      },
    //      {
    //          id: 0e9e0d4f-f390-40dc-b675-91a704e58658,
    //          isDeleted: false,
    //          createDate: '2025-02-28T06:05:20.380Z',
    //          updateDate: '',
    //          firstName: 'Doe',
    //          calculatedCol: 'Doepotato'
    //      }
    //  ]

}

main()

For join operation JoinDAO class needs to be used. This class can be used to perform innerJoin, leftJoin, rightJoin and where operations. Also virtual columns can be added based on multiple tables. Here is an example:

    import { configureDB } from 'autoscript'

    let result = await new JoinDAO(new Dummy1DAO())
        .innerJoin(new Dummy2DAO(), "table1.name1", "table2.name2")
        .leftJoin(new Dummy3DAO(), "table2.name2", "table3.name3")
        .rightJoin(new Dummy4DAO(), "table4.name4", "table3.name3")
        .addComputedColumn("col1", "CONCAT(table1.name1, table2.name2)")
        .where("table1.name1", "=", "potato")
        .and()
        .where("table2.name2", "=", "tomato")
        .execute()

    if(result!=null) {
        result.map(e => {
            console.log(
                e[0].getAsObject(), //Dummy1DTO
                e[1].getAsObject(), //Dummy2DTO
                e[2].getAsObject(), //Dummy3DTO
                e[3].getAsObject(), //Dummy4DTO
                e[4] //Record<"col1", any>
            )
        })
    }

If in any case execute cannot be called instantly, AnyJoinDAO type will be needed to chain methods later. But this cause typescript from tracking types. Here is an example:

    import { type AnyJoinDAO, configureDB } from 'autoscript'

    let joinDAO: AnyJoinDAO = new JoinDAO(new Dummy1DAO())
        .innerJoin(new Dummy2DAO(), "table1.name1", "table2.name2")
    
    if(/*SomeLogic*/) {
        joinDAO = joinDAO
            .leftJoin(new Dummy3DAO(), "table2.name2", "table3.name3")
            .rightJoin(new Dummy4DAO(), "table4.name4", "table3.name3")        
    }

    result = await joinDAO.execute()

    if(result!=null) {
        result.map(e => {
            console.log(
                (e[0] as Dummy1DTO).getAsObject(),
                (e[1] as Dummy2DTO).getAsObject(),
                (e[2] as Dummy3DTO).getAsObject(),
                (e[3] as Dummy4DTO).getAsObject()
            )
        })
    }