NestboltNestbolt

@nestbolt/taggable

Decorator

The @Taggable() class decorator marks an entity for polymorphic tagging.

@Taggable()

The @Taggable() decorator marks a TypeORM entity as taggable. It stores metadata on the class that the service uses to determine the taggableType value in the pivot table.

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

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

  @Column()
  title!: string;
}

Options

OptionTypeDefaultDescription
typestringClass nameOverride the entity type name stored in the taggables pivot table

Custom Type

By default, the taggableType stored in the pivot table is the entity's class name. You can override this with a custom string:

@Taggable({ type: "BlogPost" })
@Entity("posts")
export class Post {
  // ...
}

This is useful when:

  • Your class name doesn't match the desired type identifier
  • You want a stable identifier that won't change if the class is renamed
  • You have multiple entity classes that should share the same tag pool

Default Behavior

@Taggable()
@Entity("posts")
export class Post { /* ... */ }
// taggableType in pivot table: "Post"

@Taggable()
@Entity("articles")
export class Article { /* ... */ }
// taggableType in pivot table: "Article"

Custom Type Override

@Taggable({ type: "content" })
@Entity("posts")
export class Post { /* ... */ }
// taggableType in pivot table: "content"

@Taggable({ type: "content" })
@Entity("articles")
export class Article { /* ... */ }
// taggableType in pivot table: "content"
// Now Post and Article share the same tag pool

Without the Decorator

You can use TaggableService methods without the @Taggable() decorator. In that case, the entity's class name is used as the taggableType by default:

// No @Taggable() decorator
@Entity("comments")
export class Comment {
  @PrimaryGeneratedColumn("uuid")
  id!: string;
}

// This still works -- taggableType falls back to "Comment"
await taggableService.attachTag(Comment, commentId, tagId);

The decorator is only required if you want to customize the type name or use the TaggableMixin with accurate type resolution.

Combining with TaggableMixin

The @Taggable() decorator works together with TaggableMixin. The mixin's getTaggableType() method reads the decorator metadata:

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

const post = new Post();
post.getTaggableType(); // "BlogPost"

See Mixin for all mixin methods.