{"_id":"@divami-labs/nestjs-api-connector","name":"@divami-labs/nestjs-api-connector","dist-tags":{"latest":"0.0.1"},"versions":{"0.0.1":{"name":"@divami-labs/nestjs-api-connector","version":"0.0.1","description":"Enterprise-grade API Proxy and Transformation Framework for NestJS","author":{"name":"Divami"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/divamidesignlabs/nestjs-api-corrector.git"},"keywords":["nestjs","api-gateway","api-proxy","transformation","jsonpath","enterprise","resilience","mapping"],"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc -p tsconfig.build.json","build:watch":"tsc -p tsconfig.build.json --watch","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","lint":"eslint \"{src,apps,libs,test}/**/*.ts\" --fix","test":"jest","test:watch":"jest --watch","test:cov":"jest --coverage","prepublishOnly":"npm run build","start":"nest start"},"license":"MIT","peerDependencies":{"@nestjs/common":"^10.0.0 || ^11.0.0","@nestjs/core":"^10.0.0 || ^11.0.0","@nestjs/typeorm":"^10.0.0 || ^11.0.0","reflect-metadata":"^0.1.13 || ^0.2.0","rxjs":"^7.8.0","typeorm":"^0.3.0"},"dependencies":{"@nestjs/axios":"^3.0.0","axios":"^1.6.0","jsonpath":"^1.1.1"},"devDependencies":{"@nestjs/cli":"^10.0.0","@nestjs/common":"^10.0.2","@nestjs/core":"^10.0.2","@nestjs/platform-express":"^10.0.2","@nestjs/schematics":"^10.0.0","@nestjs/testing":"^10.0.2","@types/express":"^4.17.17","@types/jest":"^29.5.12","@types/jsonpath":"^0.2.4","@types/node":"^20.0.0","@types/supertest":"^6.0.0","eslint":"^8.0.0","eslint-config-prettier":"^9.0.0","eslint-plugin-prettier":"^5.0.0","globals":"^15.0.0","jest":"^29.7.0","prettier":"^3.0.0","reflect-metadata":"^0.1.13","rxjs":"^7.8.2","source-map-support":"^0.5.21","supertest":"^6.0.0","ts-jest":"^29.1.0","ts-loader":"^9.0.0","ts-node":"^10.0.0","tsconfig-paths":"^4.0.0","typescript":"~5.7.2","typescript-eslint":"^8.0.0"},"jest":{"moduleFileExtensions":["js","json","ts"],"rootDir":"src","testRegex":".*\\.spec\\.ts$","transform":{"^.+\\.(t|j)s$":"ts-jest"},"collectCoverageFrom":["**/*.(t|j)s"],"coverageDirectory":"../coverage","testEnvironment":"node"},"_id":"@divami-labs/nestjs-api-connector@0.0.1","gitHead":"51eac510e9d156bcf5e63ada03cc3aa3fc0690e8","bugs":{"url":"https://github.com/divamidesignlabs/nestjs-api-corrector/issues"},"homepage":"https://github.com/divamidesignlabs/nestjs-api-corrector#readme","_nodeVersion":"18.20.8","_npmVersion":"10.8.2","dist":{"integrity":"sha512-qLWfsu+E3r/iGNhtAMGxlvHulA640vsswiRfasM5QOxAwD9Q2BfJ4nX/4Iqg0lT5tiKFkuT7gUUHtX9UpB4P6w==","shasum":"924e813b68d0cd2e78fc447a4fbb3709c4810cec","tarball":"https://registry.npmjs.org/@divami-labs/nestjs-api-connector/-/nestjs-api-connector-0.0.1.tgz","fileCount":55,"unpackedSize":293509,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDUlqjCJ4jplRFt60U6wCcUxMsTvZMAbj9xnzekAakrBgIgROZa12HGvIowMBE8ar8QKn55oVZhi1uT+O8K8lsD/rU="}]},"_npmUser":{"name":"divami-artefacts","email":"devops@divami.com"},"directories":{},"maintainers":[{"name":"divami-artefacts","email":"devops@divami.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nestjs-api-connector_0.0.1_1770377667973_0.7923304637275643"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-06T11:34:27.876Z","0.0.1":"2026-02-06T11:34:28.132Z","modified":"2026-02-06T11:34:28.311Z"},"maintainers":[{"name":"divami-artefacts","email":"devops@divami.com"}],"description":"Enterprise-grade API Proxy and Transformation Framework for NestJS","homepage":"https://github.com/divamidesignlabs/nestjs-api-corrector#readme","keywords":["nestjs","api-gateway","api-proxy","transformation","jsonpath","enterprise","resilience","mapping"],"repository":{"type":"git","url":"git+https://github.com/divamidesignlabs/nestjs-api-corrector.git"},"author":{"name":"Divami"},"bugs":{"url":"https://github.com/divamidesignlabs/nestjs-api-corrector/issues"},"license":"MIT","readme":"# 🚀 NestJS API Connector\n\n**A configuration-driven API integration & transformation framework for NestJS.**\n\n[![npm version](https://badge.fury.io/js/nestjs-api-connector.svg)](https://badge.fury.io/js/nestjs-api-connector)\n\n\n**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.\n\n---\n\n## ✨ Features\n\n*   **Dynamic Configuration**: Define API endpoints, methods, and auth type in your DB.\n*   **Zero-Code Updates**: Change target URLs or field mappings without redeploying code.\n*   **Robust Authentication**: Supported strategies (Bearer, Basic, ApiKey, OAuth2) with strict database priority.\n*   **High Performance Transformation**: Transform requests and responses using JSONPath or Custom Javascript with optimized array processing.\n*   **Standardized Responses**: Consistent error handling (CLIENT_ERROR, TARGET_API_ERROR, INTERNAL_ERROR).\n*   **Database Agnostic**: Built-in TypeORM support, easily adaptable to any repository.\n\n---\n\n## 📦 Installation\n\n```bash\nnpm install nestjs-api-connector\n```\n\n---\n\n## 🛠️ Usage\n\n### 1. Database Setup\n\nThe library includes a `database_init.sql` file in the root directory. You can use this to initialize your PostgreSQL database.\n\n*   **Tables Created**: `connector_mappings_config`\n*   **Columns**: `id`, `name`, `source_system`, `target_system`, `mapping_config`, `created_at`, `updated_at`.\n\nYou can also create a **Custom Table Name** (see below).\n\n### 2. Import Module in `AppModule`\n\n#### A. Using TypeORM (Recommended)\n\n```typescript\nimport { Module } from '@nestjs/common';\nimport { TypeOrmModule } from '@nestjs/typeorm';\nimport { DataSource } from 'typeorm';\nimport { \n  ConnectorModule, \n  TypeOrmMappingRepository, \n  IntegrationMappingEntity \n} from 'nestjs-api-connector';\n\n@Module({\n  imports: [\n    TypeOrmModule.forRoot({\n      type: 'postgres',\n      entities: [IntegrationMappingEntity],\n      synchronize: false, \n    }),\n\n    ConnectorModule.forRootAsync({\n      inject: [DataSource],\n      useFactory: (dataSource: DataSource) => ({\n        mappingRepository: new TypeOrmMappingRepository(\n          dataSource.getRepository(IntegrationMappingEntity)\n        ),\n      }),\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n#### B. Using Custom Table Name (Optional)\n\nIf you prefer a custom table name (e.g., `my_custom_connectors`), use the `getMappingEntity` utility:\n\n```typescript\nimport { getMappingEntity, TypeOrmMappingRepository } from 'nestjs-api-connector';\n\n// 1. Create the entity class with your custom table name\nconst MyCustomEntity = getMappingEntity('my_custom_connectors');\n\n@Module({\n  imports: [\n    // Register the custom entity in TypeORM\n    TypeOrmModule.forFeature([MyCustomEntity]),\n    \n    ConnectorModule.forRootAsync({\n      inject: [DataSource],\n      useFactory: (dataSource: DataSource) => ({\n        tableName: 'my_custom_connectors',\n        mappingRepository: new TypeOrmMappingRepository(\n          dataSource.getRepository(MyCustomEntity)\n        ),\n      }),\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n#### C. Extending with Custom Fields (Extra Entity)\n\nYou 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:\n\n```typescript\nimport { getMappingEntity } from 'nestjs-api-connector';\nimport { Entity, Column } from 'typeorm';\n\n// 1. Get the base connector entity class\nconst BaseConnectorEntity = getMappingEntity('enterprise_connectors');\n\n// 2. Extend it to add custom fields\n@Entity('enterprise_connectors')\nexport class ExtendedConnectorEntity extends BaseConnectorEntity {\n  @Column({ nullable: true })\n  clientOwner: string;\n\n  @Column({ default: 'PROD' })\n  environment: string;\n\n  @Column({ type: 'boolean', default: true })\n  isActive: boolean;\n}\n\n// 3. Register as normal\n@Module({\n  imports: [\n    TypeOrmModule.forFeature([ExtendedConnectorEntity]),\n    ConnectorModule.forRootAsync({\n      inject: [DataSource],\n      useFactory: (dataSource: DataSource) => ({\n        mappingRepository: new TypeOrmMappingRepository(\n          dataSource.getRepository(ExtendedConnectorEntity)\n        ),\n      }),\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n\n\n### 4. Built-in API Proxy\n\nThe framework automatically exposes a standardized endpoint: `POST /connector/execute`.\n\n**Sample Request Payload:**\n```json\n{\n  \"connectorKey\": \"get-products\",\n  \"payload\": { \"id\": 101 },\n  \"authConfig\": {\n    \"authType\": \"BEARER_TOKEN\",\n    \"config\": { \"token\": \"abc-123-token\" }\n  },\n  \"headerData\": { \"X-Custom-Source\": \"Mobile-App\" },\n  \"queryParams\": { \"version\": \"v2\" }\n}\n```\n\n---\n\n## 🔐 Authentication Standards\n\nThe framework ensures security by prioritizing **Database Configuration** over incoming request data.\n\n| Auth Type | Config Fields required in DB/Request | Injection Method |\n| :--- | :--- | :--- |\n| **`BEARER_TOKEN`** | `token` | `Authorization: Bearer <token>` |\n| **`BASIC`** | `username`, `password` | `Authorization: Basic <base64>` |\n| **`API_KEY`** | `keyName`, `keyValue` | Custom header (e.g., `x-api-key: val`) |\n| **`OAUTH2_CLIENT_CREDENTIALS`** | `tokenUrl`, `clientId`, `clientSecret` | Automatic Token generation & caching |\n| **`NONE`** | - | No Auth |\n\n**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`.\n\n---\n\n## 📝 Database Mapping Guide\n\nThe `mapping_config` column in your database governs how data flows. Here is the standard format for various integration scenarios.\n\n### 1. Basic Object Mapping (`type: \"OBJECT\"`)\nUse this for standard JSON-to-JSON transformations.\n\n```json\n{\n  \"id\": \"user-connector\",\n  \"targetApi\": {\n    \"url\": \"https://api.external.com/users\",\n    \"method\": \"POST\"\n  },\n  \"requestMapping\": {\n    \"type\": \"OBJECT\",\n    \"mappings\": [\n      { \"source\": \"$.firstName\", \"target\": \"$.full_name\" },\n      { \"source\": \"$.meta.age\", \"target\": \"$.age\", \"default\": 18, \"required\": true }\n    ]\n  }\n}\n```\n\n### 2. Array List Mapping (`type: \"ARRAY\"`)\nUse this when the target API returns a list of items and you need to transform each item.\n\n```json\n{\n  \"responseMapping\": {\n    \"type\": \"ARRAY\",\n    \"root\": \"$.items\",         // JSONPath to the array in the source\n    \"outputWrapper\": \"$.data\", // (Optional) Wraps result in a specific key\n    \"mappings\": [\n      { \"source\": \"$.id\", \"target\": \"$.userId\" },\n      { \"source\": \"$.title\", \"target\": \"$.name\", \"transform\": \"uppercase\" }\n    ]\n  }\n}\n```\n\n\n### 3. Transforms\nApply built-in functions during mapping.\n\n```json\n{\n  \"mappings\": [\n    { \n      \"source\": \"$.price\", \n      \"target\": \"$.formattedPrice\", \n      \"transform\": \"roundTo2\" \n    }\n  ]\n}\n```\n\n**Built-in Transforms:** `uppercase`, `lowercase`, `roundTo2`, `toNumber`, `toString`.\n\n---\n\n## 🛑 Error Response Examples\n\nThe framework provides standardized error responses for different failure scenarios.\n\n### 1. Mapping Not Found (404)\nTriggered when the requested `connectorKey` does not exist in the database.\n\n```json\n{\n    \"success\": false,\n    \"statusCode\": 404,\n    \"errorType\": \"CLIENT_ERROR\",\n    \"message\": \"Mapping with ID or Name 'jsonplaceholder-users' not found\"\n}\n```\n\n### 2. Target API Error (401/500/etc.)\nTriggered when the external service returns an error. The `targetResponse` field contains the raw response from the external API.\n\n```json\n{\n    \"success\": false,\n    \"statusCode\": 401,\n    \"errorType\": \"TARGET_API_ERROR\",\n    \"targetResponse\": {\n        \"message\": \"Invalid or expired token\",\n        \"error\": \"Unauthorized\",\n        \"statusCode\": 401\n    }\n}\n```\n\n### 3. Authentication Mismatch (400)\nTriggered when the authentication type passed in the request does not match the mandatory authentication type configured in the database for that connector.\n\n```json\n{\n    \"success\": false,\n    \"statusCode\": 400,\n    \"errorType\": \"CLIENT_ERROR\",\n    \"message\": \"Auth type BEARER_TOKE does not match required BEARER_TOKEN\"\n}\n```\n\n\n\n","readmeFilename":"README.md","_rev":"1-c5dc3269122e732667530776a11bedd9"}