Skip to content

Commit

Permalink
feat: add proxios wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
aneeshrelan committed Sep 29, 2021
1 parent 7cac13d commit e31e654
Show file tree
Hide file tree
Showing 14 changed files with 3,511 additions and 1 deletion.
31 changes: 31 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Release

on:
push:
branches: [main]

jobs:
release:
name: Release
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 14.x
- name: Install dependencies
run: npx ci
- name: Install semantic-release extra plugins
run: npm install --save-dev @semantic-release/changelog @semantic-release/git
- name: Test
run: npm run test
- name: Build
run: npm run build
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
4 changes: 4 additions & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx --no-install commitlint --edit ""
6 changes: 6 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
src
tsconfig.json
coverage
*.config.js
tests
.prettierrc
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"tabWidth": 4,
"arrowParens": "avoid",
"semi": true,
"printWidth": 120
}
Empty file added CHANGELOG.md
Empty file.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# proxios
# praxios
6 changes: 6 additions & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ["@commitlint/config-conventional"],
rules: {
"body-max-line-length": [0, "always"],
},
};
6 changes: 6 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
collectCoverage: true,
};
29 changes: 29 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "praxios",
"version": "0.0.0-semantic-release",
"description": "wrapper to support corporate proxies in axios",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"repository": "[email protected]:Safe-Security/praxios.git",
"author": "Aneesh Relan <[email protected]>",
"license": "MIT",
"dependencies": {
"axios": "^0.21.4",
"tunnel": "^0.0.6"
},
"devDependencies": {
"@commitlint/cli": "^13.2.0",
"@commitlint/config-conventional": "^13.2.0",
"@types/jest": "^27.0.2",
"@types/tunnel": "^0.0.3",
"husky": "^7.0.2",
"jest": "^27.2.3",
"ts-jest": "^27.0.5",
"typescript": "^4.4.3"
},
"scripts": {
"build": "tsc",
"test": "jest",
"prepare": "husky install"
}
}
23 changes: 23 additions & 0 deletions release.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = {
branches: ["main"],
plugins: [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/changelog",
{
changelogFile: "CHANGELOG.md",
},
],
"@semantic-release/npm",
"@semantic-release/github",
[
"@semantic-release/git",
{
assets: ["CHANGELOG.md", "dist/**"],
message:
"chore(release): set `package.json` to ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}",
},
],
],
};
34 changes: 34 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import axios from "axios";
import * as tunnel from "tunnel";

const { PROXY_HOST, PROXY_PORT, PROXY_USERNAME, PROXY_PASSWORD, NO_PROXY } = process.env;

const isProxyDefined = (): boolean => {
return PROXY_HOST !== undefined && PROXY_PORT !== undefined;
};

const getProxyAuth = (): string | undefined => {
if (PROXY_USERNAME && PROXY_PASSWORD) {
return `${PROXY_USERNAME}:${PROXY_PASSWORD}`;
}

return;
};

let praxios = axios.create();

if (isProxyDefined()) {
const httpsAgent = tunnel.httpsOverHttp({
proxy: {
host: PROXY_HOST!,
port: Number(PROXY_PORT!),
localAddress: NO_PROXY,
proxyAuth: getProxyAuth(),
},
});

praxios = axios.create({ httpsAgent, proxy: false });
}

export { tunnel, axios as baseAxios };
export default praxios;
53 changes: 53 additions & 0 deletions tests/proxios.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import axios from "axios";

let praxios;

describe("praxios", () => {
const OLD_ENV = process.env;

beforeEach(() => {
jest.resetModules();
process.env = { ...OLD_ENV };
});

afterAll(() => {
process.env = OLD_ENV; // Restore old environment
});

test("base axios client is exported if proxy isn't defined", async () => {
praxios = (await import("../src/index")).default;
expect(praxios.defaults.httpsAgent).toBeUndefined();
expect(praxios.defaults.proxy).toBeUndefined();
});

test("proxy instance with tunneling agent is available when proxy env vars are set", async () => {
process.env.PROXY_HOST = "dummy";
process.env.PROXY_PORT = "3128";

const praxios = (await import("../src/index")).default;

expect(praxios.defaults.proxy).toEqual(false);
expect(praxios.defaults.httpsAgent.proxyOptions.host).toEqual("dummy");
expect(praxios.defaults.httpsAgent.proxyOptions.port).toEqual(3128);
expect(praxios.defaults.httpsAgent.proxyOptions.localAddress).toBeUndefined();
expect(praxios.defaults.httpsAgent.proxyOptions.proxyAuth).toBeUndefined();
});

test("proxy instance with tunneling agent and proxy auth is available when proxy and auth env vars are set", async () => {
process.env.PROXY_HOST = "dummy";
process.env.PROXY_PORT = "3128";
process.env.PROXY_USERNAME = "foo";
process.env.PROXY_PASSWORD = "bar";

const praxios = (await import("../src/index")).default;

expect(praxios.defaults.httpsAgent.proxyOptions.proxyAuth).toEqual("foo:bar");
});

test("tunnel and base axios module is available", async () => {
const praxios = await import("../src/index");

expect(praxios).toHaveProperty("baseAxios");
expect(praxios).toHaveProperty("tunnel");
});
});
10 changes: 10 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"declaration": true,
"outDir": "./dist",
"strict": true
},
"include": ["src"]
}
Loading

0 comments on commit e31e654

Please sign in to comment.