From 0e47c240f024edd80f4ef8edfdbe0d7030e71a76 Mon Sep 17 00:00:00 2001 From: paullaster Date: Wed, 29 Oct 2025 05:21:17 +0300 Subject: [PATCH 1/2] ref: refactor the reference to the options of request option type - primaryKeys after update dating the type and pluralizing --- src/transport/Transport.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/transport/Transport.ts b/src/transport/Transport.ts index 280a63f..6dcea76 100644 --- a/src/transport/Transport.ts +++ b/src/transport/Transport.ts @@ -183,15 +183,15 @@ export class Transport { } async patch(endpoint: string, payload?: any, options?: RequestOptions): Promise { try { - const primaryKeys = this.extractPrimaryKeys(payload, options?.primaryKey); + const primaryKeys = this.extractPrimaryKeys(payload, options?.primaryKeys); const url = `${endpoint}(${primaryKeys.join(',')})`; if (options?.headers) { options.headers['If-Match'] = "*"; } else { options = { ...options, headers: { 'If-Match': "*" } }; } - if (options.primaryKey) { - for (const key of options.primaryKey) { + if (options.primaryKeys) { + for (const key of options.primaryKeys) { delete payload[key]; } } @@ -202,15 +202,15 @@ export class Transport { } async put(endpoint: string, payload?: any, options?: RequestOptions): Promise { try { - const primaryKeys = this.extractPrimaryKeys(payload, options?.primaryKey); + const primaryKeys = this.extractPrimaryKeys(payload, options?.primaryKeys); const url = `${endpoint}(${primaryKeys.join(',')})`; if (options?.headers) { options.headers['If-Match'] = "*"; } else { options = { ...options, headers: { 'If-Match': "*" } }; } - if (options.primaryKey) { - for (const key of options.primaryKey) { + if (options.primaryKeys) { + for (const key of options.primaryKeys) { delete payload[key]; } } @@ -222,7 +222,7 @@ export class Transport { async delete(endpoint: string, payload?: any, options?: RequestOptions): Promise { try { this.invalidateCache(endpoint, options); - const primaryKeys = this.extractPrimaryKeys(payload, options?.primaryKey); + const primaryKeys = this.extractPrimaryKeys(payload, options?.primaryKeys); const url = `${endpoint}(${primaryKeys.join(',')})`; if (options?.headers) { options.headers['If-Match'] = "*"; From f37d718e633d3c43a2dea1613a6854998c01613a Mon Sep 17 00:00:00 2001 From: paullaster Date: Wed, 29 Oct 2025 06:53:29 +0300 Subject: [PATCH 2/2] feat: Added Request context company commands for setting and modifying preferred company value and property (Company-Name or Company-Id) per request or in every request as you wish. By default company name from the environment configs are used if no company custom header commands are valid. If a company value; either name or id is set in the request headers company commands, they are given priority and the company configs on the environment files are ignored. --- index.ts | 61 +++++++++++++++++++++++++++++++++++++- src/transport/Transport.ts | 26 ++++++++++++++-- tests/unit/oauth2.test.mts | 8 ++++- 3 files changed, 91 insertions(+), 4 deletions(-) diff --git a/index.ts b/index.ts index 94e1e8b..11af0e4 100644 --- a/index.ts +++ b/index.ts @@ -10,13 +10,14 @@ import { TimeoutError } from "./src/errors/TimeoutError.js"; // Load configuration from environment variables -const { baseURL, authType, credentials, oath2Config, redisConfig, accessTokenURL } = getConfig(); +const { baseURL, authType, credentials, oath2Config, redisConfig, accessTokenURL, companyName, companyId } = getConfig(); // Create an authentication handler const authHandler = CreateAuthHandler(authType, credentials, oath2Config, accessTokenURL, redisConfig); // Initialize the transport utility const transport = new Transport({ baseURL, cacheTTL: 600 }, authHandler); + transport.addMiddleware(async (config) => { const token = await authHandler.getAccessToken(); if (!token) return config; @@ -26,6 +27,64 @@ transport.addMiddleware(async (config) => { config.headers['Authorization'] = `Bearer ${token}`; return config; }); + +transport.addMiddleware(async (config) => { + const company = config?.headers?.['X-Custom-Request-Company']; + const whichCompanyIdentifier = config?.headers?.['X-Custom-Request-Company-Identifier']; + config.headers = config.headers ?? {} + if (company) { + if (whichCompanyIdentifier) { + switch (whichCompanyIdentifier) { + case 'Company-Name': { + config.params = config.params ?? {}; + config.params.company = company; + config.headers['X-Custom-Params-Company-Command'] = 'Skip' + break; + }; + case 'Company-Id': { + const splittedUrl = config?.url?.split("/"); + if (splittedUrl && Array.isArray(splittedUrl)) { + const last = splittedUrl[splittedUrl.length - 1]; + const url = `${splittedUrl.slice(0, -1).join("/")}/companies(${company})/${last}`; + config.url = url; + config.headers = config.headers ?? {} + config.headers['X-Custom-Params-Company-Command'] = 'Remove' + } + break; + }; + default: { + config.headers['X-Custom-Params-Company-Command'] = 'Set' + } + } + } + } else { + if (whichCompanyIdentifier) { + switch (whichCompanyIdentifier) { + case 'Company-Name': { + config.params = config.params ?? {}; + config.params.company = companyName; + config.headers['X-Custom-Params-Company-Command'] = 'Skip' + break; + }; + case 'Company-Id': { + const splittedUrl = config?.url?.split("/") + if (splittedUrl && Array.isArray(splittedUrl)) { + const last = splittedUrl[splittedUrl.length - 1]; + const url = `${splittedUrl.slice(0, -1).join("/")}/companies(${companyId})/${last}`; + config.url = url; + config.headers = config.headers ?? {} + config.headers['X-Custom-Params-Company-Command'] = 'Remove' + } + break; + }; + default: { + config.headers['X-Custom-Params-Company-Command'] = 'Set' + } + } + } + } + return config; +}); export { Transport, CreateAuthHandler, diff --git a/src/transport/Transport.ts b/src/transport/Transport.ts index 6dcea76..ef4335d 100644 --- a/src/transport/Transport.ts +++ b/src/transport/Transport.ts @@ -118,8 +118,30 @@ export class Transport { if (config.params) { config.params = { ...config.params }; } - if (!config.params.company) { - config.params.company = this.defaultCompany + config.headers = config.headers ?? {}; + const companyParamCommand = config.headers['X-Custom-Params-Company-Command']; + + switch (companyParamCommand) { + case 'Set': { + if (!config.params.company) { + config.params.company = this.defaultCompany; + } + break; + }; + case 'Skip': { + break + } + case 'Remove': { + if (config.params.company) { + delete config.params.company; + } + break; + } + default: { + if (!config.params.company) { + config.params.company = this.defaultCompany; + } + } } return config; }) diff --git a/tests/unit/oauth2.test.mts b/tests/unit/oauth2.test.mts index c157595..3fb07a1 100644 --- a/tests/unit/oauth2.test.mts +++ b/tests/unit/oauth2.test.mts @@ -3,7 +3,13 @@ import { transport } from "../../index.ts"; async function runTest() { try { - const response = await transport.get("/api/KineticTechnology/CashMgt/v2.0/imprestAPI", {}, { headers: { 'Prefer': "maxpagesize=2" } }) as Response; + const response = await transport.get("/api/nurture/ESS/v1.0/leavemployees", {}, { + headers: { + 'Prefer': "maxpagesize=2", + 'X-Custom-Request-Company-Identifier': 'Company-Id', + 'X-Custom-Request-Company': "083db09a-ff98-f011-a7b2-6045bdacc0b6" + } + }) as Response; // const filter = await transport.filter({ // date_from: "2022-01-01", // date_to: '2022-01-01',