@elsikora/nestjs-typeorm-aws-connector

中文文档
3.0.0发布于 2026/11/03MITTypeScriptES Module近 30 天下载 6253

NestJS TypeORM connector for AWS SSM and Secrets Manager with bounded credential rotation

原始使用文档
文档目录30 节
  1. 💡 Highlights
  2. 📚 Table of Contents
  3. 📖 Description
  4. Real-World Use Cases
  5. 🛠️ Tech Stack
  6. 🚀 Features
  7. 🏗 Architecture
  8. System Architecture
  9. Data Flow
  10. 📁 Project Structure
  11. 📋 Prerequisites
  12. 🛠 Installation
  13. Verify Installation
  14. 💡 Usage
  15. Prerequisites: Register Parameter Store Config Module
  16. Basic Usage: Static Registration
  17. Custom SSM Lookups
  18. Local Development: Raw Value Overrides
  19. Enabling Credential Rotation
  20. Shutdown Lifecycle
  21. Async Registration with Factory
  22. Multiple Database Modules In One App
  23. Value Resolution Priority
  24. Migrating to 3.0
  25. Migrating from 1.x
  26. 🛣 Roadmap
  27. ❓ FAQ
  28. ❓ Frequently Asked Questions
  29. 🔒 License
  30. 🙏 Acknowledgments

project-logo

🔌 NestJS-TypeORM-AWS-Connector

Seamlessly bridge TypeORM with AWS Parameter Store & Secrets Manager for secure, auto-rotating database connections in NestJS

ElsiKora TypeScript NestJS Node.js AWS Rollup ESLint Prettier GitHub Actions npm PostgreSQL MySQL

💡 Highlights

  • 🔐 Zero-credential codebase — resolves all database config from AWS SSM Parameter Store & Secrets Manager at runtime
  • ♻️ Bounded automatic credential rotation with health checks, transaction affinity, and at most one retiring pool
  • ⏱️ Bounded shutdown with explicit drain timeout, aggregate failure, and package-neutral lifecycle events
  • 🏗️ Split-source architecture — infra teams own host/port/secrets, app teams own pool/timeout/sync settings independently
  • 📦 ES module build with extension-qualified TypeScript declarations for NestJS 12 and TypeORM 1, loadable from CommonJS through require(esm)

📚 Table of Contents

📖 Description

NestJS-TypeORM-AWS-Connector is a production-grade NestJS module that eliminates the pain of managing database configuration in AWS-hosted applications. Instead of hardcoding credentials or juggling environment variables, this connector resolves your entire TypeORM DataSourceOptions from AWS Systems Manager Parameter Store and AWS Secrets Manager — with built-in credential rotation.

In modern cloud-native architectures, database credentials are rotated regularly for security compliance. Traditional approaches break connections during rotation, causing downtime. This connector avoids destructive mid-run DataSource teardown by validating a replacement connection first, promoting the new driver for future query runners, and retiring the previous pool only after existing query runners drain. It permits at most one current and one retiring generation; later intervals defer instead of growing the pool count.

Real-World Use Cases

  • ECS Fargate Microservices: Deploy NestJS APIs on Fargate where credentials are managed by AWS Secrets Manager with automatic rotation policies — the connector picks up fresh credentials without redeployment.
  • Multi-Environment Deployments: Use the same codebase across dev, staging, and production — each environment resolves its own database configuration from namespaced SSM parameters.
  • Aurora PostgreSQL / RDS MySQL: Connect to managed AWS databases where infrastructure teams control host, port, and secret references via Parameter Store, while application teams only configure entities and behavior.
  • Compliance-First Organizations: Meet SOC2 and PCI-DSS requirements by never storing credentials in code, environment files, or container images.

The connector uses a split-source model: infrastructure-owned parameters (host, port, secret ID) live in canonical AWS namespaces, while application-owned settings (pool size, timeouts, sync behavior) live in your app's namespace. Raw value overrides let you bypass SSM entirely for local development.

🛠️ Tech Stack

CategoryTechnologies
LanguageTypeScript
RuntimeNode.js
FrameworkNestJS
ORMTypeORM
Cloud ServicesAWS SSM Parameter Store, AWS Secrets Manager
Build ToolRollup
LintingESLint, Prettier
CI/CDGitHub Actions, Semantic Release
Package Managernpm

🚀 Features

  • ✨ AWS Parameter Store Integration — Resolves database host, port, name, type, and tuning parameters from structured SSM paths with hierarchical namespace support
  • ✨ AWS Secrets Manager Integration — Fetches username/password credentials from Secrets Manager with proper error handling for missing or malformed secrets
  • ✨ Bounded Credential Rotation — Validates a replacement before promotion and permits only the current pool plus one retiring pool
  • ✨ Transaction Affinity — Query runners and manager-bound transactions stay on the generation where they started
  • ✨ Bounded Shutdown — Stops new work, waits for active generations, then reports timeout or close failures as one aggregate error
  • ✨ Rotation Events — Reports deferred rotation, retired generations, and drain timeouts without a Nest EventEmitter dependency
  • ✨ Emergency Recovery — After 3 consecutive rotation failures, automatically retries recovery without destructively tearing down the live DataSource
  • ✨ Connection Health Validation — Validates both existing and new connections with SELECT 1 queries before and after rotation
  • ✨ Split-Source Configuration Model — Infrastructure-owned settings (host, port, secret-id) use canonical AWS namespaces; app-owned settings use your module namespace
  • ✨ Raw Value Overrides — Bypass SSM entirely for any field by providing direct values — perfect for local development with host: '127.0.0.1'
  • ✨ Hierarchical Lookup Resolution — Field-level SSM lookup → canonical defaults → ssmLookupDefaults → ParameterStoreConfigModule defaults
  • ✨ ES Module Build — Ships ES modules with extension-qualified TypeScript declarations and source maps; CommonJS applications load it through require(esm)
  • ✨ Bounded Error Model — Static diagnostics expose only a validated error type and optional SQLSTATE while retaining the original failure as cause
  • ✨ NestJS 12 and TypeORM 1 — Peers @nestjs/common and @nestjs/core >=12.3.2 <13 and typeorm >=1.1.2 <2
  • ✨ Sync & Async Registration — Use register() for static config or registerAsync() with factory functions for dynamic configuration

🏗 Architecture

System Architecture

flowchart TD
    appModule[AppModule] --> paramStore[ParameterStoreConfigModule]
    appModule --> connectorModule[TypeOrmAwsConnectorModule]
    connectorModule --> connectorService[TypeOrmAwsConnectorService]
    connectorModule --> rotatorService[RotatorService]
    connectorModule --> scheduleModule[ScheduleModule]
    connectorService --> paramStoreService[ParameterStoreConfigService]
    connectorService --> configService[NestJS ConfigService]
    connectorService --> ssmParameterStore[AWS SSM Parameter Store]
    connectorService --> secretsManager[AWS Secrets Manager]
    rotatorService --> connectorService
    rotatorService --> dataSource[TypeORM DataSource]
    connectorModule --> typeOrmModule[TypeOrmModule.forRootAsync]

Data Flow

sequenceDiagram
    participant App as NestJS App
    participant Connector as ConnectorService
    participant SSM as AWS Parameter Store
    participant SM as AWS Secrets Manager
    participant TypeORM as TypeORM DataSource
    participant Rotator as RotatorService

    App->>Connector: getTypeOrmOptions()
    Connector->>SSM: Resolve host, port, dbName, type
    SSM-->>Connector: Parameter values
    Connector->>SSM: Resolve secretId
    SSM-->>Connector: Secret ID
    Connector->>SM: GetSecretValue(secretId)
    SM-->>Connector: username + password
    Connector->>SSM: Resolve optional tuning params
    SSM-->>Connector: poolSize, timeouts, etc.
    Connector-->>App: DataSourceOptions
    App->>TypeORM: Initialize DataSource

    loop Every rotation interval
        Rotator->>TypeORM: Validate connection health
        Rotator->>Connector: getTypeOrmOptions()
        Connector->>SM: Fetch fresh credentials
        SM-->>Connector: New username + password
        Rotator->>TypeORM: Initialize replacement DataSource
        Rotator->>TypeORM: Verify with SELECT 1
        Rotator->>TypeORM: Promote replacement driver for future query runners
        Rotator->>TypeORM: Retire previous pool after active query runners drain
    end

📁 Project Structure

Click to expand
NestJS-TypeORM-AWS-Connector/
├── .github/
│   ├── workflows/
│   │   ├── mirror-docs-to-docviewer.yml
│   │   ├── mirror-to-codecommit.yml
│   │   ├── qodana-quality-scan.yml
│   │   ├── release.yml
│   │   ├── snyk-security-scan.yml
│   │   └── test.yml
│   └── dependabot.yml
├── docs/
│   ├── api-reference/
│   ├── getting-started/
│   └── guides/
├── scripts/
│   ├── test/
│   │   └── consumer-smoke.mjs
│   └── check-declaration-imports.cjs
├── src/
│   ├── modules/
│   │   └── typeorm-aws-connector/
│   ├── shared/
│   │   ├── constant/
│   │   ├── enum/
│   │   ├── interface/
│   │   ├── provider/
│   │   └── type/
│   └── index.ts
├── test/
│   ├── consumer/
│   └── typeorm-aws-connector/
├── CHANGELOG.md
├── commitlint.config.js
├── eslint.config.js
├── LICENSE
├── lint-staged.config.js
├── nest-cli.json
├── package-lock.json
├── package.json
├── prettier.config.js
├── README.md
├── release.config.js
├── rollup.config.js
├── tsconfig.build.json
└── tsconfig.json

📋 Prerequisites

  • Node.js ^22.13.0 || >=24.11.0
  • npm >= 9.0.0
  • @nestjs/common and @nestjs/core >=12.3.2 <13
  • @nestjs/config >=12.0.1 <13
  • typeorm >=1.1.2 <2
  • @elsikora/nestjs-aws-parameter-store-config ^3.0.0-dev.1 (the 3.0 prereleases and every stable 3.x)
  • @aws-sdk/client-ssm >=3.535.0 <4
  • AWS credentials configured (IAM role, environment variables, or AWS CLI profile)

🛠 Installation

These source docs describe Connector 3. ^3.0.0-0 selects a 3.0 prerelease and later stable 3.x releases.

# Install the connector and its peer dependencies
npm install @elsikora/nestjs-typeorm-aws-connector@^3.0.0-0 @elsikora/nestjs-aws-parameter-store-config@^3.0.0-0 @aws-sdk/client-ssm @nestjs/common@^12 @nestjs/core@^12 @nestjs/config@^12 @nestjs/typeorm@^12 typeorm@^1

The connector installs @aws-sdk/client-secrets-manager and @nestjs/schedule as direct dependencies. @elsikora/nestjs-aws-parameter-store-config and @nestjs/config are peers: the connector injects ParameterStoreConfigService and ConfigService, so it must share the application's copy of both.

Verify Installation

npm ls @elsikora/nestjs-typeorm-aws-connector @elsikora/nestjs-aws-parameter-store-config @nestjs/config typeorm

💡 Usage

Prerequisites: Register Parameter Store Config Module

Before using the connector, register ParameterStoreConfigModule from @elsikora/nestjs-aws-parameter-store-config. Register ConfigModule as global: the connector injects ConfigService inside its own module:

import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { ENamespace, ParameterStoreConfigModule } from "@elsikora/nestjs-aws-parameter-store-config";

@Module({
    imports: [
        ConfigModule.forRoot({ isGlobal: true }),
        ParameterStoreConfigModule.registerAsync({
            imports: [ConfigModule],
            inject: [ConfigService],
            useFactory: (configService: ConfigService) => ({
                application: configService.getOrThrow<string>("APPLICATION"),
                config: { region: configService.getOrThrow<string>("AWS_REGION") },
                environment: configService.getOrThrow<string>("ENVIRONMENT"),
                instanceName: "my-api",
                namespace: ENamespace.AWS_ECS_FARGATE,
                shouldDecryptParameters: true,
            }),
        }),
    ],
})
export class AppModule {}

Basic Usage: Static Registration

import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { TypeOrmAwsConnectorModule, TypeOrmAwsConnectorService } from "@elsikora/nestjs-typeorm-aws-connector";
import { UserEntity } from "./entities/user.entity";

@Module({
    imports: [
        TypeOrmModule.forRootAsync({
            // Register the connector inside the TypeORM factory module so the factory can inject its service
            imports: [
                TypeOrmAwsConnectorModule.register({
                    entities: [UserEntity],
                    rotation: {
                        isEnabled: false,
                    },
                }),
            ],
            inject: [TypeOrmAwsConnectorService],
            useFactory: async (connectorService: TypeOrmAwsConnectorService) => connectorService.getTypeOrmOptions(),
        }),
    ],
})
export class DatabaseModule {}

The connector resolves DataSourceOptions; TypeOrmModule remains the owner that initializes the live DataSource. Set rotation.isEnabled: false for one-shot processes, or see Enabling Credential Rotation for long-running services.


Custom SSM Lookups

Override where specific fields are resolved from in Parameter Store:

import { ENamespace } from "@elsikora/nestjs-aws-parameter-store-config";
import { TypeOrmAwsConnectorModule } from "@elsikora/nestjs-typeorm-aws-connector";

TypeOrmAwsConnectorModule.register({
    entities: [UserEntity],
    ssmLookupDefaults: {
        instanceName: "my-api",
        namespace: ENamespace.AWS_ECS_FARGATE,
    },
    ssmLookups: {
        secretId: {
            instanceName: "database",
            namespace: ENamespace.AWS_SECRETS_MANAGER,
            path: ["secret-id"],
        },
        host: {
            instanceName: "aurora-postgres",
            namespace: ENamespace.AWS_RDS,
            path: ["host"],
        },
        port: {
            instanceName: "aurora-postgres",
            namespace: ENamespace.AWS_RDS,
            path: ["port"],
        },
        rotationShutdownDrainTimeoutMs: {
            path: ["database", "rotation", "shutdown-drain-timeout-ms"],
        },
    },
});

Local Development: Raw Value Overrides

Bypass AWS entirely for local development:

import { EDatabaseType } from "@elsikora/nestjs-typeorm-aws-connector";

TypeOrmAwsConnectorModule.register({
    entities: [UserEntity],
    host: "127.0.0.1",
    port: 5432,
    username: "local-user",
    password: "local-password",
    databaseName: "mydb",
    type: EDatabaseType.POSTGRES,
});

Enabling Credential Rotation

Enable automatic credential rotation for long-running services:

import { Logger } from "@nestjs/common";
import { ETypeOrmAwsConnectorRotationEvent, TypeOrmAwsConnectorModule } from "@elsikora/nestjs-typeorm-aws-connector";

const rotationLogger = new Logger("DatabaseRotation");

TypeOrmAwsConnectorModule.register({
    entities: [UserEntity],
    rotation: {
        isEnabled: true,
        intervalMs: 3_600_000, // Rotate every hour
        shutdownDrainTimeoutMs: 15_000,
        onEvent: (event) => {
            switch (event.type) {
                case ETypeOrmAwsConnectorRotationEvent.DRAIN_TIMEOUT: {
                    rotationLogger.error("Database rotation drain timed out", event);
                    break;
                }
                case ETypeOrmAwsConnectorRotationEvent.GENERATION_RETIRED: {
                    rotationLogger.log("Database generation retired", event);
                    break;
                }
                case ETypeOrmAwsConnectorRotationEvent.ROTATION_DEFERRED: {
                    rotationLogger.warn("Database rotation deferred", event);
                    break;
                }
            }
        },
    },
});

When rotation is enabled, shutdownDrainTimeoutMs is required and must be a positive integer. Provide it directly or through the canonical SSM path typeorm/rotation/shutdown-drain-timeout-ms; the connector does not invent a shutdown default.

The rotation service will:

  1. Validate current connection health
  2. Fetch fresh credentials from AWS Secrets Manager
  3. Create a replacement DataSource with schema synchronization, migrations, schema drop, and extension installation disabled
  4. Verify the replacement connection with a SELECT 1 query
  5. Promote the replacement driver for future query runners without destroying the live DataSource
  6. Keep query runners and manager-bound transactions on the generation where they started
  7. Defer later intervals until the one retiring generation drains and closes
  8. Attempt emergency recovery through the same bounded rotation gate after 3 consecutive failures

At most two database pools exist during rotation: the current generation and one retiring generation. Overlapping intervals coalesce instead of creating queued replacements.

onEvent is an optional, package-neutral observability callback. It can return void or Promise<void>; its returned promise is not awaited, and its synchronous body should stay small. It must not own correctness or database writes. Listener failures are logged only as a validated error type plus an optional SQLSTATE and are isolated from the rotation lifecycle. Event objects are frozen and contain no credentials.

The connector permanently sets TypeORM query logging to false. Foreign failure messages, stacks, SQL, parameters, driver payloads, credentials, lookup coordinates, profiles, IP addresses, and URLs are never copied into connector logs or wrapper messages. Wrapper errors retain the original failure as cause for explicit in-process handling.

EventMeaning
ROTATION_DEFERREDRotation was skipped because another rotation, retirement, or shutdown prevents promotion
GENERATION_RETIREDA current or retiring generation closed successfully
DRAIN_TIMEOUTActive work did not drain, or generation close did not settle, in time

Rotation is intended for long-lived services. For one-shot jobs, migrations, Bootstrap, or explicit CLI tasks, keep rotation.isEnabled disabled so the connector does not register a background interval.

Shutdown Lifecycle

Enable Nest shutdown hooks in long-running applications so SIGTERM reaches the connector:

const app = await NestFactory.create(AppModule);

app.enableShutdownHooks();
await app.listen(3000);

During shutdown, the connector removes its interval, refuses new query runners, waits up to shutdownDrainTimeoutMs for active work, and then closes the current, pending, and retiring generations. If drain or close does not settle, it emits DRAIN_TIMEOUT, performs best-effort cleanup, and rejects with one AggregateError; callers and orchestrators must treat that shutdown as unclean.

Drain and generation close each have a bounded phase, so the host termination budget must exceed approximately 2 × shutdownDrainTimeoutMs plus the surrounding Nest shutdown work and an operational margin.


Async Registration with Factory

TypeOrmAwsConnectorModule.registerAsync({
    imports: [ConfigModule],
    inject: [ConfigService],
    useFactory: (configService: ConfigService) => {
        const isRotationEnabled = configService.get<boolean>("DB_ROTATION_ENABLED", false);

        return {
            entities: [UserEntity],
            rotation: {
                intervalMs: configService.get<number>("DB_ROTATION_INTERVAL", 3_600_000),
                isEnabled: isRotationEnabled,
                ...(isRotationEnabled
                    ? {
                            shutdownDrainTimeoutMs: configService.getOrThrow<number>("DB_ROTATION_SHUTDOWN_DRAIN_TIMEOUT"),
                        }
                    : {}),
            },
        };
    },
});

Omit the raw shutdownDrainTimeoutMs property when the enabled service should resolve it from Parameter Store instead of ConfigService.


Multiple Database Modules In One App

Register the connector separately inside each Nest database module that owns a specific TypeORM connection. The connector module is scoped to that module registration, so multiple connector instances can safely coexist in one application.

import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { getDataSourceToken, TypeOrmModule } from "@nestjs/typeorm";
import { TypeOrmAwsConnectorModule, TypeOrmAwsConnectorService } from "@elsikora/nestjs-typeorm-aws-connector";
import { ProviderEntity } from "./entities/provider.entity";

@Module({
    imports: [
        TypeOrmModule.forRootAsync({
            imports: [
                TypeOrmAwsConnectorModule.registerAsync({
                    // Must match the name below so RotatorService binds to this DataSource
                    dataSourceToken: getDataSourceToken("provider"),
                    imports: [ConfigModule],
                    inject: [ConfigService],
                    useFactory: (configService: ConfigService) => ({
                        entities: [ProviderEntity],
                        poolSize: configService.get<number>("PROVIDER_DB_POOL_SIZE", 10),
                    }),
                }),
            ],
            inject: [TypeOrmAwsConnectorService],
            name: "provider",
            useFactory: async (connectorService: TypeOrmAwsConnectorService) => connectorService.getTypeOrmOptions(),
        }),
    ],
})
export class ProviderDatabaseModule {}

Use dataSourceToken when the connector's RotatorService should bind to a named TypeORM DataSource instead of the default connection token. Each registration owns an independent interval, generation state, and event callback.


Value Resolution Priority

For each configuration field, values are resolved in this order:

  1. Raw value override (provided directly in config)
  2. SSM Parameter Store lookup (via structured lookup)
  3. Built-in default (only for optional tuning fields like poolSize, connectionTimeoutMs)

Required fields (host, port, databaseName, type, secretId) throw explicit errors if not resolvable. When rotation resolves as enabled, rotation.shutdownDrainTimeoutMs is also required. Explicit rotation properties take priority over their structured SSM lookups.

Migrating to 3.0

3.0 moves the connector to NestJS 12 and TypeORM 1 and ships it as ES modules only. The configuration API, the canonical SSM lookup contract, the rotation lifecycle and the exported names do not change.

Requirement2.x3.0
Node.js>=20.0.0^22.13.0 || >=24.11.0
@nestjs/common, @nestjs/core^8 || ^9 || ^10 || ^11>=12.3.2 <13
@nestjs/configdependency ^4.0.3peer >=12.0.1 <13
typeorm^0.3.20>=1.1.2 <2
@elsikora/nestjs-aws-parameter-store-configdependency ^2.0.2peer ^3.0.0-dev.1
@aws-sdk/client-ssm^3.535.0>=3.535.0 <4 (same range)
Module formatESM and CommonJSESM only
  1. Upgrade Node.js, NestJS and TypeORM first. Applications on NestJS 11 or older, TypeORM 0.3 or Node.js 20 stay on 2.x.
  2. Install @elsikora/nestjs-aws-parameter-store-config 3 and @nestjs/config 12 in the application; they are no longer installed by the connector. npm ls must show one copy of each.
  3. Import only from the package root. dist/esm, dist/cjs and the require export condition are gone.

ES module applications import the package with moduleResolution set to bundler, node16 or nodenext; the declarations carry .js extensions on every relative import. CommonJS applications keep require(), which Node.js serves through require(esm) on every supported release. TypeScript with module: commonjs finds the types through the top-level types field with moduleResolution: node10 (TypeScript 6 then needs "ignoreDeprecations": "6.0"), and through exports without moduleResolution, which TypeScript 6 resolves as bundler. Native ES module builds such as the Nest CLI SWC builder type relations between entities that import each other as Relation<T>; otherwise startup fails with ReferenceError: Cannot access '...' before initialization.

Importing the package loads no .env file and writes nothing to the console. CI checks this, and runs ESM, CommonJS and SWC consumer apps against Postgres, on the packed tarball: with the latest release in each peer range, and on Node.js 22.13.0 with every peer at the lower bound of its range.

See the complete Migrating to 3.0 guide.

Migrating from 1.x

Connector 2.0 intentionally removes the unbounded rotation and force-only shutdown contract. Existing applications that enable rotation must add a positive rotation.shutdownDrainTimeoutMs, enable Nest shutdown hooks for process signals, and decide how to surface the new structured rotation events.

See the complete Migrating to 2.0 guide before upgrading.

🛣 Roadmap

Click to expand
Task / FeatureStatus
ES module build for NestJS 12 and TypeORM 1✅ Done
AWS Secrets Manager credential resolution✅ Done
Automatic credential rotation with staged driver promotion✅ Done
Bounded current-plus-one-retiring generation lifecycle✅ Done
Structured package-neutral rotation lifecycle events✅ Done
Emergency recovery after consecutive rotation failures✅ Done
Split-source configuration model (infra vs app namespaces)✅ Done
Raw value overrides for local development✅ Done
Async module registration with factory pattern✅ Done
Semantic release with prerelease channel✅ Done
Support for additional database types (e.g., MariaDB, CockroachDB)🚧 In Progress
Connection pool monitoring and metrics export🚧 In Progress
Read replica support with separate SSM lookups🚧 In Progress
Integration test suite with LocalStack🚧 In Progress

❓ FAQ

Click to expand

❓ Frequently Asked Questions

Q: Do I need AWS credentials to use this locally? A: No! Use raw value overrides to bypass AWS entirely during local development. Set host, port, username, password, databaseName, and type directly in the config.

Q: Which databases are supported? A: Currently PostgreSQL (EDatabaseType.POSTGRES) and MySQL (EDatabaseType.MYSQL). The type field is resolved from SSM or set directly.

Q: What happens if AWS Secrets Manager is unreachable during rotation? A: The rotation service catches the error, increments a failure counter, and logs only its validated error type and optional SQLSTATE. After 3 consecutive failures, it attempts an emergency recovery with a fresh replacement connection. Failed replacements are discarded, and the currently promoted pool stays in place until a later rotation succeeds.

Q: Can I use this without @elsikora/nestjs-aws-parameter-store-config? A: No. The connector depends on ParameterStoreConfigService.get() for SSM lookups. You must register ParameterStoreConfigModule first. However, if you provide raw values for all fields, SSM lookups won't actually be invoked.

Q: How does the split-source model work? A: Infrastructure-owned fields like host, port, and secretId default to canonical AWS namespaces (e.g., aws-rds/aurora-postgres). Application-owned fields like poolSize and connectionTimeoutMs use your app's namespace (e.g., aws-ecs-fargate/my-api). You can override any lookup.

Q: Which NestJS and TypeORM versions are supported? A: 3.x needs NestJS 12 (@nestjs/common and @nestjs/core >=12.3.2 <13) and TypeORM 1 (>=1.1.2 <2) on Node.js ^22.13.0 || >=24.11.0. Applications on NestJS 8–11 or TypeORM 0.3 stay on 2.x.

Q: Can a CommonJS application use the connector? A: Yes. The package is ES modules only, and require("@elsikora/nestjs-typeorm-aws-connector") loads it through Node.js require(esm), which every supported Node.js release has without a flag.

Q: How do I disable credential rotation? A: Don't set the rotation config, or explicitly set rotation.isEnabled: false. The RotatorService will skip interval registration entirely. This is the recommended mode for one-shot jobs, migrations, and other short-lived processes.

Q: What's the default rotation interval? A: 1 hour (3,600,000 ms). Override it via rotation.intervalMs or the SSM path typeorm/rotation/interval-ms.

Q: Is there a default shutdown drain timeout? A: No. Rotation-enabled services must provide a positive integer through rotation.shutdownDrainTimeoutMs or typeorm/rotation/shutdown-drain-timeout-ms. One-shot services with rotation disabled do not require it.

Q: Can several rotations create several old pools? A: No. The connector permits one current and at most one retiring generation. Further intervals emit ROTATION_DEFERRED until the retiring generation closes.

Q: What happens to a transaction during credential rotation? A: Its query runner remains attached to the generation where it started. New query runners use the promoted generation, and ordinary rotation waits for the old pool's runners to release without applying the shutdown timeout. Forced release after shutdownDrainTimeoutMs occurs only during process shutdown.

Q: Does onEvent use Nest EventEmitter? A: No. It is an optional callback in the rotation configuration. Use it to bridge structured events into your logger, metrics, or error reporting system without adding @nestjs/event-emitter.

🔒 License

This project is licensed under MIT.

🙏 Acknowledgments

  • NestJS — The progressive Node.js framework that makes building server-side applications a joy
  • TypeORM — The ORM that powers the database layer with decorator-based entity definitions
  • AWS SDK for JavaScript v3 — Modular AWS SDK used for SSM and Secrets Manager client operations
  • @elsikora/nestjs-aws-parameter-store-config — The Parameter Store config module that provides the structured lookup foundation
  • Semantic Release — Automated versioning and changelog generation
  • Rollup — Module bundler powering the ES module build output
  • Built with ❤️ by ElsiKora

Back to Top

版本与发布记录

@elsikora/nestjs-typeorm-aws-connector 共发布 26 个版本,首次发布于 2025/01/14;过去 12 个月发布了 18 个版本。

版本发布日期距今
3.0.0latest2026/11/0310 天前
3.0.0-dev.2beta2026/11/0310 天前
3.0.0-dev.12026/11/0211 天前
2.0.12026/09/012 个月前
2.0.1-dev.12026/09/012 个月前
2.0.02026/07/273 个月前

关于 @elsikora/nestjs-typeorm-aws-connector 的常见问题

@elsikora/nestjs-typeorm-aws-connector 是什么?

NestJS TypeORM connector for AWS SSM and Secrets Manager with bounded credential rotation

如何安装 @elsikora/nestjs-typeorm-aws-connector?

在项目目录运行 npm install @elsikora/nestjs-typeorm-aws-connector,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:typeorm(>=1.1.2 <2)、@nestjs/core(>=12.3.2 <13)、@nestjs/common(>=12.3.2 <13)、@nestjs/config(>=12.0.1 <13)、@aws-sdk/client-ssm(>=3.535.0 <4)、@elsikora/nestjs-aws-parameter-store-config(^3.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@elsikora/nestjs-typeorm-aws-connector 支持 TypeScript 吗?

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

@elsikora/nestjs-typeorm-aws-connector 支持 ESM 还是 CommonJS?

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

@elsikora/nestjs-typeorm-aws-connector 需要什么版本的 Node.js?

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

@elsikora/nestjs-typeorm-aws-connector 可以商用吗?

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

@elsikora/nestjs-typeorm-aws-connector 的下载量有多少?

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

@elsikora/nestjs-typeorm-aws-connector 还在维护吗?

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