Skip to content

Commit

Permalink
v1.7.0 (#10)
Browse files Browse the repository at this point in the history
* Add an option to use functional response transformer

* Update dependencies

* Fix class transformer returing undefined instead of transformed object

* Update README.md

* Add an option to use functional request interceptor

* Update README.md

* Bump version

* Fix request interceptor tests

* Add an option to make concurrent requests

* Add ResponseInspector to inspect HTTP response

* Change name to display as multiple

* Add name to TailorFetchResponse and change how ResponseInspector.ts accesses it

* update README.md

* release v1.7.0

---------

Co-authored-by: Marek Dev <[email protected]>
Co-authored-by: Marek home Home <[email protected]>
  • Loading branch information
3 people authored Jan 17, 2025
1 parent 3a4623f commit 07470d7
Show file tree
Hide file tree
Showing 9 changed files with 460 additions and 281 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,20 @@ await TailorFetch.POST(url, options);
- `maxRetries` - Maximum number of times to attempt to make an HTTP request
- `retryDelay` - Number of milliseconds to wait between attempts

## Concurrent Requests
TailorFetch supports making concurrent HTTP requests out of the box.

```typescript
const responses: TailorResponse[] = await TailorFetch.concurrent([
{url: 'https://dummyjson.com/products', method: 'GET', options: {name: 'products', json: true}},
{url: 'https://dummyjson.com/products/1', method: 'GET', options: {name: 'product', json: true}},
{url: 'https://dummyjson.com/carts', method: 'GET', options: {name: 'carts', json: true}},
]);
```

You can name each request by supplying the `name` option


## Cache

### Built-in cache
Expand Down
622 changes: 352 additions & 270 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tailorfetch",
"version": "1.6.0",
"version": "1.7.0",
"description": "TailorFetch is a lightweight Node.js library for making HTTP requests with customizable options and response transformations.",
"main": "lib/index.js",
"scripts": {
Expand Down
1 change: 1 addition & 0 deletions src/IRequestOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import BaseRequestInterceptor from "./BaseRequestInterceptor";
type redisClient = ReturnType<typeof createClient>;

export default interface IRequestOptions {
name?: string,
headers?: { [key: string]: string };
queryParams?: { [key: string]: string };
timeout?: number;
Expand Down
6 changes: 5 additions & 1 deletion src/Response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import IRequestOptions from "./IRequestOptions";

export default class TailorResponse {

public name: string | undefined = 'TailorResponse';

/**
* Response data
*/
Expand Down Expand Up @@ -38,6 +40,7 @@ export default class TailorResponse {
public response: Response | undefined;

constructor(data: any, response: Response | undefined, requestOptions: IRequestOptions, isCached: boolean = false) {
this.name = requestOptions.name
this.data = data;
this.status = response?.status;
this.statusText = response?.statusText;
Expand All @@ -50,6 +53,7 @@ export default class TailorResponse {
// TODO: This is probably not needed here
toObject() {
return {
name: this.name,
data: this.data,
status: this.status,
statusText: this.statusText,
Expand Down Expand Up @@ -167,7 +171,7 @@ export default class TailorResponse {
/**
* 401 Unauthorized
*
* @returns {boolean} Wether the request status was 401
* @returns {boolean} Weather the request status was 401
*/
unauthorized(): boolean {
return this.status == 401;
Expand Down
20 changes: 19 additions & 1 deletion src/TailorFetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,25 @@ import IRequestOptions from "./IRequestOptions";
import Request from "./Request";
import TailorResponse from "./Response";

type RequestMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'CONNECT' | 'HEAD' | 'OPTIONS';

export default class TailorFetch {

/**
* Allow concurrent requests
*
* @param requests
*/
static async concurrent(requests: { url: string; method: RequestMethod, options?: IRequestOptions }[]): Promise<TailorResponse[]> {
// Map requests to TailorFetch.make calls
const promises = requests.map((request) =>
TailorFetch.make(request.url, request.method, request.options)
);

// Use Promise.all to wait for all requests to complete
return Promise.all(promises);
}

/**
*
* @param urlStr {string} Url to make request to
Expand All @@ -11,7 +29,7 @@ export default class TailorFetch {
*
* @returns {TailorResponse}
*/
static async make(urlStr: string, method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'CONNECT' | 'HEAD' | 'OPTIONS', options?: IRequestOptions): Promise<TailorResponse> {
static async make(urlStr: string, method: RequestMethod, options?: IRequestOptions): Promise<TailorResponse> {
const request = new Request(urlStr, method, { ...options });

return await request.make();
Expand Down
39 changes: 39 additions & 0 deletions src/helpers/ResponseInspector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import TailorResponse from "../Response";

export default class ResponseInspector {

constructor() {
// Maybe later
}

private static output = (response: TailorResponse) => {
console.log('----------------------BEGIN RESPONSE INSPECTOR--------------------------');

if (response.successful()) {
console.log(` Request Name: ${response.name ?? 'Unknown'}`);
console.log(` Status: ${response.status}`);
console.log(` Headers: ${JSON.stringify(response.headers, null, 2)}`);
console.log(` Data: ${JSON.stringify(response.data, null, 2)}`);
}

if (response.failed()) {
console.error(` Request Name: ${response.name ?? 'Unknown'}`);
console.error(` Error: Response failed`);
console.error(` Status: ${response.status}`);
console.error(` Headers: ${JSON.stringify(response.headers, null, 2)}`);
console.error(` Data: ${JSON.stringify(response.data, null, 2)}`);
}

console.log('----------------------END RESPONSE INSPECTOR-----------------------------')
}

static inspectSingle = (response: TailorResponse) => {
ResponseInspector.output(response);
}

static inspectMultiple = (responses: TailorResponse[])=> {
responses.forEach((response: TailorResponse) => {
ResponseInspector.output(response);
})
}
}
21 changes: 21 additions & 0 deletions tests/ConcurrentRequestTest.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {describe} from "node:test";
import TailorFetch, {TailorResponse} from "../src";
import {assert} from "chai";

describe('make concurrent requests', () => {
it('should make concurrent requests', async () => {

// Arrange: Set up the test by defining the URL and request options
const responses: TailorResponse[] = await TailorFetch.concurrent([
{url: 'https://dummyjson.com/products', method: 'GET', options: {name: 'products', json: true}},
{url: 'https://dummyjson.com/products/1', method: 'GET', options: {name: 'product', json: true}},
{url: 'https://dummyjson.com/carts', method: 'GET', options: {name: 'carts', json: true}},
]);

// Check if the response is successful (status code 2xx).
assert.equal(responses.length, 3, "Failed to make all requests");

// Check if response is an instance of TailorResponse
assert.instanceOf(responses, Array);
});
})
16 changes: 8 additions & 8 deletions tests/RequestTest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ describe('make GET, POST, PUT, PATCH, DELETE requests', () => {
const url = "https://dummyjson.com/products/1";
const requestOptions = { json: true };

// Act: Perform the GET request and recieve response
// Act: Perform the GET request and receive response
const response: TailorResponse = await TailorFetch.GET(url, requestOptions);

// Assert: Verify the expected outcomes

// Check if the response is successful (status code 2xx).
assert.equal(response.successful(), true, "GET request failed");

// Check if response if an instance of TailorResponse
// Check if response is an instance of TailorResponse
assert.instanceOf(response, TailorResponse);

// Check that data is recieved and is not undefined
// Check that data is received and is not undefined
expect(response.data).to.not.be.undefined;
});

Expand All @@ -36,15 +36,15 @@ describe('make GET, POST, PUT, PATCH, DELETE requests', () => {
})
};

// Act: Perform the GET request and recieve response
// Act: Perform the GET request and receive response
const response: TailorResponse = await TailorFetch.POST(url, requestOptions);

// Assert: Verify the expected outcomes

// Check if the response is successful (status code 2xx)
assert.equal(response.successful(), true, "POST request failed");

// Check if response if an instance of TailorResponse
// Check if response is an instance of TailorResponse
assert.instanceOf(response, TailorResponse);

// Check that data is received and is not undefined
Expand All @@ -67,15 +67,15 @@ describe('make GET, POST, PUT, PATCH, DELETE requests', () => {
})
};

// Act: Perform the GET request and recieve response
// Act: Perform the GET request and receive response
const response: TailorResponse = await TailorFetch.PUT(url, requestOptions);

// Assert: Verify the expected outcomes

// Check if the response is successful (status code 2xx)
assert.equal(response.successful(), true, 'PUT request has failed');

// Check if response if an instance of TailorResponse
// Check if response is an instance of TailorResponse
assert.instanceOf(response, TailorResponse);

// Check that data is received and is not undefined
Expand All @@ -98,7 +98,7 @@ describe('make GET, POST, PUT, PATCH, DELETE requests', () => {
})
};

// Act: Perform the GET request and recieve response
// Act: Perform the GET request and receive response
const response: TailorResponse = await TailorFetch.PATCH(url, requestOptions);

// Assert: Verify the expected outcomes
Expand Down

0 comments on commit 07470d7

Please sign in to comment.