@open-kingdom/shared-backend-data-access-database-setup
v0.0.2-16
Published
A NestJS global dynamic module that opens a `better-sqlite3` connection, wraps it with Drizzle ORM, applies SQLite PRAGMAs, and provides the `BetterSQLite3Database` instance to the NestJS DI container under the `DB_TAG` injection token.
Readme
@open-kingdom/shared-backend-data-access-database-setup
A NestJS global dynamic module that opens a better-sqlite3 connection, wraps it with Drizzle ORM, applies SQLite PRAGMAs, and provides the BetterSQLite3Database instance to the NestJS DI container under the DB_TAG injection token.
Exports
| Export | Kind | Description |
| ---------------------------- | ----------- | -------------------------------------------------------------------- |
| DatabaseSetupModule | class | Global NestJS dynamic module. Use .register(options) to configure. |
| DatabaseSetupModuleOptions | interface | Type-only export. Type of the argument accepted by .register(). |
Type Definitions
DatabaseSetupModuleOptions is a generic interface with a type parameter TSchema extends Record<string, unknown> (defaulting to Record<string, unknown>). It accepts the following properties:
| Property | Type | Required | Default | Description |
| ---------- | ------------------------ | -------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| schema | TSchema | Yes | — | Drizzle table definitions object. Pass all tables the application needs so relational queries resolve correctly. |
| filename | string | No | 'demo.db' | Path to the SQLite database file. Relative paths resolve from the process working directory. The file is created if it does not exist. |
| pragmas | Record<string, string> | No | {} | SQLite PRAGMAs applied immediately after the connection opens. Each key/value pair is executed as sqlite.pragma('key = value'). |
The injection token is not exported from this package. It is DB_TAG from @open-kingdom/shared-poly-util-constants.
Module Registration
DatabaseSetupModule is declared global: true. Register it once in the root AppModule. All other modules throughout the application can inject the database without importing this module again.
// app.module.ts
import { Module } from '@nestjs/common';
import { DatabaseSetupModule } from '@open-kingdom/shared-backend-data-access-database-setup';
import * as schema from '@open-kingdom/demo-scaffold-backend-feature-root-schema';
@Module({
imports: [
DatabaseSetupModule.register({
schema,
filename: process.env['DB_FILENAME'] ?? 'app.db',
pragmas: {
journal_mode: 'WAL',
foreign_keys: 'ON',
},
}),
],
})
export class AppModule {}Configuration Options
| Option | Type | Default | Description |
| ---------- | ----------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| schema | TSchema extends Record<string, unknown> | — (required) | All Drizzle table definition objects the application needs. Pass the full merged schema so that relational queries (db.query.*) resolve correctly. |
| filename | string | 'demo.db' | Path to the SQLite database file. Relative paths resolve from the process working directory. The file is created if it does not exist. |
| pragmas | Record<string, string> | {} | SQLite PRAGMAs applied immediately after the connection opens. Each entry is executed as sqlite.pragma('key = value'). Common values: { journal_mode: 'WAL', foreign_keys: 'ON' }. |
Module Behavior
DatabaseSetupModule.register(options)returns aDynamicModulewithglobal: true.- The module factory opens (or creates) the SQLite file at
options.filenameusingbetter-sqlite3. - Each entry in
options.pragmasis applied synchronously before any queries run. - Drizzle ORM wraps the connection using the provided
options.schema. - The resulting
BetterSQLite3Database<TSchema>is provided under theDB_TAGtoken and exported globally.
Migration execution is not performed automatically. Migrations are managed via drizzle-kit scripts in the application's package.json. The typical scripts are db:generate (runs drizzle-kit generate) and db:migrate (runs drizzle-kit migrate), both pointing to a drizzle.config.ts configuration file.
Injecting the Database
import { Injectable, Inject } from '@nestjs/common';
import { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
import { DB_TAG } from '@open-kingdom/shared-poly-util-constants';
import * as schema from '@open-kingdom/demo-scaffold-backend-feature-root-schema';
@Injectable()
export class MyService {
constructor(@Inject(DB_TAG) private db: BetterSQLite3Database<typeof schema>) {}
async findAll() {
return this.db.query.myTable.findMany();
}
}API Reference
DatabaseSetupModule.register<TSchema>(options: DatabaseSetupModuleOptions<TSchema>): DynamicModule
Static factory method returning a NestJS DynamicModule. Must be called in the imports array of a module decorator.
Provided token: DB_TAG → BetterSQLite3Database<TSchema>
Global: true — the provided token is visible to all modules in the application without further imports.
Throws at startup if the SQLite file cannot be opened (permission denied, invalid directory, etc.).
Testing
nx test @open-kingdom/shared-backend-data-access-database-setup