@nestjs-mod/prisma
TypeScript icon, indicating that this package has built-in type declarations

1.8.1 • Public • Published

@nestjs-mod/prisma

Next-generation Node.js and TypeScript ORM for NestJS-mod (preview version only for Postgres)

NPM version monthly downloads Telegram bot

Installation

npm i --save-dev prisma
npm i --save @prisma/client @nestjs-mod/prisma

Modules

Link Category Description
PrismaModule core Next-generation Node.js and TypeScript ORM for NestJS-mod (preview version only for Postgres)

Modules descriptions

PrismaModule

Next-generation Node.js and TypeScript ORM for NestJS-mod (preview version only for Postgres)

Use in NestJS

For add support prisma in NestJS please read https://docs.nestjs.com/recipes/prisma#set-up-prisma

Use with forRoot options.

import { InjectPrismaClient, PrismaModule } from '@nestjs-mod/prisma';
import { NestFactory } from '@nestjs/core';
import { randomUUID } from 'crypto';

import { Injectable, Module } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class AppService {
  constructor(
    @InjectPrismaClient()
    private readonly prismaService: PrismaClient
  ) {}

  async createUser({ externalUserId }: { externalUserId: string }) {
    return await this.prismaService.prismaUser.create({ data: { externalUserId } });
  }

  async getUsers() {
    return await this.prismaService.prismaUser.findMany();
  }
}

@Module({
  imports: [
    PrismaModule.forRoot({
      staticConfiguration: {
        prismaModule: import(`@prisma/prisma-user-client`),
        addMigrationScripts: true,
      },
    }),
  ],
  providers: [AppService],
})
export class AppModule {}

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  const service = app.get<AppService>(AppService);
  const externalUserId = randomUUID();
  await service.createUser({ externalUserId });
  console.log(await service.getUsers()); // output: [{ externalUserId: '568a823e-65ea-46ba-aa57-0194ee67e0f9' }]
}

bootstrap();

An example of access to module services with forFeature.

import { InjectPrismaClient, PrismaModule } from '@nestjs-mod/prisma';
import { NestFactory } from '@nestjs/core';
import { randomUUID } from 'crypto';

import { Injectable, Module } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class FeatureService {
  constructor(
    @InjectPrismaClient()
    private readonly prismaService: PrismaClient
  ) {}

  async createUser({ externalUserId }: { externalUserId: string }) {
    return await this.prismaService.prismaUser.create({ data: { externalUserId } });
  }

  async getUsers() {
    return await this.prismaService.prismaUser.findMany();
  }
}
@Module({
  imports: [
    PrismaModule.forFeature({
      featureModuleName: 'FeatureModule',
    }),
  ],
  providers: [FeatureService],
})
export class FeatureModule {}

@Module({
  imports: [
    PrismaModule.forRoot({
      staticConfiguration: {
        prismaModule: import(`@prisma/prisma-user-client`),
        addMigrationScripts: true,
      },
    }),
    FeatureModule,
  ],
})
export class AppModule {}

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  const service = app.get<FeatureService>(FeatureService);
  const externalUserId = randomUUID();
  await service.createUser({ externalUserId });
  console.log(await service.getUsers()); // output: [{ externalUserId: '568a823e-65ea-46ba-aa57-0194ee67e0f9' }]
}

bootstrap();

Use in NestJS-mod

An example of using forRoot with parameters, you can see the full example here https://github.com/nestjs-mod/nestjs-mod-contrib/tree/master/apps/example-prisma.

For Prisma to work, you must first connect the Docker Compose module and the Docker Compose module to work with the database.

import {
  DefaultNestApplicationInitializer,
  DefaultNestApplicationListener,
  InfrastructureMarkdownReportGenerator,
  PACKAGE_JSON_FILE,
  ProjectUtils,
  bootstrapNestApplication,
  isInfrastructureMode,
} from '@nestjs-mod/common';
import { DOCKER_COMPOSE_FILE, DockerCompose, DockerComposePostgreSQL } from '@nestjs-mod/docker-compose';
import { FakePrismaClient, PRISMA_SCHEMA_FILE, PrismaModule } from '@nestjs-mod/prisma';
import { join } from 'path';
import { userFeatureName } from './app/app.constants';
import { AppModule } from './app/app.module';

const rootFolder = join(__dirname, '..', '..', '..');
const appFolder = join(rootFolder, 'apps', 'example-prisma');

bootstrapNestApplication({
  modules: {
    system: [
      ProjectUtils.forRoot({
        staticConfiguration: {
          applicationPackageJsonFile: join(appFolder, PACKAGE_JSON_FILE),
          packageJsonFile: join(rootFolder, PACKAGE_JSON_FILE),
          envFile: join(rootFolder, '.env'),
        },
      }),
      DefaultNestApplicationInitializer.forRoot(),
      DefaultNestApplicationListener.forRoot({
        staticConfiguration: {
          // When running in infrastructure mode, the backend server does not start.
          mode: isInfrastructureMode() ? 'silent' : 'listen',
        },
      }),
    ],
    core: [
      PrismaModule.forRoot({
        staticConfiguration: {
          schemaFile: join(appFolder, 'src', 'prisma', `${userFeatureName}-${PRISMA_SCHEMA_FILE}`),
          featureName: userFeatureName,
          prismaModule: isInfrastructureMode()
            ? { PrismaClient: FakePrismaClient }
            : // remove after first run docs:infrastructure
              { PrismaClient: FakePrismaClient },
          // uncomment after first run docs:infrastructure
          // import(`@prisma/prisma-user-client`),
          addMigrationScripts: true,
        },
      }),
    ],
    feature: [AppModule.forRoot()],
    infrastructure: [
      InfrastructureMarkdownReportGenerator.forRoot({
        staticConfiguration: {
          markdownFile: join(appFolder, 'INFRASTRUCTURE.MD'),
          skipEmptySettings: true,
        },
      }),
      DockerCompose.forRoot({
        configuration: {
          dockerComposeFileVersion: '3',
          dockerComposeFile: join(appFolder, DOCKER_COMPOSE_FILE),
        },
      }),
      DockerComposePostgreSQL.forRoot(),
      DockerComposePostgreSQL.forFeature({
        featureModuleName: userFeatureName,
      }),
    ],
  },
});

After connecting the module to the application and npm run build and starting generation of documentation through npm run docs:infrastructure, you will have new files and scripts to run.

New scripts mostly package.json

{
  "scripts": {
    "_____prisma_____": "_____prisma_____",
    "prisma:migrate-dev-new:example-prisma": "./node_modules/.bin/nx run example-prisma:prisma-migrate-dev --create-only --name=new",
    "prisma:migrate-dev:example-prisma": "./node_modules/.bin/nx run example-prisma:prisma-migrate-dev --create-only",
    "prisma:migrate-deploy:example-prisma": "./node_modules/.bin/nx run example-prisma:prisma-migrate-deploy",
    "prisma:migrate-deploy": "./node_modules/.bin/nx run-many --exclude=@nestjs-mod/contrib -t=prisma-migrate-deploy",
    "prisma:pull": "./node_modules/.bin/nx run-many --exclude=@nestjs-mod/contrib -t=prisma-pull",
    "prisma:generate": "./node_modules/.bin/nx run-many --exclude=@nestjs-mod/contrib -t=prisma-generate"
  },
  "scriptsComments": {
    "prisma:pull": ["Generating a prisma schema based on a database"],
    "prisma:generate": ["Generation of client prisma schema of all applications and modules"],
    "prisma:migrate-dev:example-prisma": [
      "Alias for create new migration for example-prisma (example: `npm run prisma:migrate-dev:example-prisma --name=new)`"
    ],
    "prisma:migrate-deploy": ["Applying migrations of all applications and modules"],
    "prisma:migrate-dev-new:example-prisma": ["Command to create new empty migration for example-prisma"],
    "prisma:migrate-deploy:example-prisma": ["Applying migrations for example-prisma"]
  }
}

Additional commands in the nx application project.json

{
  "targets": {
    "prisma-generate": {
      "executor": "nx:run-commands",
      "options": {
        "commands": [
          "./node_modules/.bin/prisma generate --schema=./apps/example-prisma/src/prisma/prisma-user-schema.prisma"
        ],
        "parallel": false,
        "envFile": "./.env",
        "color": true
      }
    },
    "prisma-pull": {
      "executor": "nx:run-commands",
      "options": {
        "commands": [
          "./node_modules/.bin/prisma db pull --schema=./apps/example-prisma/src/prisma/prisma-user-schema.prisma"
        ],
        "parallel": false,
        "envFile": "./.env",
        "color": true
      }
    },
    "prisma-migrate-dev": {
      "executor": "nx:run-commands",
      "options": {
        "commands": [
          "./node_modules/.bin/prisma migrate dev --schema=./apps/example-prisma/src/prisma/prisma-user-schema.prisma"
        ],
        "parallel": false,
        "envFile": "./.env",
        "color": true
      }
    },
    "prisma-migrate-deploy": {
      "executor": "nx:run-commands",
      "options": {
        "commands": [
          "./node_modules/.bin/prisma migrate deploy --schema=./apps/example-prisma/src/prisma/prisma-user-schema.prisma"
        ],
        "parallel": false,
        "envFile": "./.env",
        "color": true
      }
    }
  }
}

Example of a prisma schema schema.prisma

generator client {
  provider   = "prisma-client-js"
  engineType = "binary"
  output     = "../../../../node_modules/@prisma/prisma-user-client"
}

datasource db {
  provider          = "postgres"
  url               = env("PRISMA_PRISMA_USER_DATABASE_URL")
  shadowDatabaseUrl = env("PRISMA_PRISMA_USER_SHADOW_DATABASE_URL")
}

model PrismaUser {
  id             String   @id(map: "PK_PRISMA_USER") @default(dbgenerated("uuid_generate_v4()")) @db.Uuid
  externalUserId String   @unique(map: "UQ_PRISMA_USER") @db.Uuid
  createdAt      DateTime @default(now()) @db.Timestamp(6)
  updatedAt      DateTime @default(now()) @db.Timestamp(6)
}

New environment variable

PRISMA_ROOT_DATABASE_URL=postgres://postgres:postgres_password@localhost:5432/postgres?schema=public
PRISMA_PRISMA_USER_DATABASE_URL=postgres://prisma_user:prisma_user_password@localhost:5432/prisma_user?schema=public
PRISMA_PRISMA_USER_SHADOW_DATABASE_URL=postgres://prisma_user:prisma_user_password@localhost:5432/shadow_prisma_user?schema=public

For create all needs prisma clients, please run npm run generate.

When launched in the infrastructure documentation generation mode, the module creates an .env file with a list of all required variables, as well as an example example.env, where you can enter example variable values.

Shared providers

PrismaClientFactoryService, PrismaClient

Environments

Key Description Sources Constraints Default Value
databaseUrl Connection string for database with credentials (example: postgres://feat:feat_password@localhost:5432/feat?schema=public) obj['databaseUrl'], process.env['DATABASE_URL'] isNotEmpty (databaseUrl should not be empty) - -

Static configuration

Key Description Constraints Default Value
defaultLogger Default logger optional - -
prismaModule NodeJS module with Prisma modules isNotEmpty (prismaModule should not be empty) - hidden
logging Logging types (all_queries or long_queries) optional long_queries -
maxQueryExecutionTime Max query execution time for detect long queries optional 5000 -
pingDatabaseIntervalMs Ping database interval (0 - disable) optional 0 -
featureName Prisma feature name for generate prefix to environments keys (infrastructure) optional - -
schemaFile Schema file for prisma (infrastructure) optional - -
addMigrationScripts The option specifies whether it is necessary to create scripts to work with database migrations, for those who use third-party applications to create and apply migrations in the database (infrastructure, example: https://flywaydb.org, https://www.npmjs.com/package/db-migrate) optional true -
customSchemaContent Unsafe string custom content for add to end of prisma schema file (infrastructure) optional - -
binaryTargets Binary targets (infrastructure) optional - -

Back to Top

Links

License

MIT

Package Sidebar

Install

npm i @nestjs-mod/prisma

Weekly Downloads

130

Version

1.8.1

License

MIT

Unpacked Size

97.4 kB

Total Files

44

Last publish

Collaborators

  • endykaufman