# @elsikora/nestjs-crud-config 中文文档

规范地址：https://npmcn.com/package/%40elsikora/nestjs-crud-config/

版本：5\.1\.0
npm 元数据更新时间：2026-11-04T11:49:48.146Z
中文译文更新时间：2026-11-13T14:16:40.683Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40elsikora/nestjs-crud-config
原文对照：https://npmcn.com/package/%40elsikora/nestjs-crud-config/?lang=original
项目主页：https://github.com/ElsiKora/NestJS-Crud-Config#readme
源码仓库：https://github.com/ElsiKora/NestJS-Crud-Config

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：214 kB，104 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：^22\.13\.0 \|\| \>=24\.11\.0
- 运行依赖：4 个
- peer 依赖：lodash ^4\.18\.1，fastify ^5\.12\.7，typeorm ^1\.1\.2，@nestjs/core ^12\.3\.2，@nestjs/common ^12\.3\.2，@nestjs/swagger ^12\.0\.0，@nestjs/typeorm ^12\.0\.1，class-validator ^0\.15\.1，@nestjs/passport ^12\.0\.0，@nestjs/throttler ^6\.7\.1，class-transformer ^0\.5\.1，@nestjs/platform-fastify ^12\.3\.2，@elsikora/nestjs-crud-automator ^5\.0\.0
- 首次发布：2025-07-14T13:27:36.521Z
- 最新版本发布：2026-11-04T11:49:47.967Z
- 近 30 天下载量：7382（2026-10-14 至 2026-11-12，npm 官方下载统计）
- 已发布版本数：49（近 12 个月 35 个）

## 中文简介

通过数据库存储 NestJS 应用程序配置

## 安装

```sh
npm install @elsikora/nestjs-crud-config
```

也可以使用：`pnpm add @elsikora/nestjs-crud-config`、`yarn add @elsikora/nestjs-crud-config`、`bun add @elsikora/nestjs-crud-config`

## README

![project-logo](https://6jft62zmy9nx2oea.public.blob.vercel-storage.com/nestjs-crud-config-dCbe8myqKpk3fxrTwBFBVCkKaz399M.png)

# 雀巢JS CRUD 配置

_具有全部CRUD能力的 NestJS 应用程序的数据库支持配置管理_

 [![ElsiKora](https://img.shields.io/badge/MADE%20BY%20ElsiKora-333333.svg?style=for-the-badge)](https://elsikora.com/)![TypeScript](https://img.shields.io/badge/TypeScript-3178C6.svg?style=for-the-badge&logo=typescript&logoColor=white) ![NestJS](https://img.shields.io/badge/NestJS-E0234E.svg?style=for-the-badge&logo=nestjs&logoColor=white) ![Node.js](https://img.shields.io/badge/Node.js-339933.svg?style=for-the-badge&logo=node.js&logoColor=white) ![PostgreSQL](https://img.shields.io/badge/PostgreSQL-4169E1.svg?style=for-the-badge&logo=postgresql&logoColor=white) ![MySQL](https://img.shields.io/badge/MySQL-4479A1.svg?style=for-the-badge&logo=mysql&logoColor=white) ![SQLite](https://img.shields.io/badge/SQLite-003B57.svg?style=for-the-badge&logo=sqlite&logoColor=white) ![MongoDB](https://img.shields.io/badge/MongoDB-47A248.svg?style=for-the-badge&logo=mongodb&logoColor=white) ![Swagger](https://img.shields.io/badge/Swagger-85EA2D.svg?style=for-the-badge&logo=swagger&logoColor=black)

## 目录

-   [说明](https://npmcn.com/package/%40elsikora/nestjs-crud-config/#readme--description)
-   [特征](https://npmcn.com/package/%40elsikora/nestjs-crud-config/#readme--features)
-   [安装](https://npmcn.com/package/%40elsikora/nestjs-crud-config/#readme--installation)
-   [迁移到 5.0](https://npmcn.com/package/%40elsikora/nestjs-crud-config/#readme-migrating-to-50)
-   [使用量](https://npmcn.com/package/%40elsikora/nestjs-crud-config/#readme--usage)
-   [移徙系统](https://npmcn.com/package/%40elsikora/nestjs-crud-config/#readme--migration-system)
-   [API 文档](https://npmcn.com/package/%40elsikora/nestjs-crud-config/#readme--api-documentation)
-   [数据库Schema](https://npmcn.com/package/%40elsikora/nestjs-crud-config/#readme--database-schema)
-   [高级配置](https://npmcn.com/package/%40elsikora/nestjs-crud-config/#readme--advanced-configuration)
-   [路线图](https://npmcn.com/package/%40elsikora/nestjs-crud-config/#readme--roadmap)
-   [财务问题](https://npmcn.com/package/%40elsikora/nestjs-crud-config/#readme--faq)
-   [许可证](https://npmcn.com/package/%40elsikora/nestjs-crud-config/#readme--license)

## 说明

NestJS CRUD Cfig是一个强大的配置管理模块,它革命化了NestJS应用程序如何处理配置数据. 与传统环境可变方法不同的是,这种库存储配置在一个拥有完整 CRUD 操作的数据库中,使它在跨越多个环境和服务的动态配置管理上变得完美.

该模块通过章节和数据条目提供分级组织,支持敏感值的可选AES-256-GCM加密,并包括用于配置管理的自动REST API端点. 由TypeScript-First设计并使用NestJS CRUD Automator用于自动API生成而来,它具有运行时动态实体创建的特点,命名为交易所有权,以及智能缓存.

无论是管理跨不同环境的API密钥,存储地物旗,还是维护需要不进行再调用而改变的应用程序设置,本模块为微服务架构,多租户应用程序,以及任何需要集中的,数据库支持的配置管理,以及实时更新的系统提供了稳健,安全和可扩展的解决方案.

## \* 特性

-   **QQ 数据库支持的配置存储** - 将配置储存在任何TypeORM支持的数据库中,以便持久和可扩展
-   **\* 动态实体创建** - 实体在运行时有自定义的表格名称、字段长度和限制
-   **\* 等级组织** - 利用章节和数据条目组织配置,以更好地构建和管理结构
-   **AES-256-GCM 加密支持** - 利用行业标准算法保护内置加密的敏感配置值
-   **\* 多种环境支助** - 管理整个开发、中转和生产环境的配置
-   **\* 完整的 CRUD 操作** - 完成创建、读取、更新、删除自动 REST API 端点的操作
-   **自动 Swagger 文档** - 为所有配置终点生成 OpenAPI 文件
-   **QQ TypeScript 第一设计** - 有综合接口和类型定义的完整类型安全
-   **NestJS CRUD 自动化器集成** - 控制器和服务高级CRUD自动化
-   **智能缓存** - 内置缓存支持,可配置 TTL 和缓存大小限制
-   **\* 已命名交易所有权** - 每个自动化人拥有的工作单位使用一个精确的TypeORM管理器,包括联合迁移写作
-   **高度定制** - 配置表格前缀、字段长度、验证规则和实体关系
-   **XQ 灵活控制器配置** - 自定义 API 路径、禁用端点或以无头模式运行
-   **高级 CRUD 定制** - 全面控制航道、扫描文档和控制者行为
-   **模块架构** - 为您的使用设置所需的启用/残疾特性
-   **生产准备移民系统** - 应用程序启动期间初始化和管理配置状态

## \* 安装

这些文件描述了 CrudConfig 5 合同: Automator 5, NestJS 12, TypeORM 1, 仅ES模块. 使用5.x范围,它也接受5.0.0预放:

```bash
# npm
npm install @elsikora/nestjs-crud-config@^5.0.0-0

# yarn
yarn add @elsikora/nestjs-crud-config@^5.0.0-0

# pnpm
pnpm add @elsikora/nestjs-crud-config@^5.0.0-0
```

### 先决条件

节点.js `^22.13.0 || >=24.11.0`。安装所需的同伴依赖:

```bash
npm install @elsikora/nestjs-crud-automator@^5.0.0-0 @nestjs/common@^12 @nestjs/core@^12 @nestjs/typeorm@^12 typeorm@^1
npm install @nestjs/passport@^12 @nestjs/platform-fastify@^12 @nestjs/swagger@^12 @nestjs/throttler class-transformer class-validator fastify lodash
```

包船仅作为ES模块. 通用JS应用程序保存 `require("@elsikora/nestjs-crud-config")`,该节点Js装入 `require(esm)`。导入软件包 `.env` 文件: 设置 `NCC_LOG_LEVEL` 在环境中,或负载 `.env` 在应用程序中,例如: `ConfigModule.forRoot()`。 。 。 .

### 自动化 5 兼容性

CrudConfig 5 需要一个 `@elsikora/nestjs-crud-automator ^5.0.0`。自动化器 4 和 4 以上不支持.

生成的路径运行自动化器 `ApiAuthorizationGuard`。当区域或数据控制器启用时,导入 Automator 全局 `ApiAuthorizationModule` 在根模块中一次, 如以下示例; 没有它, 应用程序启动时失败 `Nest can't resolve dependencies of the ApiAuthorizationGuard`无头模式不需要它.

生成的路由覆盖继续使用自动生成配置 :

```typescript
DELETE: {
 generation: {
  isEnabled: false,
 },
},
```

配置数据 `CREATE` 财务报告和审定财务报表 `UPDATE` 使用自动嵌入的请求关系加载。 内置的章节关系期望请求机构,如 `{ "section": { "id": "section-uuid" } }`。 。 。 .

CrudConfig 通过创建每个生成的服务 `createDynamicService()` 财务报告和审定财务报表 `@ApiService({ entity })`,因此其所继承的同实体 CRUD 方法满足了自动生成-路由能力边界. 应用程序不需要包装或相容层.

### 迁移到 5.0

CrudConfig 5 移动到最新的主机和舰只作为ES模块. CrudConfig运行时间合同没有变化:

-   同位素移动到自动化器 5, NestJS 12, Swagger 12, `@nestjs/typeorm` 12和类型ORM 1;节点.js `^22.13.0 || >=24.11.0`· ;
-   仅基于无害环境管理: `dist/esm`, (中文(简体) ), `dist/cjs` 编辑 `require` 导出条件已去, CommunityJS 应用程序装入软件包 `require(esm)`· ;
-   页:1 `@nestjs/cache-manager` 依赖性移动到12,所以 `npm ci` 不再失败 `ERESOLVE` (c) 监视12;
-   包不再导入 `dotenv/config`: 从不装入 `.env`,以及 `NCC_LOG_LEVEL` 来源于应用程序的环境;
-   模块选项, `CrudConfigService`,生成的路由,数据库计划和交易所有权不变.

见完整 [5.0 移徙指南](https://npmcn.com/package/%40elsikora/nestjs-crud-config/docs/guides/migrating-to-5-0/page.mdx)编辑 [4.0 (韩语)](https://npmcn.com/package/%40elsikora/nestjs-crud-config/docs/guides/migrating-to-4-0/page.mdx) 财务报告和审定财务报表 [3.0 调用](https://npmcn.com/package/%40elsikora/nestjs-crud-config/docs/guides/migrating-to-3-0/page.mdx) 旧的升级仍提供移徙指南.

### 数据库支持

此软件包与 TypeORM 支持的任何数据库工作 :

-   邮递SQL
-   MySQL/马里亚DB
-   SQLite (通过 `better-sqlite3` 驱动程序; TypeORM 1 删除 `sqlite`(中文(简体) )
-   微软 SQL 服务器
-   甲骨文
-   蒙戈DB
-   鸡尾酒

## 使用量

### 基本设置

```typescript
// app.module.ts
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { ApiAuthorizationModule } from "@elsikora/nestjs-crud-automator";
import { CrudConfigModule, TOKEN_CONSTANT } from "@elsikora/nestjs-crud-config";

@Module({
 imports: [
  // Automator's generated routes run ApiAuthorizationGuard; import this global module once in the root module
  ApiAuthorizationModule,
  // First register CrudConfigModule to create dynamic entities
  CrudConfigModule.register({
   environment: "development",
   shouldAutoCreateSections: true,

   // Cache configuration
   cacheOptions: {
    isEnabled: true,
    maxCacheItems: 1000,
    maxCacheTTL: 3600000, // 1 hour in milliseconds
   },

   // Encryption configuration
   encryptionOptions: {
    isEnabled: true,
    encryptionKey: process.env.CONFIG_ENCRYPTION_KEY, // 32+ character key
   },

   // Controller configuration (optional)
   controllersOptions: {
    section: {
     isEnabled: true,
     properties: {
      path: "api/config/sections",
     },
    },
    data: {
     isEnabled: true,
     properties: {
      path: "api/config/data",
     },
    },
   },

   // Entity customization
   entityOptions: {
    tablePrefix: "app_",
    timestampColumnType: "timestamptz", // PostgreSQL; defaults to Date, the timestamp type of the driver
    configSection: {
     tableName: "config_sections",
     maxNameLength: 128,
     maxDescriptionLength: 512,
    },
    configData: {
     tableName: "config_data",
     maxValueLength: 8192,
     maxEnvironmentLength: 64,
     maxNameLength: 128,
     maxDescriptionLength: 512,
    },
   },
  }),

  // Then register TypeORM with dynamic entities using registerAsync
  TypeOrmModule.forRootAsync({
   imports: [CrudConfigModule],
   inject: [TOKEN_CONSTANT.CONFIG_SECTION_ENTITY, TOKEN_CONSTANT.CONFIG_DATA_ENTITY],
   useFactory: async (sectionEntity, dataEntity) => ({
    type: "postgres",
    host: "localhost",
    port: 5432,
    username: "postgres",
    password: "postgres",
    database: "config_db",
    entities: [
     // Your other entities
     // UserEntity, ProductEntity, etc.

     // Dynamic entities from CrudConfigModule
     sectionEntity,
     dataEntity,
    ],
    synchronize: true,
   }),
  }),
 ],
})
export class AppModule {}
```

### 使用配置服务

```typescript
// config.service.ts
import { Injectable } from "@nestjs/common";
import { CrudConfigService } from "@elsikora/nestjs-crud-config";

@Injectable()
export class MyConfigService {
 constructor(private readonly configService: CrudConfigService) {}

 async setupApplicationConfig() {
  // Set a configuration value
  await this.configService.set({
   section: "api-settings",
   name: "API_KEY",
   value: "my-secret-api-key",
   description: "Production API key",
   environment: "production",
  });

  // Retrieve configuration by section and name
  const apiConfig = await this.configService.get({
   section: "api-settings",
   name: "API_KEY",
   environment: "production",
   shouldLoadSectionInfo: true,
   useCache: true,
  });

  console.log("API Configuration:", apiConfig);
  // apiConfig.value will be automatically decrypted if it was encrypted

  return apiConfig;
 }

 async getConfigurationList() {
  // Get all configurations in a section
  const configs = await this.configService.getList({
   section: "api-settings",
   environment: "production",
   useCache: true,
  });

  return configs;
 }

 async deleteConfiguration() {
  // Delete a configuration
  await this.configService.delete({
   section: "api-settings",
   name: "API_KEY",
   environment: "production",
  });
 }
}
```

### Async 模块注册

使用时 `registerAsync()`,必须通过 `staticOptions` 属性, 因为 NestJS 不支持 async 控制器注册 :

```typescript
// app.module.ts
import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { ApiAuthorizationModule } from "@elsikora/nestjs-crud-automator";
import { CrudConfigModule } from "@elsikora/nestjs-crud-config";

@Module({
 imports: [
  ApiAuthorizationModule,
  ConfigModule.forRoot(),
  CrudConfigModule.registerAsync({
   imports: [ConfigModule],
   inject: [ConfigService],
   // Dynamic options - resolved asynchronously
   useFactory: async (configService: ConfigService) => ({
    environment: configService.get("NODE_ENV", "development"),
    encryptionOptions: {
     isEnabled: true,
     encryptionKey: configService.get("ENCRYPTION_KEY"),
    },
    cacheOptions: {
     isEnabled: true,
     maxCacheItems: 1000,
     maxCacheTTL: 3600000,
    },
   }),
   // Static options - must be known at module registration time
   staticOptions: {
    controllersOptions: {
     section: {
      isEnabled: true,
      properties: {
       path: "api/config/sections",
      },
     },
     data: {
      isEnabled: true,
      properties: {
       path: "api/config/data",
      },
     },
    },
    entityOptions: {
     tablePrefix: "app_",
     timestampColumnType: "timestamptz", // Must be static for dynamic entities
     configSection: {
      tableName: "config_sections",
      maxNameLength: 128,
     },
     configData: {
      tableName: "config_data",
      maxValueLength: 8192,
     },
    },
    migrationEntityOptions: {
     tableName: "config_migrations",
    },
   },
  }),
 ],
})
export class AppModule {}
```

**重要内容:** 这个 `staticOptions` 属性包含在模块编译时必须知道的配置 :

-   `controllersOptions` - REST API 控制器配置
-   `entityOptions` - 数据库实体定制(表格名称、字段长度、时间戳类型)
-   `migrationEntityOptions` - 迁移跟踪表配置

## 移民系统

NestJS CRUD 配置模块包含一个强大的 **生产准备移民系统** 它允许您在应用程序启动时初始化和管理配置状态。 该系统确保您的应用程序始终拥有不同环境和部署所需的配置数据.

### 关键特性

-   **启动时自动执行** - 应用程序拖带时自动迁移
-   **QQ 已命名的交易支持** - 在一个名为Automator的拥有者内部进行交易式迁移
-   **环境专题小组** - 为不同的环境创建不同的配置
-   **移徙跟踪** - 有时间戳和执行状况的完整审计线索
-   **后退支持** - 为每次迁移确定回滚程序
-   **被困移民清理** - 自动暂停和清理已坠毁的迁移
-   **\* 类型安全状态跟踪** - 用途 `EConfigMigrationStatus` 可靠状态管理说明
-   **\* 种族条件保护** - 安全执行防止同时发生的冲突

### 移民状态 Enum

移徙系统使用 `EConfigMigrationStatus` 用于跟踪移民状况的提示:

```typescript
import { EConfigMigrationStatus } from "@elsikora/nestjs-crud-config";

// Available statuses:
EConfigMigrationStatus.PENDING; // Migration is pending execution
EConfigMigrationStatus.RUNNING; // Migration is currently running
EConfigMigrationStatus.COMPLETED; // Migration completed successfully
EConfigMigrationStatus.FAILED; // Migration failed with error
EConfigMigrationStatus.STUCK; // Migration is stuck (timeout)
```

### 基本迁移配置

在模块注册中配置迁移 :

```typescript
import { CrudConfigModule } from "@elsikora/nestjs-crud-config";
import { initialAppConfigMigration } from "./migrations/001-initial-app-config.migration";

@Module({
 imports: [
  CrudConfigModule.register({
   environment: process.env.NODE_ENV || "development",

   // Migration configuration
   migrationOptions: {
    isEnabled: true,
    shouldRunOnStartup: true,
    useTransaction: true,
    stuckMigrationTimeoutMinutes: 30,
    tableName: "config_migrations", // Optional: custom table name

    migrations: [
     initialAppConfigMigration,
     // Add more migrations here
    ],
   },

   // Other configuration options...
  }),
 ],
})
export class AppModule {}
```

与 `useTransaction: true` (默认),执行拥有一个 `crud-config-migrations` 交易并传递准确 `EntityManager` 每一次迁移回调。 传那个经理作为 `eventManager` 在迁移的每个配置操作。 把它从 `set()` 试图打开单独的 `crud-config-set` 拥有者,而自动化器拒绝嵌入式拥有者.

与 `useTransaction: false`,没有全移民的拥有者和接收回电 `undefined`独立 `set()` 仍然拥有自己的原子 `crud-config-set` 交易,所以多个配置写不是全或一无所有。 倒行刑总是使用被命名为"迁移"的主人.

### 创建迁移文件

创建带有所需结构的迁移文件 :

```typescript
// migrations/001-initial-app-config.migration.ts
import type { IConfigMigrationDefinition } from "@elsikora/nestjs-crud-config";
import type { CrudConfigService } from "@elsikora/nestjs-crud-config";
import type { EntityManager } from "typeorm";

export const initialAppConfigMigration: IConfigMigrationDefinition = {
 name: "001_initial_app_config",
 description: "Initialize basic application configuration",

 async up(configService: CrudConfigService, entityManager?: EntityManager): Promise<void> {
  // Create application settings
  await configService.set({
   section: "app-settings",
   name: "APP_NAME",
   value: "My Application",
   description: "Application name",
   environment: "default",
   eventManager: entityManager,
  });

  await configService.set({
   section: "app-settings",
   name: "APP_VERSION",
   value: "1.0.0",
   description: "Application version",
   environment: "default",
   eventManager: entityManager,
  });

  // Create API settings
  await configService.set({
   section: "api-settings",
   name: "API_RATE_LIMIT",
   value: "100",
   description: "API rate limit per minute",
   environment: "default",
   eventManager: entityManager,
  });
 },

 async down(configService: CrudConfigService, entityManager?: EntityManager): Promise<void> {
  // Rollback: remove configurations created by this migration
  const configurationsToRemove = [
   { name: "APP_NAME", section: "app-settings" },
   { name: "APP_VERSION", section: "app-settings" },
   { name: "API_RATE_LIMIT", section: "api-settings" },
  ];

  for (const config of configurationsToRemove) {
   try {
    await configService.delete({
     section: config.section,
     name: config.name,
     environment: "default",
     eventManager: entityManager,
    });
   } catch (error) {
    // Expected if config was never created
    console.warn(`Failed to delete config ${config.section}:${config.name} during rollback`);
   }
  }
 },
};
```

### 特定环境移徙

创建在不同环境中工作的迁移:

```typescript
// migrations/002-environment-specific-config.migration.ts
export const environmentSpecificConfigMigration: IConfigMigrationDefinition = {
 name: "002_environment_specific_config",
 description: "Environment-specific configuration settings",

 async up(configService: CrudConfigService, entityManager?: EntityManager): Promise<void> {
  const environments = ["development", "staging", "production"];

  for (const env of environments) {
   // Environment-specific debug settings
   await configService.set({
    section: "app-settings",
    name: "DEBUG_MODE",
    value: env === "development" ? "true" : "false",
    description: "Enable debug mode",
    environment: env,
    eventManager: entityManager,
   });

   // Environment-specific API limits
   const rateLimits = {
    development: "1000",
    staging: "500",
    production: "100",
   };

   await configService.set({
    section: "api-settings",
    name: "API_RATE_LIMIT",
    value: rateLimits[env],
    description: "API rate limit per minute",
    environment: env,
    eventManager: entityManager,
   });
  }
 },

 async down(configService: CrudConfigService, entityManager?: EntityManager): Promise<void> {
  const environments = ["development", "staging", "production"];
  const configurationsToRemove = [
   { name: "DEBUG_MODE", section: "app-settings" },
   { name: "API_RATE_LIMIT", section: "api-settings" },
  ];

  for (const config of configurationsToRemove) {
   for (const environment of environments) {
    try {
     await configService.delete({
      section: config.section,
      name: config.name,
      environment: environment,
      eventManager: entityManager,
     });
    } catch (error) {
     console.warn(
      `Failed to delete config ${config.section}:${config.name}:${environment} during rollback`,
     );
    }
   }
  }
 },
};
```

### 高级迁移配置

配置带有自定义选项的迁移 :

```typescript
CrudConfigModule.registerAsync({
 imports: [ConfigModule],
 inject: [ConfigService],
 useFactory: async (configService: ConfigService) => ({
  environment: configService.get("NODE_ENV", "development"),

  migrationOptions: {
   isEnabled: true,
   shouldRunOnStartup: true,
   useTransaction: true,
   stuckMigrationTimeoutMinutes: 60, // Custom timeout

   migrations: [
    initialAppConfigMigration,
    environmentSpecificConfigMigration,
    // Add more migrations in order
   ],
  },

  // Other dynamic options...
 }),
 // Static options for entities and controllers
 staticOptions: {
  migrationEntityOptions: {
   tableName: "my_migrations", // Custom table name must be in staticOptions
   maxNameLength: 256,
  },
  controllersOptions: {
   section: { isEnabled: true },
   data: { isEnabled: true },
  },
 },
});
```

### 移徙最佳做法

1.  **命名公约**: 使用带有序列号的描述性名称
    
    -   ✅ `001_initial_app_config`
    -   ✅ `002_add_feature_flags`
    -   ❌ `migration1`, (中文(简体) ), `config_setup`
2.  **重试安全性**: 使用 `set()` 作为配置密钥的更新
    
    ```typescript
    await configService.set({ eventManager: entityManager, ...properties });
    ```
    
3.  **处理错误**: 总是优雅地处理错误
    
    ```typescript
    try {
     await configService.set({ eventManager: entityManager, ...properties });
    } catch (error) {
     console.error("Migration failed:", error);
     throw error; // Re-throw to mark migration as failed
    }
    ```
    
4.  **回滚支持**: 总是执行 `down` 方法
    
    ```typescript
    async down(configService: CrudConfigService, entityManager?: EntityManager): Promise<void> {
      // Implement rollback logic
    }
    ```
    
5.  **环境意识**: 使用特定环境配置
    
    ```typescript
    const currentEnv = process.env.NODE_ENV || "development";
    await configService.set({
     eventManager: entityManager,
     environment: currentEnv,
     // ... other options
    });
    ```
    

### 移徙监测

使用日志监视迁移执行 :

```typescript
import { EConfigMigrationStatus } from "@elsikora/nestjs-crud-config";

@Injectable()
export class MigrationMonitorService {
 constructor(private readonly migrationService: ConfigMigrationService) {}

 async getMigrationStatus(): Promise<void> {
  const migrations = await this.migrationService.getExecutedMigrations();

  const completed = migrations.filter((m) => m.status === EConfigMigrationStatus.COMPLETED);
  const failed = migrations.filter((m) => m.status === EConfigMigrationStatus.FAILED);
  const stuck = migrations.filter((m) => m.status === EConfigMigrationStatus.STUCK);

  console.log(
   `Migrations - Completed: ${completed.length}, Failed: ${failed.length}, Stuck: ${stuck.length}`,
  );
 }

 async getFailedMigrations(): Promise<IConfigMigration[]> {
  const migrations = await this.migrationService.getExecutedMigrations();
  return migrations.filter((m) => m.status === EConfigMigrationStatus.FAILED);
 }
}
```

### 测试移民

测试您在不同环境中的迁移 :

```typescript
describe("Initial App Config Migration", () => {
 let configService: CrudConfigService;
 let migration: IConfigMigrationDefinition;

 beforeEach(async () => {
  // Setup test environment
  migration = initialAppConfigMigration;
 });

 it("should create required configurations", async () => {
  await migration.up(configService);

  const appName = await configService.get({
   section: "app-settings",
   name: "APP_NAME",
   environment: "default",
  });

  expect(appName.value).toBe("My Application");
 });

 it("should rollback configurations", async () => {
  await migration.up(configService);
  await migration.down(configService);

  await expect(
   configService.get({
    section: "app-settings",
    name: "APP_NAME",
    environment: "default",
   }),
  ).rejects.toThrow();
 });
});
```

## API 文档

该模块会自动生成 REST API 端点, 并带有自定义路径 :

### 配置区域( 默认 ): `/config/section`(中文(简体) )

-   `GET /config/section` - 列出所有章节
-   `POST /config/section` - 创建一个新的部分
-   `GET /config/section/:id` - 获取部分的ID
-   `PUT /config/section/:id` - 更新部分
-   `DELETE /config/section/:id` - 删除一节

**请求 POST/PUT 的正文 :**

```json
{
 "name": "api-settings",
 "description": "API configuration settings"
}
```

### 配置数据( 默认 ): `/config/data`(中文(简体) )

-   `GET /config/data` - 列出所有配置数据
-   `POST /config/data` - 创建新配置
-   `GET /config/data/:id` - 由ID进行配置
-   `PUT /config/data/:id` - 更新配置
-   `DELETE /config/data/:id` - 删除配置

**请求 POST/PUT 的正文 :**

```json
{
 "name": "API_KEY",
 "value": "your-secret-key",
 "environment": "production",
 "description": "Production API key",
 "isEncrypted": true,
 "section": { "id": "section-uuid-here" }
}
```

### 自定义 API 端点

```typescript
CrudConfigModule.register({
 controllersOptions: {
  section: {
   properties: {
    path: "api/v1/settings/sections",
    name: "CustomSectionController",
    swagger: {
     tags: ["Configuration Sections"],
    },
   },
  },
  data: {
   properties: {
    path: "api/v1/settings/data",
    routes: {
     DELETE: { generation: { isEnabled: false } }, // Disable deletion
    },
   },
  },
 },
});
```

使用自动化路由选项 `generation.isEnabled` 用于路由生成。 关系加载使用类型ORM `relationLoadStrategy` 数值(`"query"` 或者说 `"join"`); 内置配置数据段关系使用 `"query"`。 。 。 .

## 数据库Schema

该模块创建了两个主要表格,其默认结构如下:

### 配置区域表 (E)`config_section`(中文(简体) )

```sql
CREATE TABLE config_section (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  name VARCHAR(128) NOT NULL UNIQUE,
  description VARCHAR(512),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

### 配置数据表( E)`config_data`(中文(简体) )

```sql
CREATE TABLE config_data (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  name VARCHAR(128) NOT NULL,
  value VARCHAR(8192) NOT NULL,
  environment VARCHAR(64) NOT NULL,
  description VARCHAR(512),
  is_encrypted BOOLEAN DEFAULT FALSE,
  section_id UUID NOT NULL REFERENCES config_section(id) ON DELETE CASCADE,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  UNIQUE(name, environment, section_id)
);
```

## 高级配置

### 加密支持

该模块为敏感配置值提供内置的AES-256-GCM加密:

```typescript
// Enable encryption with bounded derived-key reuse for repeated uncached reads
CrudConfigModule.register({
 cacheOptions: { isEnabled: false },
 encryptionOptions: {
  isEnabled: true,
  encryptionKey: process.env.CONFIG_ENCRYPTION_KEY, // 32+ character key
  derivedKeyCacheMaxEntries: 64,
 },
});

// When encryption is enabled, all values are encrypted automatically
await configService.set({
 section: "database",
 name: "DB_PASSWORD",
 value: "my-secret-password",
});

// Retrieve and decrypt automatically
const config = await configService.get({
 section: "database",
 name: "DB_PASSWORD",
 useCache: false,
});

console.log(config.value); // Automatically decrypted value
console.log(config.isEncrypted); // true
```

`encryptionOptions.derivedKeyCacheMaxEntries` 使用 `lru-cache`关闭它或设置它 `0` 以禁用再利用; 正安全整数使其得以使用。 同一选项可通过 `registerAsync()`。 。 。 .

此缓存在进程内存中保留了衍生的加密密钥,而不是配置值. 与 `useCache: false`,每个读取器仍然获取当前数据库值,每个解密调用AES-GCM认证所提供的密码文本。 只有成功的解密输入或促进缓存条目。 用不同的加密密钥来解密受影响的密钥缓冲器。 加密存储格式和同步加密API不变.

### 交易和复制保护

`CrudConfigService.set()` 没有调用时, 拥有一个名为自动化的交易 `eventManager`当迁移时,所有生成的配置科和配置数据服务业务都加入了同一交易.

包裹不需要消费者 `EventEmitterModule` 接线 配置数据独有性由整个数据库执行 `name`, (中文(简体) ), `environment`,以及 `section`; 自动化人映射一个相冲突生成的创建或更新到 `409 CONFIGDATA_DUPLICATE_KEY`。将特定应用程序的验证或审计放入应用程序服务/生命周期层,而不是包放入前事件.

### 无头模式( 没有控制器)

```typescript
CrudConfigModule.register({
 controllersOptions: {
  section: { isEnabled: false },
  data: { isEnabled: false },
 },
});
```

这是完美的:

-   仅需要方案获取的背景服务
-   通过信件队列管理配置的微服务
-   带有自定义 GraphQL 或 gRPC 接口的应用程序

### 与多种环境合作

```typescript
// multi-env.service.ts
@Injectable()
export class MultiEnvironmentService {
 constructor(private readonly configService: CrudConfigService) {}

 async setupEnvironmentConfigs() {
  const environments = ["development", "staging", "production"];

  for (const env of environments) {
   await this.configService.set({
    section: "database",
    name: "DATABASE_URL",
    environment: env,
    value: `postgres://localhost:5432/${env}_db`,
    description: `Database URL for ${env} environment`,
   });
  }
 }
}
```

## \* 路线图

| 任务/ 特性 | 状态 |
| --- | --- |
| 核心动态实体系统 | 完毕 |
| TypeORM 与所有数据库的整合 | 完毕 |
| 等级配置(区/数据) | 完毕 |
| 使用 REST API 的 CRUD 操作 | 完毕 |
| 斯瓦格/ OpenAPI 文档 | 完毕 |
| 多种环境支助 | 完毕 |
| 已命名的自动化交易所有权 | 完毕 |
| 带有 TTL 的缓存系统 | 完毕 |
| 自定义表格名称和前缀 | 完毕 |
| 审定和制约因素 | 完毕 |
| NestJS CRUD 自动化器集成 | 完毕 |
| 脚本接口和类型 | 完毕 |
| AES-256-GCM 加密支持 | 完毕 |
| Async 模块注册 | 完毕 |
| 自动分区创建 | 完毕 |
| 图QL API 端点 | 执行中 |
| 配置版本和历史 | 执行中 |
| 基于角色的出入控制 | 执行中 |
| 配置模板和继承 | 执行中 |
| 通过 WebSocket 实时配置更新 | 执行中 |
| 配置验证计划 | 执行中 |
| 批量进出口功能 | 执行中 |
| 配置 diff 和合并工具 | 执行中 |
| 审计记录和变更跟踪 | 执行中 |
| 配置备份并恢复 | 执行中 |
| 与外部秘密管理人员合并 | 执行中 |

## 问 题

### 支持哪些数据库?

该模块支持TypeORM支持的任何数据库,包括:

-   **邮递SQL** - 建议的生产
-   **MySQL/马里亚DB** - 网络应用程序的流行选择
-   **SQL 点** - 适合开发和测试(TypeORM 1驱动程序) `better-sqlite3`(中文(简体) )
-   **微软 SQL 服务器** - 企业数据库支助
-   **甲骨文** - 企业级数据库
-   **蒙戈DB** - 无SQL文档数据库
-   **鸡尾酒** - 分布式SQL数据库

### 这与环境变量有何比较?

虽然环境变量对于简单的配置来说很大,但本模块提供:

-   **数据库的持久性** - 在容器重启后幸存的配置
-   **运行时间更新** - 不重新部署而改变配置
-   **等级组织** - 组相关配置
-   **多种环境支助** - 从一个地方管理去除/储存/记录
-   **加密支持** - 安全敏感数据
-   **(原始内容存档于2013-10-12) (英语). REST API** - 方案管理配置
-   **审计线索** - 音轨配置变化

### 我能从环境变量中迁移吗?

没错! 您可以在应用程序启动期间通过程序设置配置轻松地迁移 :

```typescript
async function migrateFromEnvVars() {
 const configs = [
  { section: "database", name: "DATABASE_URL", value: process.env.DATABASE_URL },
  { section: "api", name: "API_KEY", value: process.env.API_KEY },
  // ... more configurations
 ];

 for (const config of configs) {
  await configService.set(config);
 }
}
```

### 我如何处理敏感的配置数据?

该模块提供内置的AES-256-GCM加密支持:

```typescript
CrudConfigModule.register({
 encryptionOptions: {
  isEnabled: true,
  encryptionKey: process.env.CONFIG_ENCRYPTION_KEY,
 },
});
```

敏感值在存储前自动加密,被检索后解密.

### 我能用这个微服务吗?

当然 该模块对于微服务架构是完美的:

-   **集中配置** - 所有服务可以共享相同的配置数据库
-   **特定服务科** - 按服务组织配置
-   **环境隔离** - 单独的去除/固定/程序配置
-   **动态更新** - 不重启服务的更新配置

### 我如何定制表格名称和字段大小?

该模块提供了广泛的定制选项:

```typescript
CrudConfigModule.register({
 entityOptions: {
  tablePrefix: "myapp_",
  timestampColumnType: "timestamptz",
  configSection: {
   tableName: "configuration_sections",
   maxNameLength: 256,
   maxDescriptionLength: 1024,
  },
  configData: {
   tableName: "configuration_values",
   maxValueLength: 16384, // 16KB values
   maxEnvironmentLength: 128,
   maxNameLength: 256,
   maxDescriptionLength: 1024,
  },
 },
});
```

`timestampColumnType` 适用于本节所有九个时间栏、数据和移徙实体。 默认为 `Date`,哪个 TypeORM 映射到每个驱动程序的时间戳类型 : `timestamp` 关于PostgreSQL和 `datetime` 在MySQL, MariaDB, SQLite 上 (中文(简体) )`better-sqlite3`)和SQL.js,因此默认实体对每个实体都工作. 设置特定驱动程序类型, 如 `"timestamptz"` 用于 PostgreSQL ,只有在应用程序需要时。 为现有的数据库修改它仍然需要相应的计划迁移.

### 如果数据库不可用怎么办?

模块包括缓存处理临时数据库中断:

-   **内存缓存** - 最近访问的配置被缓存
-   **可配置 TTL** - 控制缓存配置的时间
-   **严重退化** - 数据库不可用时返回到缓存值

### 我能用这个吗?

没错! 该模块支持禁用控制器的"无头模式":

```typescript
CrudConfigModule.register({
 controllersOptions: {
  section: { isEnabled: false },
  data: { isEnabled: false },
 },
});
```

### 准备好生产了吗?

没错! 该模块的建造考虑到了生产用途:

-   **类型安全** - 完整类型脚本支持防止运行时间出错
-   **作战测试** - 以已证实的技术(NestJS、TypeORM)建造
-   **可缩放** - 企业数据库方面的工作
-   **安全** - 内置加密和验证
-   **可观察** - 综合伐木和监测钩

## 许可证

这个项目的许可证根据 **MIT 许可证**

版权(c) 2025 Elsi Kora

特此准许任何人免费获得本软件和相关文件文件("软件")的副本,不受限制地在软件中进行交易,包括不受限制地享有软件的使用、复制、修改、合并、出版、分发、分版和(或)销售的权利,并允许软件获得者这样做,但须符合下列条件: 1

上述版权通知和许可通知应载入软件的所有副本或大部分.

软件是提供的"AS IS", 没有任何种类的恐惧, 释放或被卷入, 包括但不限制在 危机的保障, 证明一个特定的目的和无关。 任何索赔、索赔或其他负债,无论是合同、交易或其他行为,产生于、产生于或涉及软件或软件的使用或其他交易的行为,都不得作为担保.

## 常见问题

### @elsikora/nestjs-crud-config 是什么？

通过数据库存储 NestJS 应用程序配置

### 如何安装 @elsikora/nestjs-crud-config？

在项目目录运行 npm install @elsikora/nestjs-crud-config，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：lodash（^4\.18\.1）、fastify（^5\.12\.7）、typeorm（^1\.1\.2）、@nestjs/core（^12\.3\.2）、@nestjs/common（^12\.3\.2）、@nestjs/swagger（^12\.0\.0）、@nestjs/typeorm（^12\.0\.1）、class-validator（^0\.15\.1）、@nestjs/passport（^12\.0\.0）、@nestjs/throttler（^6\.7\.1）、class-transformer（^0\.5\.1）、@nestjs/platform-fastify（^12\.3\.2）、@elsikora/nestjs-crud-automator（^5\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @elsikora/nestjs-crud-config 支持 TypeScript 吗？

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

### @elsikora/nestjs-crud-config 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @elsikora/nestjs-crud-config 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js ^22\.13\.0 \|\| \>=24\.11\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @elsikora/nestjs-crud-config 可以商用吗？

@elsikora/nestjs-crud-config 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @elsikora/nestjs-crud-config 的下载量有多少？

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

### @elsikora/nestjs-crud-config 还在维护吗？

最新版本 5\.1\.0 发布于 2026/11/04（9 天前）；至今共发布 49 个版本，其中过去 12 个月发布了 35 个；首次发布于 2025/07/14。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

