@edifice.io/edifice-nestjs-core

中文文档
1.0.7发布于 2026/11/14AGPL-3.0TypeScriptCommonJS近 30 天下载 3097

Core NestJS modules and utilities for Edifice applications

原始使用文档
文档目录12 节
  1. 📦 Installation
  2. 🚀 Features
  3. Modules
  4. Utilities
  5. 📖 Usage
  6. Basic Setup
  7. CLI Tools
  8. 🔧 Configuration
  9. Environment Variables
  10. 🛠 Development
  11. 🔗 Related Packages
  12. 🐛 Issues

About edifice-nestjs-core

  • Licence : Copyright Edifice
  • Funder(s) : Edifice
  • Developer(s) : Edifice

@edifice.io/edifice-nestjs-core

Core NestJS modules and utilities for Edifice applications.

📦 Installation

pnpm add @edifice.io/edifice-nestjs-core

🚀 Features

This package provides essential building blocks for building Edifice backend applications with NestJS:

Modules

  • AppRegistry: Application registry service
  • Config: Centralized configuration management
  • Database: MikroORM integration with PostgreSQL support
  • Event: Event emitter for data
  • Health: Health check endpoints (readiness, liveness)
  • I18n: Internationalization service for multi-language support
  • Logger: Structured logging with Pino (access logs, request logs)
  • NATS: NATS messaging client integration
  • Permission: Authorization guards and decorators (ADMC, permission-based)
  • Session: Session management middleware and decorators
  • Timeline: Timeline notification service

AppRegistry (Application Registration)

The AppRegistryService is included automatically via the CoreModule.
It registers your application with the Edifice App Registry at startup.

This process scans all controllers for @RequirePermission decorators, collects all declared workflow permissions, and sends them to the registry along with application metadata.

How it works:

  • On application bootstrap, AppRegistryService.registerApp() is called.
  • It extracts all permissions from your controllers using reflection.
  • It sends an AppRegistrationRequestDTO to the registry via NATS.
  • The registration is retried every 10 seconds until successful.

Where and when:

  • Registration happens automatically during the bootstrap phase (see createApp() in bootstrap.utils.ts).
  • You do not need to call it manually; it is triggered by the core module (CoreModule).

Why:

  • This ensures your app and its permissions are discoverable and manageable by the Edifice platform.
  • It enables centralized permission management and workflow integration.

Example:

import { CoreModule } from '@edifice.io/edifice-nestjs-core';

@Module({
  imports: [CoreModule], // AppRegistryService is included automatically
})
export class AppModule {}

@Controller()
export class ResourceController {
  @Get()
  @RequirePermission('ACCESS')
  async findAll() {
    // This permission will be registered automatically
  }
}

Config (Centralized Application Configuration)

The ConfigModule is automatically included when you import CoreModule in your application.
It provides centralized configuration management for your Edifice backend, using NestJS's ConfigModule and supporting environment variables.

Features:

  • Loads configuration from environment variables.
  • Exposes configuration via NestJS ConfigService for dependency injection.
  • Provides helpers for logging, database, Swagger, and other modules to read their settings.

How it works:

  • On application startup, the configuration is loaded from environment variables and injected globally.
  • All modules (database, logger, NATS, etc.) read their settings from ConfigService.
  • You can override configuration by setting environment variables.

Where and when:

  • The configuration system is initialized automatically at application startup by CoreModule.
  • No manual setup is needed; just set the required environment variables.

Configuration:

  • Set your main configuration using environment variables.
  • See src/config/EnvVars.md for a full list of supported variables and their defaults.

Example environment variables:

APP_NAME=my-edifice-app
APP_DISPLAY_NAME=My Edifice App
APP_PREFIX=/api
APP_ICON=https://example.com/icon.png

HOST=0.0.0.0
PORT=3002

DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
DATABASE_USER=user
DATABASE_PASSWORD=pass
DATABASE_SCHEMA=public
DATABASE_DEBUG=true
DATABASE_SSL=false

NATS_URL=nats://localhost:4222
NATS_USER=natsuser
NATS_PASSWORD=natspass
NATS_DEBUG=false

LOG_LEVEL=info
LOG_KEEP_RAW_FIELDS=false

SWAGGER_SERVER_URL=https://api.example.com
HEAP_MEMORY=300
RSS_MEMORY=300

Example:

import { Module } from '@nestjs/common';
import { CoreModule } from '@edifice.io/edifice-nestjs-core';
import { ConfigService } from '@nestjs/config';

@Module({
  imports: [CoreModule], // ConfigModule is included automatically
})
export class AppModule {
  constructor(private readonly configService: ConfigService) {
    const appName = this.configService.get<string>('app.name');
    console.log(`App name: ${appName}`);
  }
}

Note:
You do not need to configure the configuration system manually; it is ready to use when you import CoreModule.
All modules and services can access configuration via dependency injection of ConfigService.

Additional configuration:

You can also provide additional configuration like so

import { Module } from '@nestjs/common';
import { configuration as CoreConfig } from '@edifice.io/edifice-nestjs-core';
import AppConfig from './config/configuration'; // Your app's configuration object
import { CoreModule } from '@edifice.io/edifice-nestjs-core';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [
    CoreModule,
    // Use config defined in core + app config
    // (warn: does not override core config fields)
    ConfigModule.forRoot({
      isGlobal: true,
      load: [CoreConfig, AppConfig],
    }),
  ],
})
export class AppModule {}

Database (MikroORM Integration)

The DatabaseModule provides seamless integration with MikroORM and PostgreSQL for your Edifice backend application.

Features:

  • Automatic database connection and configuration using NestJS ConfigModule.
  • Runs pending migrations automatically at startup (if enabled in configuration).
  • Provides helpers to execute SQL scripts and manage schema evolution.

How to use:

  • Import DatabaseModule in your main application module (already included in CoreModule).
  • Configure your database connection via environment variables (DATABASE_URL, DATABASE_USER, etc.).
  • Place your migration scripts in the sql/ directory, following the naming convention:
    • NN-description.sql for migration scripts (e.g., 01-init.sql)
    • NN-rollback.sql for rollback scripts (e.g., 01-rollback.sql)
  • Implement migration classes in ./src/migrations/, each using the helper to execute the corresponding SQL files.

Example:

  • Implement migration classes in ./src/migrations/, each using the helper to execute the corresponding SQL files.

SQL migration script (sql/01-init.sql):

-- Create a demo table
CREATE TABLE demo_table (
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL
);

SQL rollback script (sql/01-rollback.sql):

-- Drop the demo table
DROP TABLE IF EXISTS demo_table;

Migration class (src/migrations/Migration01.ts):

import { Migration } from '@mikro-orm/migrations';
import { executeScript } from '@edifice.io/edifice-nestjs-core';

export class Migration01 extends Migration {
  async up(): Promise<void> {
    await executeScript(this, '01-init.sql');
  }

  async down(): Promise<void> {
    await executeScript(this, '01-rollback.sql');
  }
}

Entity definition (src/entities/demo.entity.ts):

import { Entity, PrimaryKey, Property } from '@mikro-orm/core';

@Entity()
export class Demo {
  @PrimaryKey()
  id!: number;

  @Property()
  name!: string;
}

Service using EntityRepository (src/demo/demo.service.ts):

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@mikro-orm/nestjs';
import { EntityRepository } from '@mikro-orm/postgresql';
import { Demo } from '../entities/demo.entity';

@Injectable()
export class DemoService {
  constructor(
    @InjectRepository(Demo)
    private readonly demoRepository: EntityRepository<Demo>,
  ) {}

  async createDemo(name: string): Promise<Demo> {
    const demo = this.demoRepository.create({ name });
    await this.demoRepository.persistAndFlush(demo);
    return demo;
  }

  async findAll(): Promise<Demo[]> {
    return this.demoRepository.findAll();
  }
}

Demo module (src/demo/demo.module.ts):

import { Module } from '@nestjs/common';
import { CoreModule } from '@edifice.io/edifice-nestjs-core';
import { DemoService } from './demo.service';
import { Demo } from '../entities/demo.entity';
import { MikroOrmModule } from '@mikro-orm/nestjs';

@Module({
  imports: [CoreModule, MikroOrmModule.forFeature([Demo])],
  providers: [DemoService],
  exports: [DemoService],
})
export class DemoModule {}

Note:

  • Database connection parameters and migration behavior are controlled via environment variables.
  • The module ensures your database schema is up-to-date and provides utilities for advanced migration workflows.

Event (User Event Tracking)

The EventModule provides services for tracking and recording user events (such as access and creation) in your Edifice backend application.

Features:

  • Publishes user events (ACCESS, CREATE) to the Edifice event system via NATS.
  • Automatically extracts user/session information from requests.
  • Skips access events for mobile webview requests.
  • Centralizes event logging for analytics and auditing.

How to use:

  • Import CoreModule in your main application module (already includes EventModule).
  • Inject EventService into your controllers or services.
  • Call createAccessEvent(request, resourceType) or createCreateEvent(request, resourceType) to record events.

Example:

import { Controller, Get, Post, Req, Injectable } from '@nestjs/common';
import { EventService, CoreModule } from '@edifice.io/edifice-nestjs-core';
import { FastifyRequest } from 'fastify';

@Module({
  imports: [CoreModule],
})
export class AppModule {}

@Controller()
export class ResourceController {
  constructor(private readonly eventService: EventService) {}

  @Get('/')
  async onResourceAccess(@Req() request: FastifyRequest) {
    await this.eventService.createAccessEvent(request);
  }

  @Post('/')
  async onResourceCreate(@Req() request: FastifyRequest) {
    await this.eventService.createCreateEvent(request, 'RESOURCE_TYPE');
  }
}

Configuration:

  • The module uses ConfigService to get the application name (app.name).
  • Events are sent via the NATS client (EntNatsServiceClient), which is configured automatically by the core module.

Note:

  • You do not need to configure the event system manually; it is ready to use when you import CoreModule.
  • Events are useful for analytics, auditing, and workflow triggers.

Health (Readiness & Liveness Checks)

The HealthModule is automatically included when you import CoreModule in your application.
It provides endpoints and services for readiness and liveness checks, integrating with NestJS Terminus.

Features:

  • Exposes a /health endpoint for readiness and liveness checks.
  • Checks database connectivity (MikroORM), memory usage, and NATS connection.
  • Customizable thresholds for memory usage via configuration.
  • Integrates with monitoring and orchestration systems (Kubernetes, Docker, etc.).

How it works:

  • The HealthController aggregates checks for database, memory, and NATS.
  • Health indicators are injected and run automatically.
  • The /health endpoint is public and can be used for probes.

Where and when:

  • The health system is initialized automatically at application startup by CoreModule.
  • No manual configuration is needed; all dependencies are wired by the core module.

Configuration:

  • Memory thresholds and other health parameters are set using environment variables:
    HEAP_MEMORY=300
    RSS_MEMORY=300
    
  • You can adjust these values to fit your deployment requirements.

Example:

import { Module } from '@nestjs/common';
import { CoreModule } from '@edifice.io/edifice-nestjs-core';

@Module({
  imports: [CoreModule], // HealthModule is included automatically
})
export class AppModule {}

Note:
You do not need to configure health endpoints manually; they are ready to use when you import CoreModule.
Health checks are essential for cloud-native deployments and automated monitoring.

I18n (Internationalization Service)

The I18nModule is automatically included when you import CoreModule in your application.
It provides services for registering and fetching translations, enabling multi-language support for your Edifice backend.

Features:

  • Registers translation files for your application at startup.
  • Fetches translations dynamically based on request headers (language detection).
  • Integrates with the Edifice ENT client for centralized translation management.
  • Supports custom translation files per language (e.g., assets/i18n/fr.json).
  • Used by other modules such as notifications to provide localized content.

How it works:

  • The I18nService is initialized and injected by the core module.
  • On application startup, translation files in assets/i18n/ are registered automatically.
  • You can fetch translations for the current request or application using provided service methods.
  • The notification system (TimelineService and custom notification services) uses I18nService to localize notification content.

Where and when:

  • The i18n system is initialized automatically at application startup by CoreModule.
  • No manual configuration is needed; all dependencies are wired by the core module.

Configuration:

  • The application name (APP_NAME) must be set using environment variables.
  • Place your translation files in the assets/i18n/ directory (e.g., fr.json, en.json).

Example:

import { Module, Controller, Get, Req } from '@nestjs/common';
import { CoreModule, I18nService } from '@edifice.io/edifice-nestjs-core';
import { FastifyRequest } from 'fastify';

@Module({
  imports: [CoreModule], // I18nModule is included automatically
})
export class AppModule {}

@Injectable()
export class MyService {
  constructor(private readonly i18nService: I18nService) {}

  async getTranslations(@Req() request: FastifyRequest) {
    return await this.i18nService.fetchCurrentAppTranslationsForRequest(
      request,
    );
  }
}

Note:
By default, FrontendController exposes an /i18n route that serves translations for your application.
You do not need to create a custom controller or route for i18n; it is already handled by the core module.

Logger (Structured Logging)

The LoggerModule is automatically included when you import CoreModule in your application.
It provides structured logging using Pino, including access logs and request logs for your Edifice backend.

Features:

  • Structured JSON logging for all requests and application events.
  • Request-scoped logger (RequestLogger) for contextual logs (user, path, method).
  • Access logger (AccessLogger) for logging authentication and access events.
  • Integrates with NestJS and supports log levels, child loggers, and custom fields.

How it works:

  • The logger is initialized and injected by the core module.
  • You can inject RequestLogger or AccessLogger into your controllers, services, or middleware.
  • Logs are automatically enriched with request/session/user information.

Where and when:

  • Logging is initialized automatically at application startup by CoreModule.
  • No manual configuration is needed; all dependencies are wired by the core module.

Configuration:

  • Log level and options are set using environment variables:
    LOG_LEVEL=info
    LOG_KEEP_RAW_FIELDS=false
    
  • You can adjust these values to fit your deployment requirements.

Example:

import { Module, Controller, Get, Req } from '@nestjs/common';
import { Logger } from 'nestjs-pino';
import { CoreModule } from '@edifice.io/edifice-nestjs-core';
import { FastifyRequest } from 'fastify';

@Module({
  imports: [CoreModule], // LoggerModule is included automatically
})
export class AppModule {}

@Controller()
export class MyController {
  constructor(private readonly logger: Logger) {}

  @Get('hello')
  async hello(@Req() request: FastifyRequest) {
    this.logger.info({ path: request.url }, 'Hello endpoint accessed');
    return { message: 'Hello world' };
  }
}

Note:
You do not need to configure logging manually; it is ready to use when you import CoreModule.
All logs are structured and can be consumed by log aggregation systems.

NATS (Messaging Client Integration)

The NatsModule is automatically included when you import CoreModule in your application.
It provides a centralized NATS client for messaging, service calls, and pub/sub communication between Edifice microservices.

Features:

  • Centralized NATS configuration and connection management.
  • Exports a configured NATS ClientProxy for messaging and service communication.
  • Supports pub/sub and request/response patterns using NestJS decorators (EventPattern, MessagePattern).
  • Includes a safe deserializer to handle non-JSON messages gracefully.
  • Allows you to instantiate external service clients (like EntNatsServiceClient from @edifice.io/edifice-ent-client), which use the provided NATS connection for inter-service calls.
  • Provides EntNatsServiceClient for calling external Edifice services (request/response).

How it works:

  • The NATS client is initialized and injected by the core module.
  • You can inject EntNatsServiceClient to call external services.
  • You can use abstract subscriber classes (generated by the CLI) to handle incoming events and requests.

Where and when:

  • The NATS system is initialized automatically at application startup by CoreModule.
  • No manual configuration is needed; all dependencies are wired by the core module.

Configuration:

  • NATS connection parameters are set using environment variables:
    NATS_URL=nats://localhost:4222
    NATS_USER=natsuser
    NATS_PASSWORD=natspass
    NATS_DEBUG=false
    
  • You can adjust these values to fit your deployment requirements.

Calling an external service:

This example shows how to call an external Edifice service using the EntNatsServiceClient.
The package @edifice.io/edifice-ent-client is generated from entcore via the CLI.
It is an external dependency and uses the NATS connection provided by the core module.

import { Injectable } from '@nestjs/common';
import { EntNatsServiceClient } from '@edifice.io/edifice-ent-client';

@Injectable()
export class CommunicationService {
  constructor(private readonly entServiceClient: EntNatsServiceClient) {}

  async addLinkBetweenGroups(
    sourceGroupId: string,
    targetGroupId: string,
  ): Promise<boolean> {
    const request = { startGroupId: sourceGroupId, endGroupId: targetGroupId };
    const response = await this.entServiceClient.addLinkBetweenGroups(request);
    return response.created ?? false;
  }
}

Handling pub/sub and service requests:

This example shows how to subscribe to events or respond to service requests using NestJS decorators and abstract classes generated by the CLI.

import {
  EventPattern,
  MessagePattern,
  Payload,
  Ctx,
  NatsContext,
} from '@nestjs/microservices';

// These abstract subscriber classes are generated by the CLI.
// You should extend them to implement your own event/message handling logic.

// Example: Subscribe to events
export abstract class BrokerSubscriber {
  @EventPattern('directory.groups.deleted')
  onGroupsDeleted(
    @Payload() data: GroupsDeletedDTO,
    @Ctx() context: NatsContext,
  ) {
    this.handleGroupsDeletedEvent(data, context.getSubject());
  }
  abstract handleGroupsDeletedEvent(
    data: GroupsDeletedDTO,
    subject: string,
  ): void;
}

// Example: Respond to service requests
export abstract class AudienceSubscriber {
  @MessagePattern('audience.check.right.communities.*')
  onCheckResourceAccess(
    @Payload() request: CheckResourceAccessRequestDTO,
    @Ctx() ctx: NatsContext,
  ): Promise<CheckResourceAccessResponseDTO> {
    return this.handleCheckAnnouncementAccess(request, ctx.getSubject());
  }
  abstract handleCheckAnnouncementAccess(
    request: CheckResourceAccessRequestDTO,
    subject: string,
  ): Promise<CheckResourceAccessResponseDTO>;
}

// Example: Concrete implementation
@Controller()
export class MyBrokerSubscriber extends BrokerSubscriber {
  handleGroupsDeletedEvent(data: GroupsDeletedDTO, subject: string): void {
    // Your custom logic here
    console.log(
      `Groups deleted: ${JSON.stringify(data)} from subject: ${subject}`,
    );
  }
}

@Controller()
export class MyAudienceSubscriber extends AudienceSubscriber {
  async handleCheckAnnouncementAccess(
    request: CheckResourceAccessRequestDTO,
    subject: string,
  ): Promise<CheckResourceAccessResponseDTO> {
    // Your custom logic here
    return { accessGranted: true };
  }
}

Note:

  • You do not need to configure NATS manually; it is ready to use when you import CoreModule.
  • Use EntNatsServiceClient for external service calls, and abstract subscriber classes for pub/sub and request/response patterns.
  • The CLI can generate abstract subscriber classes to help you implement event and message handlers.

Permission (Authorization Guards & Decorators)

The PermissionModule is automatically included when you import CoreModule in your application.
It provides decorators and guards for workflow-based and admin authorization, enabling fine-grained access control for your endpoints.

Features:

  • @RequirePermission('PERMISSION_NAME'): Restricts access to endpoints based on user workflow rights. Mandatory decorator.
  • @RequireAdmc(): Restricts access to endpoints for super administrators (ADMC).
  • @Public(): Marks endpoints as public (no authentication required).
  • @BasicAuth(): Adds Basic authorization method for an endpoint. The authorized user and password are set in configuration.

How it works:

  • Decorators set metadata on your controllers and endpoints.
  • Guards read this metadata and check the user's session and permissions.
  • Permissions are automatically registered at startup by the AppRegistry service.

Where and when:

  • The permission system is initialized automatically at application startup by CoreModule.
  • No manual configuration is needed; all dependencies are wired by the core module.

Configuration:

  • User permissions and roles are provided in the session object (entSession).
  • Workflow rights are defined in your business logic and registered via decorators.

Example:

import { Controller, Get, Post } from '@nestjs/common';
import {
  RequirePermission,
  RequireAdmc,
  Public,
  CoreModule,
} from '@edifice.io/edifice-nestjs-core';

@Module({
  imports: [CoreModule], // PermissionModule is included automatically
})
export class AppModule {}

@Controller('resources')
export class ResourceController {
  @Get()
  @RequirePermission('COMMUNITY_ACCESS')
  async findAll() {
    // Only users with COMMUNITY_ACCESS permission can access this endpoint
  }

  @Post('/admin')
  @RequireAdmc() // Only super administrators can access this endpoint
  async adminTask() {
    // Admin logic here
  }

  @Get('public-info')
  @Public()
  async publicInfo() {
    // This endpoint is accessible without authentication
  }
}

Note:
You do not need to configure permission guards manually; they are ready to use when you import CoreModule.
All permissions are automatically registered and enforced for your endpoints.

Session (User Session Management)

The SessionModule is automatically included when you import CoreModule in your application.
It provides middleware, decorators, and helpers for managing user sessions in your Edifice backend.

Features:

  • Middleware to validate and attach user sessions to each request.
  • Session decorator (@Session()) to inject the session directly into your controller methods.
  • Exposes session information on the raw Fastify request object (request.raw.entSession).
  • Integrates with the ENT service via NATS for session validation and refresh.

How it works:

  • The session middleware runs on every API request, validates the session via the ENT service, and attaches it to the request.
  • You can access the session in your controllers using either the @Session() decorator or directly from the request object.

Where and when:

  • The session system is initialized automatically at application startup by CoreModule.
  • No manual configuration is needed; all dependencies are wired by the core module.

Configuration:

  • Session validation uses the NATS connection provided by the core module.

Example:

import { Controller, Get, Req } from '@nestjs/common';
import { CoreModule, Session } from '@edifice.io/edifice-nestjs-core';
import { FastifyRequest } from 'fastify';
import { ENTUserSession } from '@edifice.io/edifice-ent-client';

@Module({
  imports: [CoreModule], // SessionModule is included automatically
})
export class AppModule {}

@Controller('profile')
export class ProfileController {
  @Get()
  async getProfile(@Session() session: ENTUserSession) {
    // Access session directly via decorator
    return { userId: session.userId, name: session.displayName };
  }

  @Get('raw')
  async getProfileRaw(@Req() request: FastifyRequest) {
    // Access session via Fastify request object
    const session = request.raw.entSession;
    return { userId: session.userId, name: session.displayName };
  }
}

Note:
You do not need to configure session management manually; it is ready to use when you import CoreModule.
Session information is available in all controllers and can be accessed via the decorator or the request object.

Timeline (Notification Service)

The TimelineModule is automatically included when you import CoreModule in your application.
It provides services for registering notification templates and sending notifications to users via the Edifice timeline system.

Features:

  • Register notification templates for your application.
  • Send notifications to users (with push, mail, and preview options).
  • Integrates with the ENT client and NATS for delivery.
  • Supports localization via the I18n service.

How it works:

  • The TimelineService is initialized and injected by the core module.
  • You can register notification templates at startup or on demand.
  • You can send notifications to users by calling the service methods.

Where and when:

  • The timeline system is initialized automatically at application startup by CoreModule.
  • No manual configuration is needed; all dependencies are wired by the core module.

Configuration:

  • The application name (APP_NAME) must be set using environment variables.
  • Notification templates can be registered at module initialization or dynamically.

Registering notification templates:

When you register a notification template, you provide a RegisterNotificationRequestDTO object.
This object describes how your notification will appear and behave in the Edifice timeline system.

Main fields in RegisterNotificationRequestDTO:

  • notificationName (string):
    Unique identifier for your notification event (e.g., "MY_EVENT").

  • title (string):
    Title displayed to the user in the timeline.

  • body (string):
    Main content or message of the notification (can include HTML).

  • appAddress (string, optional):
    URL path to access the application or resource related to the notification.

  • defaultFrequency (IMMEDIATE | DAILY | WEEKLY | NEVER, optional):
    Default delivery frequency for the notification.

  • restriction (NONE | INTERNAL | EXTERNAL | HIDDEN, optional):
    Restriction level for visibility (e.g., only internal users).

  • pushNotif (object, optional):
    Push notification options, such as title and body for mobile/web push.

  • preview (object, optional):
    Preview configuration for the notification.

  • params (object, optional):
    Custom parameters for dynamic content or links.

Example:

const template: RegisterNotificationRequestDTO = {
  notificationName: 'MY_EVENT',
  title: 'My Event',
  body: '<b>A new event occurred!</b>',
  appAddress: '/events/123',
  defaultFrequency: 'IMMEDIATE',
  restriction: 'NONE',
  pushNotif: {
    title: 'Event!',
    body: 'You have a new event.',
  },
  preview: {
    imageUrl: '/assets/event.png',
    description: 'Preview of the event notification',
  },
  params: {
    resourceId: '123',
    customParam: 'value',
  },
};
import { Injectable, OnModuleInit } from '@nestjs/common';
import { TimelineService } from '@edifice.io/edifice-nestjs-core';
import { RegisterNotificationRequestDTO } from '@edifice.io/edifice-ent-client';

@Injectable()
export class MyNotificationService implements OnModuleInit {
  constructor(private readonly timelineService: TimelineService) {}

  async onModuleInit() {
    const templates: RegisterNotificationRequestDTO[] = [
      {
        notificationName: 'MY_EVENT',
        title: 'My Event',
        body: 'A new event occurred!',
        // ...other template fields
      },
    ];
    await this.timelineService.registerNotifications(templates);
  }
}

Sending a notification:

import { TimelineService } from '@edifice.io/edifice-nestjs-core';
import {
  SessionDto,
  SendNotificationRequestDTO,
} from '@edifice.io/edifice-ent-client';

@Injectable()
export class MyService {
  constructor(private readonly timelineService: TimelineService) {}

  async sendNotification(session: SessionDto) {
    const notification: SendNotificationRequestDTO = {
      notificationName: 'MY_EVENT',
      recipientIds: ['userId1', 'userId2'],
      resourceUri: '/resource/123',
      params: { customParam: 'value' },
      pushNotif: {
        title: 'Event!',
        body: 'You have a new event.',
      },
    };

    await this.timelineService.sendNotification(session, notification);
  }
}

Note:

  • You do not need to configure the timeline system manually; it is ready to use when you import CoreModule.
  • Notifications are localized using the I18n service and delivered via NATS and the ENT client.

Swagger (OpenAPI Documentation)

The Swagger module is automatically enabled when you import CoreModule in your application (unless you disable it via environment variables).
It provides an interactive OpenAPI documentation for your API, available at /openapi.

Features:

  • Auto-generates OpenAPI documentation from your controllers and DTOs.
  • Serves the Swagger UI at /openapi by default.
  • Supports custom title, description, version, and server URL via environment variables.

How it works:

  • On application startup, Swagger is configured and started automatically if ENABLE_SWAGGER=true (default).
  • The configuration is read from environment variables and injected via ConfigService.

Configuration: Set the following environment variables to customize Swagger:

ENABLE_SWAGGER=true
SWAGGER_SERVER_URL=https://api.example.com
SWAGGER_TITLE=My Edifice API
SWAGGER_DESCRIPTION=API documentation for my Edifice backend
VERSION=1.0.0

Note:
You do not need to configure Swagger manually; it is ready to use when you import CoreModule.
Access your API documentation at /openapi.

Utilities

  • Bootstrap: Application bootstrap helpers
  • Entity Naming: Database entity naming conventions
  • Static Assets: Static file serving utilities

📖 Usage

Basic Setup

import { Module } from '@nestjs/common';
import { CoreModule } from '@edifice.io/edifice-nestjs-core';

@Module({
  imports: [CoreModule],
})
export class AppModule {}

CLI Tools

This package provides several CLI tools to help you automate common backend tasks.
Each tool is available as a binary when you install @edifice.io/edifice-nestjs-core.

  • edifice-generate-entities: Generate MikroORM entities from database schema
  • edifice-generate-metadata: Generate application metadata file
  • edifice-k6-sync-dto: Synchronize DTOs for K6 Testing
  • generate-swagger-pdf: Generate a PDF from your NestJS API Swagger documentation

Generate entities

Purpose:
Generate MikroORM entity files from your PostgreSQL database schema.

Usage:

pnpm edifice-generate-entities --schema <schema-name> [options]

Arguments:

  • --schema (required): Name of the database schema to use for entity generation.
  • --path: Target directory for generated entities (default: ./src/entities).
  • --temp-dir: Temporary directory for initial generation (default: ./src/temp/entities).
  • --mapping-config: Path to entity-module mapping file (default: ./src/config/entity-mapping.config.json).
  • --keep-temp: Keep temporary directory after generation (true or false, default: false).

Examples:

pnpm edifice-generate-entities --schema community
pnpm edifice-generate-entities --schema community --temp-dir ./src/temp --path ./src/entities
pnpm edifice-generate-entities --schema community --mapping-config ./src/config/entity-mapping.config.json
pnpm edifice-generate-entities --schema community --keep-temp true

Generate metadata

Purpose:
Generate a build metadata file containing build date, git commit hash, and branch name.

Usage:

pnpm edifice-generate-metadata <target-file-path>

Arguments:

  • <target-file-path> (required): Path to the file where metadata will be written.

Example:

pnpm edifice-generate-metadata ./dist/metadata.txt

Sync K6 DTO

Purpose:
Synchronize DTO TypeScript definitions to K6-compatible types for API testing.

Usage:

pnpm edifice-k6-sync-dto

Arguments:
This script uses configuration constants for DTOs and output paths.
You can adjust the paths in the script or via environment variables if supported.

Example:

pnpm edifice-k6-sync-dto

Details:

  • Parses DTOs from client/rest/src/dtos.
  • Generates K6-compatible types in types/generated.
  • Excludes files named index.ts by default.

generate-swagger-pdf

Purpose:
Generate a PDF from the Swagger (OpenAPI) documentation exposed by your NestJS server.

Usage:

npx generate-swagger-pdf --host <host> --port <port>

Options:

  • --host, -h: Swagger server host (default: 127.0.0.1)
  • --port, -p: Swagger server port (default: 3002)

The PDF will be generated in the documentation/api-docs.pdf folder of your project.

Example:

npx generate-swagger-pdf --host 127.0.0.1 --port 4000

This package provides several CLI tools to help you automate common backend tasks.
Each tool is available as a binary when you install @edifice.io/edifice-nestjs-core.

  • edifice-generate-entities: Generate MikroORM entities from database schema
  • edifice-generate-metadata: Generate application metadata file
  • edifice-k6-sync-dto: Synchronize DTOs for K6 Testing
  • generate-swagger-pdf: Generate a PDF from your NestJS API Swagger documentation

Note:
All CLI tools are available after installing the package.
You can run them with pnpm or npx from your project root.

🔧 Configuration

The core module uses NestJS ConfigModule for configuration. You can provide configuration through environment variables or configuration files.

Environment Variables

  • DATABASE_URL: PostgreSQL connection string
  • NATS_URL: NATS server URL
  • LOG_LEVEL: Logging level (debug, info, warn, error)
  • NODE_ENV: Environment (development, production)

🛠 Development

# Install dependencies
pnpm install

# Build
pnpm build

# Format code
pnpm format

# Lint code
pnpm lint

🐛 Issues

Report issues on GitHub Issues.

版本与发布记录

@edifice.io/edifice-nestjs-core 共发布 117 个版本,首次发布于 2025/12/01;过去 12 个月发布了 117 个版本。

版本发布日期距今
1.0.7latest2026/11/14今天
1.0.6-develop.202611100922012026/11/103 天前
1.0.6-develop.202611092053462026/11/104 天前
1.0.6-develop.202611091648292026/11/104 天前
1.0.6-develop.202611091608322026/11/104 天前
1.0.6-develop.202611052251022026/11/068 天前

其他发布通道:feat-PEDAGO-3968 → 1.0.0-develop-pedago.20260429142813,feat-basic-auth-guard → 1.0.0-develop-pedago.20260430125558,chore-upgrade-orm-dependency → 1.0.0-develop-pedago.20260505114249,fix-PEDAGO-3997 → 1.0.0-develop-pedago.20260512111340,feat-PEDAGO-3959-storage-module → 1.0.3-develop-pedago.20260520165333,feat-PEDAGO-4289 → 1.0.5-develop-pedago.20260903132341。

关于 @edifice.io/edifice-nestjs-core 的常见问题

@edifice.io/edifice-nestjs-core 是什么?

Core NestJS modules and utilities for Edifice applications

如何安装 @edifice.io/edifice-nestjs-core?

在项目目录运行 npm install @edifice.io/edifice-nestjs-core,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:rxjs(7.8.2)、fastify(5.6.0)、@nestjs/core(11.0.20)、@nestjs/common(11.0.20)、@nestjs/config(4.0.0)、@mikro-orm/core(6.6.10)、@nestjs/swagger(11.2.0)、@nestjs/terminus(11.0.0)、reflect-metadata(0.2.0)、@mikro-orm/nestjs(6.1.1)、@mikro-orm/postgresql(6.6.10)、@nestjs/microservices(11.0.20)、@nestjs/platform-fastify(11.0.20)、@edifice.io/edifice-ent-client(6.16.11)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 edifice-k6-sync-dto、edifice-update-version、edifice-generate-entities、edifice-generate-metadata、edifice-update-rn-version、edifice-generate-rest-client、edifice-generate-swagger-pdf,可以用 npx edifice-k6-sync-dto 直接运行。

@edifice.io/edifice-nestjs-core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@edifice.io/edifice-nestjs-core 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@edifice.io/edifice-nestjs-core 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@edifice.io/edifice-nestjs-core 可以商用吗?

@edifice.io/edifice-nestjs-core 使用 AGPL-3.0 许可。最严格的 Copyleft:除分发外,通过网络向用户提供基于它的服务也需要开源对应源码。闭源 SaaS 使用前务必评估。以上为概括,不构成法律意见,请以许可原文为准。

@edifice.io/edifice-nestjs-core 的下载量有多少?

根据 npm 官方下载统计,@edifice.io/edifice-nestjs-core 在 2026/10/13 – 2026/11/11 这 30 天内被下载 3,097 次,日均约 103 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@edifice.io/edifice-nestjs-core 还在维护吗?

最新版本 1.0.7 发布于 2026/11/14(今天);至今共发布 117 个版本,其中过去 12 个月发布了 117 个;首次发布于 2025/12/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。