Skip to content

Commit

Permalink
docs: init readme
Browse files Browse the repository at this point in the history
  • Loading branch information
jenspots committed Mar 12, 2024
1 parent e056123 commit 95f39ea
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 28 deletions.
72 changes: 72 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,75 @@
# http-utils-processor-ts

[![Build and test with Bun](https://github.com/jenspots/http-utils-processor-ts/actions/workflows/build-test.yml/badge.svg)](https://github.com/jenspots/http-utils-processor-ts/actions/workflows/build-test.yml)

Connector Architecture Typescript processors for handling HTTP operations.

## Functions

### [`httpFetch`](./src/index.ts)

Build and execute an HTTP request. Writes the body of the response into a user specified channel.

- `url`: endpoint against which a request is made.
- `writer`: channel into which the resulting data is written.
- `options`: an optional parameter which may include:
- `method` the HTTP method to use. (default: `GET`)
- `headers`: an array of strings to be used as headers in the outgoing request. (default: `[]`)
- `acceptStatusCodes`: an array of strings which lists all the status codes deemed "successful". These strings contain either integer literals such as `"200"`, or ranges such as `"200-300"`. Note that range "`a-b`" is inclusive `a`, exclusive `b`. (default: `["200-300"]`)
- `closeOnEnd`: whether to close the writer stream on end. (default: `true`)
- `timeOutMilliseconds`: maximum time spend waiting for a response before throwing a `HttpFetchError.timeOutError` error. (default: `null`)
- `auth`: object describing which authentication flow to use, as well as its parameters. See below for more info. (default: `null`)
- `cron`: specify the interval at which the function should run as a crontab expression. If `null`, the function only executes once before returning. (default: `null`)

#### Authentication

This package supports some forms of authentication such as HTTP Basic Authentication and the OAuth 2.0 Password Grant. Additional methods may be implemented by extending the abstract [`Auth`](./src/auth/index.ts) class, after which you must define an additional [`AuthConfig`](./src/auth/index.ts) type and extend the [`Auth.from`](./src/auth/index.ts) static method.

##### HTTP Basic Authentication

A simple flow which includes the base64 encoded username and password in each request.

- `type`: must be set to`basic`.
- `username`: your username as string.
- `password`: your plaintext password.

##### OAuth 2.0 Password Grant

Before executing your request, a POST request is sent to the OAuth server in order to obtain a token. The result of which is embedded as a header inside the original request.

- `type`: must be set to `oauth2`
- `endpoint`: the URL of the OAuth 2.0 server.
- `username`: your username as string.
- `password`: your plaintext password.

Note that your credentials are not send to the server you specified in the `url` option of `httpFetch`, but only to the `endpoint` you specified above.

## Errors

All errors thrown in `httpFetch` are of the `HttpFetchError` type, as defined in [`./src/error.ts`](./src/error.ts). This class contains a `HttpUtilsErrorType` enum value which reflects the nature of the error.

## Tests

At the time of writing, tests should be executed using the Bun runtime.

```sh
$ bun run build
$ bun test
```

Some tests interact with real online servers, and may therefore require credentials. These can be supplied inside a `.env` file at the root of the repository.

```shell
# Requires OAuth 2.0 Password Grant
RINF_USERNAME=
RINF_PASSWORD=

# Requires HTTP Basic Auth
WoRMS_USERNAME=
WoRMS_PASSWORD=

# Needs to be `true` in order to execute
BLUE_BIKE=true
```

Additional information can be found [here](./tests/README.md).
4 changes: 4 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Test Suite

> [!NOTE]
> This page still needs to be written.
53 changes: 25 additions & 28 deletions tests/online/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@ import { httpFetch } from "../../src";
import { writer } from "../writer";

describe("Real world datasets", () => {
test(
// Retrieve RINF credentials.
const rinfUsername = process.env["RINF_USERNAME"];
const rinfPassword = process.env["RINF_PASSWORD"];
const rinfTest = rinfUsername && rinfPassword ? test : test.skip;

rinfTest(
"RINF - success",
async () => {
// Retrieve credentials.
const username = process.env["RINF_USERNAME"];
const password = process.env["RINF_PASSWORD"];

if (!username || !password) {
throw new Error("RINF_USERNAME and RINF_PASSWORD must be set");
}

// Output stream which we'll check for correctness.
const writeStream = writer((output) => {
const json = JSON.parse(output);
Expand All @@ -31,8 +28,8 @@ describe("Real world datasets", () => {
{
auth: {
type: "oauth2",
username,
password,
username: rinfUsername!,
password: rinfPassword!,
endpoint: "https://rinf.era.europa.eu/api/token",
},
},
Expand All @@ -43,7 +40,7 @@ describe("Real world datasets", () => {
10 * 1000,
);

test(
rinfTest(
"RINF - missing credentials",
async () => {
const func = await httpFetch(
Expand All @@ -58,7 +55,7 @@ describe("Real world datasets", () => {
10 * 1000,
);

test(
rinfTest(
"RINF - invalid credentials",
async () => {
const func = await httpFetch(
Expand All @@ -81,26 +78,22 @@ describe("Real world datasets", () => {
10 * 1000,
);

test(
// Retrieve WoRMS credentials.
const wormsUsername = process.env["WoRMS_USERNAME"];
const wormsPassword = process.env["WoRMS_PASSWORD"];
const wormsTest = wormsUsername && wormsPassword ? test : test.skip;

wormsTest(
"WoRMS - success",
async () => {
const username = process.env["WoRMS_USERNAME"];
const password = process.env["WoRMS_PASSWORD"];

if (!username || !password) {
throw new Error(
"WoRMS_USERNAME and WoRMS_PASSWORD must be set",
);
}

const func = await httpFetch(
"https://www.marinespecies.org/download/",
new SimpleStream<string>(),
{
auth: {
type: "basic",
username,
password,
username: wormsUsername!,
password: wormsPassword!,
},
},
);
Expand All @@ -110,7 +103,7 @@ describe("Real world datasets", () => {
10 * 1000,
);

test(
wormsTest(
"WoRMS - missing credentials",
async () => {
const func = await httpFetch(
Expand All @@ -125,7 +118,7 @@ describe("Real world datasets", () => {
10 * 1000,
);

test(
wormsTest(
"WoRMS - invalid credentials",
async () => {
const func = await httpFetch(
Expand All @@ -147,7 +140,11 @@ describe("Real world datasets", () => {
10 * 1000,
);

test("BlueBike - success", async () => {
// Check if BLUE_BIKE is defined.
const blueBike = process.env["BLUE_BIKE"];
const blueBikeTest = blueBike === "true" ? test : test.skip;

blueBikeTest("BlueBike - success", async () => {
const writeStream = writer((output) => {
expect(JSON.parse(output).length).toBeGreaterThan(100);
});
Expand Down

0 comments on commit 95f39ea

Please sign in to comment.