@dudousxd/nestjs-media-database-drizzle
Drizzle media store (sqlite, and Postgres via /pg), migration-first.
A MediaStore backed by Drizzle ORM. The store is a POJO that receives your drizzle db handle.
import { DrizzleMediaStore, createMediaTable, mediaTable } from '@dudousxd/nestjs-media-database-drizzle';
createMediaTable(db); // dev/test helper — see below
MediaModule.forRoot({ default: 's3', disks: { s3 }, store: new DrizzleMediaStore(db) });Migration-first
Drizzle is migration-first by design — there's no runtime auto-schema. In production you manage the table with drizzle-kit using the exported mediaTable schema; createMediaTable(db) is a convenience for tests and quick dev setups that issues the CREATE TABLE IF NOT EXISTS.
Postgres (/pg)
Drizzle's schema is dialect-specific, so the package root ships the sqlite/libSQL schema and the Postgres flavour lives on its own subpath, @dudousxd/nestjs-media-database-drizzle/pg (built on drizzle-orm/pg-core). Its stores accept any drizzle Postgres database (PgDatabase — node-postgres, postgres-js, neon, pglite, …).
import { drizzle } from 'drizzle-orm/node-postgres';
import {
DrizzlePgMediaStore,
DrizzlePgUploadSessionStore,
createMediaPgTables,
} from '@dudousxd/nestjs-media-database-drizzle/pg';
const db = drizzle(process.env.DATABASE_URL!);
await createMediaPgTables(db); // dev/test helper — use drizzle-kit migrations in production
MediaModule.forRoot({
default: 's3',
disks: { s3 },
store: new DrizzlePgMediaStore(db),
// resumable uploads: persist sessions + multipart ETags in Postgres
uploadSessions: new DrizzlePgUploadSessionStore(db),
});| Export | What it is |
|---|---|
mediaPgTable | media table (jsonb properties/conversions, bigint size, timestamptz dates) — same logical shape as mediaTable |
DrizzlePgMediaStore | MediaStore over mediaPgTable (count / aggregate / keyset-cursor list included) |
mediaUploadSessionsPgTable, mediaUploadPartsPgTable | media_upload_sessions + media_upload_parts (FK ON DELETE CASCADE, PK (session_id, part_number)) |
DrizzlePgUploadSessionStore | UploadSessionStore with every optional method: atomic addPart (INSERT … ON CONFLICT DO UPDATE), listParts, list({ disk, keyPrefix }) |
createMediaPgTables(db) / MEDIA_PG_DDL | idempotent CREATE TABLE/INDEX IF NOT EXISTS for tests and dev |
DrizzlePgDatabase | the accepted db type (PgDatabase<any, any, any>) |
For drizzle-kit, re-export mediaPgTable, mediaUploadSessionsPgTable and mediaUploadPartsPgTable from your schema file and generate migrations as usual.
Attachment column
For the attachment column model — a single file as a JSON value object on your own table — use the attachment() custom column:
import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { attachment } from '@dudousxd/nestjs-media-database-drizzle';
export const users = sqliteTable('users', {
id: text('id').primaryKey(),
avatar: attachment('avatar'), // Attachment | null, stored as JSON text
});On write it JSON.stringifys the Attachment (or stores null); on read it rehydrates an Attachment. The column is sqlite/libSQL — for Postgres/MySQL define the equivalent JSON column in that dialect and (de)serialize with the value object's toJSON() / Attachment.fromJSON().
Peer dependencies
drizzle-orm (>=0.38 <1, tested on 0.45) and @dudousxd/nestjs-media-core, plus a driver (better-sqlite3, libsql, … — or pg / postgres for /pg). See Concepts → Persistence and Concepts → Attachments.