diff --git a/README.md b/README.md index 60e4291d..6f353342 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,14 @@ import { Component } from "@k8slens/extensions"; import axios from "axios"; // Use NodeJS HTTP adapter to get around CORS issues -axios.defaults.adapter = require("axios/lib/adapters/http"); +// This is not neded if httpAdapter: true is used. +axios.defaults.adapter = axios.getAdapter("http"); const lensPlatformClient = new LensPlatformClient({ accessToken: "", // the access token for apis getAccessToken: () => Promise.resolve(""), // the callback to be called before every request, useful if the access token needs to be renew often. keyCloakAddress: "", // keycloak address, e.g. "https://keycloak.k8slens.dev" - keycloakRealm: "", // the realm name, e.g. "lensCloud" + keycloakRealm: "", // the realm name, e.g. "lensCloud" apiEndpointAddress: "", // api endpoint address, e.g. "https://api.k8slens.dev" httpAdapter: false // Optional, defaults to false. If true, the axios HTTP adapter is used instead of xhr logLevel: "debug" // Optional, defaults to 'silent'. Options are 'silent' | 'debug' | 'error' diff --git a/package-lock.json b/package-lock.json index 5c9e8256..065d1056 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "14.1.0", "license": "MIT", "dependencies": { - "axios": "^0.27.2", + "axios": "^1.6.7", "jwt-decode": "^3.1.2", "pino": "^7.5.0", "zod": "^3.21.4" @@ -3844,12 +3844,13 @@ } }, "node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/axobject-query": { @@ -8273,6 +8274,11 @@ "node": ">= 8" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -12157,12 +12163,13 @@ "dev": true }, "axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "axobject-query": { @@ -15534,6 +15541,11 @@ "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", "dev": true }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", diff --git a/package.json b/package.json index b73659d2..6f6cef1a 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "node": ">=12 <=18" }, "files": [ - "dist/" + "dist/**/*" ], "exports": { ".": { @@ -14,7 +14,7 @@ "import": "./dist/esm/index.js" } }, - "main": "./dist/cjs/index.js", + "main": "dist/cjs/index.js", "scripts": { "test": "npm run check:type && npm run test:unit && npm run test:e2e", "test:unit": "jest", @@ -75,7 +75,7 @@ "typescript": "5.0.4" }, "dependencies": { - "axios": "^0.27.2", + "axios": "^1.6.7", "jwt-decode": "^3.1.2", "pino": "^7.5.0", "zod": "^3.21.4" diff --git a/src/LensPlatformClient.ts b/src/LensPlatformClient.ts index a9461b6a..816e8776 100644 --- a/src/LensPlatformClient.ts +++ b/src/LensPlatformClient.ts @@ -21,7 +21,38 @@ import { SSOService } from "./SSOService"; // LensPlatformClient supports using the http adapter if httpAdapter // option is set to true // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires -const axiosHttpAdapter = require("axios/lib/adapters/http"); +let axiosHttpAdapter: Function | undefined; + +// lens-platform-sdk works in multiple environments, namely +// * Node: regular Node.js process and electron's Node.js +// * Browser: Regular browsers and Electron's Chromium environment +// For this reason we need to support different kind of requires +// In particular we might want to load the http adapter to execute +// requests in Node. +const multiEnvironmentRequire = (moduleName: string) => { + try { + return window.require(moduleName); + } catch (error) { + return require(moduleName); + } +}; + +/** + * Returns axios http adapter (used for Node.js requests). + * It requires the adapter if not loaded before. + * @returns + */ +const getAxiosHttpAdapter = () => { + try { + if (!axiosHttpAdapter) { + axiosHttpAdapter = multiEnvironmentRequire("axios").getAdapter("http"); + } + + return axiosHttpAdapter; + } catch (error) { + return undefined; + } +}; export interface LensPlatformClientOptions { accessToken?: string; @@ -274,7 +305,7 @@ class LensPlatformClient { const requestOptions: RequestOptions = { headers: requestHeaders, - ...(httpAdapter ? { adapter: axiosHttpAdapter } : {}), + ...(httpAdapter ? { adapter: getAxiosHttpAdapter() } : {}), ...(proxyConfigs ? { proxy: proxyConfigs } : {}), ...(httpAgent ? { httpAgent } : {}), ...(httpsAgent ? { httpsAgent } : {}), @@ -283,6 +314,7 @@ class LensPlatformClient { }; logger.debug(`request arguments ${JSON.stringify(requestOptions)}`); + const response = await (hasBody ? prop(url, requestBody, requestOptions) : prop(url, requestOptions));