Aviary
Packages

@dudousxd/nestjs-media-database-typeorm

TypeORM media store with non-destructive auto-schema.

A MediaStore backed by TypeORM. A POJO that receives your DataSource — no @Injectable, no internal token — so you plug it into MediaModule through forRootAsync.

import { TypeOrmMediaStore, ensureMediaSchema } from '@dudousxd/nestjs-media-database-typeorm';

MediaModule.forRootAsync({
  inject: [getDataSourceToken()],
  useFactory: (ds) => ({ default: 's3', disks: { s3 }, store: new TypeOrmMediaStore(ds) }),
});

Auto-schema

new TypeOrmMediaStore(ds) creates the media table on first use, non-destructively: it creates the table if missing and adds any missing columns, but never drops, alters types, or renames. Opt out to manage it yourself:

new TypeOrmMediaStore(ds, { autoCreateSchema: false }); // you own migrations
await ensureMediaSchema(ds);                             // or call it explicitly at boot

The entity is declared via EntitySchema (not decorators), so the package carries no decorator-metadata build requirement, and order maps to a position column to avoid the reserved word.

Portable timestamps

Timestamps are stored as ISO strings (varchar) rather than a dialect-specific date type — so the same schema works on sqlite, mysql, and postgres alike. This is verified by an integration suite running the store against real Postgres (testcontainers).

Named connections

Pass any DataSource — a secondary/named connection works the same way:

inject: [getDataSourceToken('media')],
useFactory: (ds) => ({ /* … */ store: new TypeOrmMediaStore(ds) }),

Attachment column

Beyond the media table, this package also wires the attachment column model — a single file stored as a JSON value object directly on your entity. Use the @AttachmentColumn() decorator:

import { Entity, PrimaryColumn } from 'typeorm';
import type { Attachment } from '@dudousxd/nestjs-media-core';
import { AttachmentColumn } from '@dudousxd/nestjs-media-database-typeorm';

@Entity()
export class User {
  @PrimaryColumn() id!: string;

  @AttachmentColumn() avatar!: Attachment | null;
}

It stores a portable simple-json column, nullable by default, and rehydrates the value into an Attachment on read. Pass any ColumnOptions to override (@AttachmentColumn({ name: 'avatar_data' })).

Using EntitySchema instead of decorators? Apply the underlying attachmentTransformer to a simple-json column directly:

import { attachmentTransformer } from '@dudousxd/nestjs-media-database-typeorm';

columns: {
  avatar: { type: 'simple-json', nullable: true, transformer: attachmentTransformer },
}

The round-trip is verified against real sqlite in the package's test suite.

Peer dependencies

typeorm (^0.3) and @dudousxd/nestjs-media-core. See Concepts → Persistence for the shared store contract, and Concepts → Attachments for the column model.

On this page