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

@andrewcaires/sequelize

v3.3.0

Published

Decorators for sequelize

Readme

@andrewcaires/sequelize

TypeScript decorators and utilities for defining Sequelize v6 models directly on classes.

Use this package to declare columns, associations, hooks, scopes, and indexes without calling Model.init() or the native association methods manually. It also supports multiple database connections, model replication, lightweight column synchronization, and allowlisted where parsing.

Installation

npm install @andrewcaires/sequelize

Install the driver for the dialect used by your application. For MariaDB:

npm install mariadb

Enable legacy decorators and decorator metadata in tsconfig.json:

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  }
}

The package exposes a single public entrypoint, @andrewcaires/sequelize, with ESM, CommonJS, and TypeScript declaration targets.

Usage

import {
  Column,
  Database,
  DefaultValue,
  Model,
  ModelName,
  Optional,
  Sequelize,
} from "@andrewcaires/sequelize";

enum UserStatus {
  Active = "active",
  Disabled = "disabled",
}

const sequelize = new Sequelize({
  uri: "mariadb://root:[email protected]:3306/example",
});

@Database(sequelize)
@ModelName("user")
class UserModel extends Model<UserModel> {
  @Column.Id(7)
  declare readonly id: Optional<string>;

  @Column.String()
  declare name: string;

  @Column.Enum(UserStatus)
  @DefaultValue(UserStatus.Active)
  declare status: UserStatus;

  @Column.CreatedAt()
  declare readonly createdAt: Optional<Date>;

  @Column.UpdatedAt()
  declare readonly updatedAt: Optional<Date>;
}

await sequelize.sync();

const user = await UserModel.create({
  name: "John",
  status: UserStatus.Active,
});

sequelize.sync() initializes every model registered with @Database, applies its metadata, resolves associations, and then calls Sequelize's native sync.

API

All public classes, decorators, helpers, and types are exported from @andrewcaires/sequelize.

Sequelize

Extends the native Sequelize class with model registration, instance lookup, and replication between connections.

Options

The constructor accepts Sequelize's native options and these additions:

| Option | Type | Description | | --- | --- | --- | | id | TypeKey | Identifier used to retrieve the connection and its bound models. | | uri | string | Connection URI. | | prefix | string | Prefix added to model and table names during initialization. | | timeout | string | Connection timeout such as "10s" or "2m". Defaults to "10s". | | replicate | Sequelize | Connection whose registered models should be cloned onto this instance. |

Unless overridden, the constructor disables logging and timestamps and uses the +00:00 timezone. Passing logging: true enables the package's SQL logger.

Methods

declare class Sequelize extends NativeSequelize {
  addModel(model: typeof Model): void;
  addModels(...models: Array<typeof Model>): void;
  getId(): TypeKey;
  getModels(): Array<typeof Model>;
  replicate(sequelize: Sequelize): void;
  sync(options?: SyncOptions): Promise<this>;

  static getInstance(id: TypeKey): Sequelize;
  static getInstances(): Array<Sequelize>;
}

Model

Extends Sequelize's native Model and provides helpers for connections and decorator metadata.

Methods

declare class Model<T extends Model = any, K extends Model = T>
  extends NativeModel<InferAttributes<T>, InferCreationAttributes<K>> {
  static getInstance<M extends Model>(id: TypeKey): ModelStatic<M>;
  static updateAttributes(): Promise<void>;
  static version(): string;
}
  • getInstance(id) returns the model bound to a specific connection.
  • version() returns the value declared with @Version, or "0.0.0".
  • updateAttributes() tries to change each non-primary-key column and adds it when it does not exist. This is a lightweight development helper, not a replacement for production migrations.

Class decorators

Class decorators configure the model metadata consumed by Sequelize.sync().

| Decorator | Description | | --- | --- | | @Database(connection) | Registers the model with a Sequelize instance or connection id. | | @ModelName(name) | Sets the model name and lets Sequelize derive the table name. | | @TableName(name) | Sets the table name directly. | | @Name(name, pluralized?) | Uses ModelName when pluralized is true, otherwise TableName. | | @Underscored(value) | Controls Sequelize's underscored model option. | | @Indexes(...indexes) | Declares one or more model indexes. | | @Scopes(scopes) | Declares named scopes. | | @DefaultScope(scope) | Declares the default scope. | | @Hooks(hooks) | Registers multiple Sequelize hooks. | | @Version(value) | Stores an application-defined model version. |

Column decorators

Column types are available through the Column namespace.

import { Column } from "@andrewcaires/sequelize";

@Column.String(120)
declare title: string;

@Column.Decimal(10, 2)
declare price: number;

@Column.Json()
declare metadata: Record<string, unknown>;

Data types

  • Numeric: BigInt, Decimal, Double, Float, and Integer.
  • Text and binary: Blob, Char, String, and Text.
  • Date and time: DateOnly, FullDate, Time, Timestamp.
  • Other values: Boolean, Enum, Json, UUIDV1, UUIDV4, and UUIDV7.

Use @Column.Id() for an auto-incrementing integer primary key, or pass 1, 4, or 7 to create a UUID primary key with the matching default generator.

Timestamps

| Decorator | Description | | --- | --- | | @Column.CreatedAt() | Maps the property to Sequelize's creation timestamp. | | @Column.UpdatedAt() | Maps the property to Sequelize's update timestamp. | | @Column.DeletedAt() | Maps the property to the deletion timestamp and enables paranoid mode. |

Modifiers

| Decorator | Description | | --- | --- | | @AllowNull() | Sets allowNull: true. | | @NotNull() | Sets allowNull: false. | | @PrimaryKey() | Marks the column as a primary key. | | @AutoIncrement() | Enables auto-increment. | | @Unique(value) | Controls the column's unique constraint. | | @DefaultValue(value) | Sets a literal or function default value. | | @Comment(value) | Adds a SQL column comment. | | @Index(options?) | Adds the column to a model index. | | @Value(callback, force?) | Computes the property before create and update operations. |

Association decorators

Associations receive callback functions so related models can reference one another without eager evaluation.

import { Association } from "@andrewcaires/sequelize";

@Association.BelongsTo(() => CompanyModel)
declare companyId: string;

@Association.HasMany(() => PostModel)
declare posts?: Array<PostModel>;

| Decorator | Native association | | --- | --- | | @Association.BelongsTo(() => Model, options?) | belongsTo | | @Association.HasOne(() => Model, options?) | hasOne | | @Association.HasMany(() => Model, options?) | hasMany | | @Association.BelongsToMany(() => Model, () => ThroughModel, options?) | belongsToMany | | @Association.OneToOne(() => Model, options?) | hasOne and belongsTo | | @Association.OneToMany(() => Model, options?) | hasMany and belongsTo |

The decorators derive aliases and foreign keys from the decorated property and model metadata when those options are omitted. Associations default to onDelete: "CASCADE".

Method decorators

Use @Hook(type) to register any Sequelize model hook, or import a named decorator such as @BeforeCreate(), @AfterUpdate(), or @BeforeFind().

import {
  BeforeCreate,
  Column,
  Database,
  Model,
  ModelName,
  Optional,
} from "@andrewcaires/sequelize";

@Database(sequelize)
@ModelName("user")
class UserModel extends Model<UserModel> {
  @Column.Id(7)
  declare readonly id: Optional<string>;

  @Column.String()
  declare name: string;

  @BeforeCreate()
  static normalize(user: UserModel): void {
    user.name = user.name.trim();
  }
}

Named decorators are provided for the supported before and after create, update, save, destroy, restore, find, query, sync, upsert, validate, count, and bulk operation hooks.

Multiple connections

Give each connection an id to retrieve the correct model class later.

const primary = new Sequelize({
  id: "primary",
  uri: "mariadb://root:[email protected]:3306/primary",
});

const replica = new Sequelize({
  id: "replica",
  replicate: primary,
  uri: "mariadb://root:[email protected]:3306/replica",
});

await primary.sync();
await replica.sync();

const PrimaryUser = UserModel.getInstance<UserModel>("primary");
const ReplicaUser = UserModel.getInstance<UserModel>("replica");

Where

Where.parse recursively converts allowlisted operator aliases into Sequelize Op symbols and rejects attributes outside the supplied allowlist.

Signature

declare class Where {
  static parse(attributes: Array<string>, object: TypeAnyObject): TypeAnyObject;
  static value(
    attributes: Array<string>,
    value: unknown,
  ): TypeScalar | TypeAnyObject | Array<TypeAnyObject>;
}

Example

import { Op, Where } from "@andrewcaires/sequelize";

const where = Where.parse(["name", "active"], {
  $AND: [
    { name: { $LIKE: "%john%" } },
    { active: true },
  ],
});

// {
//   [Op.and]: [
//     { name: { [Op.like]: "%john%" } },
//     { active: true },
//   ],
// }

Supported aliases include $OR, $AND, $EQ, $NE, $GT, $GTE, $LT, $LTE, $IS, $NOT, $BETWEEN, $NOTBETWEEN, $REGEXP, $NOTREGEXP, $IN, $NOTIN, $LIKE, $NOTLIKE, $STARTSWITH, $ENDSWITH, and $SUBSTRING. Symbolic alternatives such as ||, &&, =, !=, >, >=, <, and <= are also supported.

Type exports

The package re-exports Sequelize's DataType, DataTypes, and Op, together with types used by its decorators and model helpers.

import type {
  ModelCreateOptions,
  ModelFindOptions,
  ModelOptions,
  ModelUpdateOptions,
  OneToManyOptions,
  OneToOneOptions,
  Optional,
  Options,
} from "@andrewcaires/sequelize";

Development

npm run build
npm run check
npm run lint
npm test
npm run typecheck

build runs ESLint and creates ESM, CommonJS, and declaration bundles with Rollup. check runs the TypeScript compiler without emitting files and then runs the test suite.

Links

License

MIT