npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@divami-labs/nestjs-api-connector

v0.0.1

Published

Enterprise-grade API Proxy and Transformation Framework for NestJS

Readme

🚀 NestJS API Connector

A configuration-driven API integration & transformation framework for NestJS.

npm version

nestjs-api-connector (formerly corrector) acts as an intelligent bridge between your application and external APIs. Instead of writing endless HTTP Services and DTOs, you define integrations in your database and manage transformations dynamically.


✨ Features

  • Dynamic Configuration: Define API endpoints, methods, and auth type in your DB.
  • Zero-Code Updates: Change target URLs or field mappings without redeploying code.
  • Robust Authentication: Supported strategies (Bearer, Basic, ApiKey, OAuth2) with strict database priority.
  • High Performance Transformation: Transform requests and responses using JSONPath or Custom Javascript with optimized array processing.
  • Standardized Responses: Consistent error handling (CLIENT_ERROR, TARGET_API_ERROR, INTERNAL_ERROR).
  • Database Agnostic: Built-in TypeORM support, easily adaptable to any repository.

📦 Installation

npm install nestjs-api-connector

🛠️ Usage

1. Database Setup

The library includes a database_init.sql file in the root directory. You can use this to initialize your PostgreSQL database.

  • Tables Created: connector_mappings_config
  • Columns: id, name, source_system, target_system, mapping_config, created_at, updated_at.

You can also create a Custom Table Name (see below).

2. Import Module in AppModule

A. Using TypeORM (Recommended)

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';
import { 
  ConnectorModule, 
  TypeOrmMappingRepository, 
  IntegrationMappingEntity 
} from 'nestjs-api-connector';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'postgres',
      entities: [IntegrationMappingEntity],
      synchronize: false, 
    }),

    ConnectorModule.forRootAsync({
      inject: [DataSource],
      useFactory: (dataSource: DataSource) => ({
        mappingRepository: new TypeOrmMappingRepository(
          dataSource.getRepository(IntegrationMappingEntity)
        ),
      }),
    }),
  ],
})
export class AppModule {}

B. Using Custom Table Name (Optional)

If you prefer a custom table name (e.g., my_custom_connectors), use the getMappingEntity utility:

import { getMappingEntity, TypeOrmMappingRepository } from 'nestjs-api-connector';

// 1. Create the entity class with your custom table name
const MyCustomEntity = getMappingEntity('my_custom_connectors');

@Module({
  imports: [
    // Register the custom entity in TypeORM
    TypeOrmModule.forFeature([MyCustomEntity]),
    
    ConnectorModule.forRootAsync({
      inject: [DataSource],
      useFactory: (dataSource: DataSource) => ({
        tableName: 'my_custom_connectors',
        mappingRepository: new TypeOrmMappingRepository(
          dataSource.getRepository(MyCustomEntity)
        ),
      }),
    }),
  ],
})
export class AppModule {}

C. Extending with Custom Fields (Extra Entity)

You can add extra business logic or auditing columns to your table while keeping the library functional. Just extend the base entity provided by the factory:

import { getMappingEntity } from 'nestjs-api-connector';
import { Entity, Column } from 'typeorm';

// 1. Get the base connector entity class
const BaseConnectorEntity = getMappingEntity('enterprise_connectors');

// 2. Extend it to add custom fields
@Entity('enterprise_connectors')
export class ExtendedConnectorEntity extends BaseConnectorEntity {
  @Column({ nullable: true })
  clientOwner: string;

  @Column({ default: 'PROD' })
  environment: string;

  @Column({ type: 'boolean', default: true })
  isActive: boolean;
}

// 3. Register as normal
@Module({
  imports: [
    TypeOrmModule.forFeature([ExtendedConnectorEntity]),
    ConnectorModule.forRootAsync({
      inject: [DataSource],
      useFactory: (dataSource: DataSource) => ({
        mappingRepository: new TypeOrmMappingRepository(
          dataSource.getRepository(ExtendedConnectorEntity)
        ),
      }),
    }),
  ],
})
export class AppModule {}

4. Built-in API Proxy

The framework automatically exposes a standardized endpoint: POST /connector/execute.

Sample Request Payload:

{
  "connectorKey": "get-products",
  "payload": { "id": 101 },
  "authConfig": {
    "authType": "BEARER_TOKEN",
    "config": { "token": "abc-123-token" }
  },
  "headerData": { "X-Custom-Source": "Mobile-App" },
  "queryParams": { "version": "v2" }
}

🔐 Authentication Standards

The framework ensures security by prioritizing Database Configuration over incoming request data.

| Auth Type | Config Fields required in DB/Request | Injection Method | | :--- | :--- | :--- | | BEARER_TOKEN | token | Authorization: Bearer <token> | | BASIC | username, password | Authorization: Basic <base64> | | API_KEY | keyName, keyValue | Custom header (e.g., x-api-key: val) | | OAUTH2_CLIENT_CREDENTIALS | tokenUrl, clientId, clientSecret | Automatic Token generation & caching | | NONE | - | No Auth |

Strict Validation: If a connector is configured as BEARER_TOKEN in the DB, any incoming request trying to pass BASIC auth will be rejected with a 400 AUTH_MISMATCH.


📝 Database Mapping Guide

The mapping_config column in your database governs how data flows. Here is the standard format for various integration scenarios.

1. Basic Object Mapping (type: "OBJECT")

Use this for standard JSON-to-JSON transformations.

{
  "id": "user-connector",
  "targetApi": {
    "url": "https://api.external.com/users",
    "method": "POST"
  },
  "requestMapping": {
    "type": "OBJECT",
    "mappings": [
      { "source": "$.firstName", "target": "$.full_name" },
      { "source": "$.meta.age", "target": "$.age", "default": 18, "required": true }
    ]
  }
}

2. Array List Mapping (type: "ARRAY")

Use this when the target API returns a list of items and you need to transform each item.

{
  "responseMapping": {
    "type": "ARRAY",
    "root": "$.items",         // JSONPath to the array in the source
    "outputWrapper": "$.data", // (Optional) Wraps result in a specific key
    "mappings": [
      { "source": "$.id", "target": "$.userId" },
      { "source": "$.title", "target": "$.name", "transform": "uppercase" }
    ]
  }
}

3. Transforms

Apply built-in functions during mapping.

{
  "mappings": [
    { 
      "source": "$.price", 
      "target": "$.formattedPrice", 
      "transform": "roundTo2" 
    }
  ]
}

Built-in Transforms: uppercase, lowercase, roundTo2, toNumber, toString.


🛑 Error Response Examples

The framework provides standardized error responses for different failure scenarios.

1. Mapping Not Found (404)

Triggered when the requested connectorKey does not exist in the database.

{
    "success": false,
    "statusCode": 404,
    "errorType": "CLIENT_ERROR",
    "message": "Mapping with ID or Name 'jsonplaceholder-users' not found"
}

2. Target API Error (401/500/etc.)

Triggered when the external service returns an error. The targetResponse field contains the raw response from the external API.

{
    "success": false,
    "statusCode": 401,
    "errorType": "TARGET_API_ERROR",
    "targetResponse": {
        "message": "Invalid or expired token",
        "error": "Unauthorized",
        "statusCode": 401
    }
}

3. Authentication Mismatch (400)

Triggered when the authentication type passed in the request does not match the mandatory authentication type configured in the database for that connector.

{
    "success": false,
    "statusCode": 400,
    "errorType": "CLIENT_ERROR",
    "message": "Auth type BEARER_TOKE does not match required BEARER_TOKEN"
}