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

orm-dao-simplified

v1.0.4

Published

A lightweight, TypeScript-first Data Access Object (DAO) library for MySQL, offering type-safe CRUD operations, declarative entity modeling with decorators, robust validation, and native transaction support. Designed to provide ORM-like structure and safe

Readme

📦 orm-dao-simplified

A lightweight and flexible Data Access Object (DAO) library built for TypeScript and MySQL. It provides a structured, type-safe layer over raw SQL, offering the safety and convenience of an ORM without the heavy abstraction.

✨ Features

  • Type-Safe Queries: Utilize TypeScript generics to ensure query clauses, fields, and joins are type-checked at compile time.
  • Declarative Entity Modeling: Define database fields and conversions using decorators (e.g., @Type(EntityPropertyType.JSON)).
  • Robust Validation: Enforce data integrity immediately upon entity instantiation using the built-in validate hook.
  • Native Transaction Support: Easily wrap multiple DAO operations in atomic transactions via the runInTransaction helper.
  • Advanced CRUD: Includes powerful methods like upsertAll (on duplicate key update) for efficient data synchronization.
  • Model Generation Script: A utility to automatically generate Entity and DAO boilerplate from your existing MySQL schema.

💾 Installation

npm install orm-dao-simplified mysql2 reflect-metadata

Note: Ensure you have typescript installed as a dev dependency and that experimentalDecorators and emitDecoratorMetadata are set to true in your tsconfig.json.

🏗️ Core Concepts

The library is based on two core classes, both exposed directly from the package:

| Component | Role | | :--- | :--- | | Entity | The abstract base class for all data models. Handles data lifecycle (validation, serialization/deserialization) and automatic type conversions via decorators. | | GenericDAO<T> | The abstract class that encapsulates all database operations. Manages query construction and executes SQL via a mysql2/promise connection. |

1. Unified Imports

Thanks to the updated structure, all core components and utilities are available from a single import:

import { 
    Entity, GenericDAO, 
    EntityPropertyType, Type, 
    Where, Join, 
    runInTransaction 
} from 'orm-dao-simplified';

2. Defining Your Entity (User.model.ts)

Extend the base Entity class and use decorators for type conversions.

import { 
    Entity, IUpdateEntity, EntityPropertyType, Type, EntityValidationError 
} from 'orm-dao-simplified';

export interface IUserEntity extends IUpdateEntity {
    username: string;
    // ... other properties
}

export default class User extends Entity implements IUserEntity {
    static EntityName = "users"; 

    id!: number;
    username!: string;
    
    // Automatic DESERIALIZATION and SERIALIZATION handled by the library
    @Type(EntityPropertyType.JSON)
    settings!: { theme: string, notifications: boolean }; 

    @Type(EntityPropertyType.DATE)
    createdAt!: Date;

    constructor(attributes: any) {
        super(attributes);
    }

    /**
     * Required: Validation hook executed in the constructor.
     * @returns true if valid, or a string error message if invalid.
     * @throws EntityValidationError if an error message is returned.
     */
    protected validate(): true | string {
        if (!this.username || this.username.length < 3) {
            return "Username must be at least 3 characters long.";
        }
        return true; 
    }
    
    // REQUIRED: Implements the abstract sanitize method
    sanitize(): IUserEntity {
        const { _joins, id, username, settings, createdAt } = this;
        return { id, username, settings, createdAt };
    }
    
    // REQUIRED: Implements the abstract update method
    update(attributes: IUpdateEntity): void {
        this.set(attributes);
    }
}

3. Defining Your DAO (UserDAO.ts)

Extend GenericDAO and inject the connection source (Pool or active Transaction Connection).

import { GenericDAO } from 'orm-dao-simplified';
import { Pool, Connection } from 'mysql2/promise';
import User from './User.model'; // Local import for the generated model

export default class UserDAO extends GenericDAO<User> {
    constructor(connection: Pool | Connection) {
        // Pass the Entity class (for table name) and its constructor (for hydration)
        super(User, User, connection); 
    }
}

🚀 Advanced Functionality

1. Atomic Transactions

Use runInTransaction to ensure atomicity.

import { runInTransaction } from 'orm-dao-simplified';
import { createPool } from 'mysql2/promise';
import UserDAO from './UserDAO'; 

const pool = createPool({ /* ... config */ });

async function transferFunds(senderId: number, receiverId: number, amount: number) {
    
    return runInTransaction(pool, async (txConnection) => {
        // IMPORTANT: Use the transaction connection for all DAOs inside the block
        const txUserDAO = new UserDAO(txConnection); 
        
        // ... Perform update operations (e.g., withdraw and deposit)
        // If an error is thrown here, the transaction is automatically rolled back.
    });
}

2. Model Generation

Use the provided script to quickly bootstrap your entity and DAO files from an existing database.

# Run from your project root (after npm run build)

# Usage: node generate:models <host> <user> [password] <database> [port]

node generate:models localhost root mypassword mydatabase