npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fluentrest-ts

v1.0.18

Published

A lightweight, fluent TypeScript API testing library inspired by Java's RestAssured. Built on top of Axios, JSONPath, and Joi for powerful request handling and response validation.

Readme

fluentrest-ts

A lightweight, fluent TypeScript API testing library inspired by Java's RestAssured. Built on top of Axios, JSONPath, and Joi for powerful request handling and response validation.


📦 Installation

npm install fluentrest-ts

🚀 Quick Start

import { fluentRest } from "fluentrest-ts";

const response = await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .givenHeader("Accept", "application/json")
  .whenGet("/posts/1");

response
  .thenExpectStatus(200)
  .thenExpectBody("$.id", 1);

❗️ Note: thenExpectX methods require the result of a request (you must await the whenX() call).


🔁 Fluent API Overview

| Method | Description | |--------|-------------| | setBaseUrl(url) | Sets the base URL | | setTimeout(ms) | Overrides timeout | | setLogLevel(level) | Sets log verbosity ("debug" | "info" | "none") | | enableFileLogging(bool) | Enables or disables file-based logging | | givenHeader(key, value) | Adds a request header | | givenQueryParam(key, value) | Adds a query parameter | | givenBody(obj) | Sets JSON request body (Serialized strings or types) / Attaches multipart form-data or files| | debug() | Prints current config to console | | getSnapshot() | Returns snapshot of current request config | | whenGet(url) | Sends a GET request | | whenPost(url) | Sends a POST request | | whenPut(url) | Sends a PUT request | | whenPatch(url) | Sends a PATCH request | | whenDelete(url) | Sends a DELETE request | | whenHead(url) | Sends a HEAD request | | whenOptions(url) | Sends an OPTIONS request | | sendAndExpect(method, url, fn, overrides?) | Sends a request and runs assertions |

> ❗️ Note: `givenBody` method is now unified with multipart form-data.

---
---

## ✅ Response Validator API

After each request, you receive a `ResponseValidator` object with the following methods:

| Method | Description |
|--------|-------------|
| `thenExpectStatus(code)` | Assert HTTP status code |
| `thenExpectBody(path, val)` | Assert JSONPath value |
| `thenExpectBodyContains(fragment)` | Assert body contains key-values |
| `thenValidateBody(schema)` | Joi schema validation |
| `thenExpectHeader(k, v)` | Assert response header |
| `thenExtract(path)` | Extract JSONPath value |
| `catchAndLog(fn)` | Wrap and log assertion failures |
| `getResponse()` | Raw Axios response |
| `getRequestConfig()` | Request config used |
| `wasFailure()` | True if request failed |
| `runAssertions()` | run multiple expectations (assertions) against a response object |

---

## 🧪 Examples by Method

POST with JSON and Assertions

await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .givenBody({ title: "foo", body: "bar", userId: 1 })
  .whenPost("/posts")
  .thenExpectStatus(201)
  .thenExpectBody("$.title", "foo");

GET with Query Params

await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .givenQueryParam("userId", "1")
  .whenGet("/posts")
  .thenExpectStatus(200);

PUT with Header

await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .givenHeader("Authorization", "Bearer token")
  .givenBody({ title: "updated title" })
  .whenPut("/posts/1")
  .thenExpectStatus(200);

PATCH and Body Fragment Check

await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .givenBody({ title: "patched" })
  .whenPatch("/posts/1")
  .thenExpectBodyContains({ title: "patched" });

DELETE

await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .whenDelete("/posts/1")
  .thenExpectStatus(200);

HEAD

await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .whenHead("/posts/1")
  .thenExpectStatus(200);

OPTIONS

await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .whenOptions("/posts")
  .thenExpectStatus(204);

🧩 Logging

await fluentRest()
  .enableFileLogging(true)
  .setLogLevel("debug")
  .whenGet("/posts/1")
  .thenExpectStatus(200);

Log levels:

  • "debug" – log everything
  • "info" – request + response
  • "none" – silence

Logs are written to logs/restassured-<pid>.log by default unless overridden via configureDefaults.


🛠️ Global Defaults

import { configureDefaults } from "fluentrest-ts";

configureDefaults({
  timeout: 15000,
  logLevel: "info",
  logFilePath: "logs/custom.log",
});

You may also use .env variables:

RA_TIMEOUT=20000
RA_LOG_LEVEL=debug
RA_LOG_FILE=logs/run.log
RA_BASE_URL=https://jsonplaceholder.typicode.com

Ensure .env is loaded before any fluentrest-ts import.


📤 Combined Send & Assert (Compact Tests)

await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .sendAndExpect("post", "/posts", res => {
    res.thenExpectStatus(201).thenExpectBody("$.title", "foo");
  }, {
    headers: { "Content-Type": "application/json" },
    body: { title: "foo", body: "bar", userId: 1 }
  });

🚀 runAssertions - FluentRest Soft Assertion Utility

- Run multiple assertions on a single response.
- Continue executing all checks even if one fails.
- Aggregate failures and throw a combined error.
- Use with `.catchAndLog()` for cleaner test output and logging.

const res = await fluentRest().whenGet('/posts/1');

await res.runAssertions([
  r => r.thenExpectStatus(404),                    // will fail
  r => r.thenExpectBody('$.title', 'wrong')       // will also fail
]).catchAndLog(err => {
  expect(err.message).toContain('Multiple assertion failures');
});

🛡️ Assertion Wrapper: catchAndLog()

Use catchAndLog() to wrap custom assertions or logic. If it throws, the error will be logged with context.

const response = await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .whenGet("/posts/1");

response.catchAndLog(() => {
  const body = response.thenExtract("$.body");
  if (!body || body.length < 10) {
    throw new Error("Body is unexpectedly short");
  }
});

This is useful for edge-case checks or combining your own logic with the library’s logging system.


🧪 Extract and Reuse Response Data

const post = await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .givenBody({ title: "foo", body: "bar", userId: 1 })
  .whenPost("/posts");

const id = post.thenExtract("$.id");

await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .whenGet(`/posts/${id}`)
  .thenExpectStatus(200);

🧪 Joi Schema Validation Example

Use Joi to validate the full response body structure:

import Joi from "joi";

const schema = Joi.object({
  id: Joi.number().required(),
  title: Joi.string().required(),
  body: Joi.string().required(),
  userId: Joi.number().required()
});

await fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .whenGet("/posts/1")
  .thenValidateBody(schema);

🔍 Debugging

To inspect the request before sending:

fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .givenBody({ name: "debug" })
  .debug();

🧩 Request Snapshot Debugging

You can print or retrieve a snapshot of the full request configuration:

const builder = fluentRest()
  .setBaseUrl("https://jsonplaceholder.typicode.com")
  .givenHeader("X-Debug", "true")
  .givenQueryParam("debug", "1");

builder.debug(); // Console output

const snapshot = builder.getSnapshot();
console.log("Snapshot method:", snapshot.method);

This is useful for troubleshooting test cases, comparing requests, or snapshot testing.


🌐 Proxy Support

🔧 Global Proxy Configuration

Apply a proxy to all requests by default:

configureDefaults({
  proxy: {
    host: 'proxy.example.com',
    port: 8080,
    auth: {
      username: 'user',
      password: 'pass'
    }
  }
});

🚀 Per-Request Proxy Override

Override the global proxy using .setProxy():

const response = await fluentRest()
  .setProxy({
    host: 'custom.proxy.com',
    port: 3128,
    auth: {
      username: 'customUser',
      password: 'customPass'
    }
  })
  .whenGet('/posts/1');

🛑 Disabling Proxy for a Specific Request

Disable proxy even if one is globally configured:

const response = await fluentRest()
  .clearProxy()
  .whenGet('/health');

🔁 Proxy Resolution Order

  1. setProxy(...) – per-request override
  2. configureDefaults(...) – global default
  3. No proxy – if .clearProxy() is used

📦 Proxy Object Format

The proxy object must match Axios's format:

{
  host: string;
  port: number;
  auth?: {
    username: string;
    password: string;
  };
  protocol?: 'http' | 'https';
}

🔍 Utilities and Tools

  • configureDefaults() – Global config via code
  • .env support – Set RA_TIMEOUT, RA_LOG_LEVEL, etc.
  • debug() – Print live config to terminal
  • getSnapshot() – Inspect request config object
  • thenExtract(path) – Pull specific data from response
  • catchAndLog(fn) – Wrap and log assertion errors with context

🧱 Designed For

  • TypeScript-first testing
  • Frameworks like Playwright / Vitest / Jest / Mocha
  • CI/CD environments
  • Readable and compact API test syntax

📦 Dependencies

| Package | Purpose | |----------------|-----------------------------------| | Axios | HTTP client | | JSONPath-Plus | JSON extraction from response | | Joi | Schema validation | | Form-Data | Multipart/form-data support | | Chalk | Terminal logging colors |


📄 License

MIT – Use, extend, and enjoy!