NestboltNestbolt

@nestbolt/taggable

Introduction

Polymorphic tagging system for NestJS with TypeORM -- attach tags and categories to any entity.

@nestbolt/taggable provides a polymorphic tagging system for NestJS that lets you attach tags and categories to any TypeORM entity using a shared tags table and a taggables pivot table. Decorate an entity with @Taggable(), and you get full tag CRUD, attach/detach/sync, and querying out of the box.

Key Features

  • Polymorphic tagging -- a single tags table and taggables pivot table work across all your entities via taggableType + taggableId.
  • Tag CRUD -- create, find, find-or-create, and delete tags with name, slug, type/group, and optional JSON metadata.
  • Attach / Detach / Sync -- attach tags to entities, detach them, or sync a set of tags in one call.
  • @Taggable() decorator -- class decorator to mark entities as taggable with an optional custom type override.
  • Entity mixin -- TaggableMixin adds attachTag(), detachTag(), syncTags(), getTags(), hasTag(), and getTagCount() directly on your entity instances.
  • Query helpers -- get all tags for an entity, check if an entity has a specific tag, get all entity IDs with a given tag, and count tags.
  • Event system -- emits tag.created, tag.deleted, tag.attached, and tag.detached events via optional @nestjs/event-emitter.
  • Unique constraints -- composite unique indexes prevent duplicate tags and duplicate attachments.

Architecture

The package is built around several core components:

TaggableModule registers all providers globally. You call TaggableModule.forRoot() or TaggableModule.forRootAsync() once in your root module, and TaggableService becomes available everywhere via dependency injection.

TaggableService is the primary API surface. It provides full tag CRUD (createTag, findOrCreateTag, findTagById, findTagBySlug, findTagsByType, getAllTags, deleteTag) plus attach/detach/sync operations and query helpers.

TagEntity is the tags table -- stores tag name, URL-friendly slug, optional type/group, and optional JSON metadata.

TaggableEntity is the taggables pivot table -- stores the polymorphic relationship between a tag and any entity via tagId, taggableType, and taggableId.

@Taggable() decorator stores metadata on your entity class that maps it to a taggableType string used in the pivot table.

TaggableMixin is an optional mixin that adds convenience methods directly to your entity instances.

Basic Usage

import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
import { Taggable, TaggableMixin } from "@nestbolt/taggable";

@Taggable()
@Entity("posts")
export class Post extends TaggableMixin(BaseEntity) {
  @PrimaryGeneratedColumn("uuid")
  id!: string;

  @Column()
  title!: string;
}

// Attach tags
const tag = await taggableService.findOrCreateTag("NestJS");
await taggableService.attachTag(Post, postId, tag.id);

Next Steps

  • Installation -- install the package and its peer dependencies.
  • Quick Start -- register the module, decorate an entity, and start tagging in minutes.
  • Configuration -- forRoot and forRootAsync module setup.
  • Decorator -- @Taggable() options reference.
  • Mixin -- add tag methods directly on your entity instances.
  • Tag CRUD -- create, find, and delete tags.
  • Attaching Tags -- attach, detach, sync, and query tags on entities.
  • Events -- listen to tag lifecycle events.