1.2.0 • Published 11 months ago

@toplo/api v1.2.0

Weekly downloads
-
License
MIT
Repository
github
Last release
11 months ago

Install

npm install @toplo/api

Requirements

  • NodeJS version >= v15.4.0

Table of Contents

HotConfiguration

⬆️Top

If you want to easily configure the @toplo/api package

  1. npm i config
  2. create a config folder in the root of your project
  3. create a default.js file in it
  4. check this Example Config

HotRequests

⬆️Top

Supports all http methods


import { HotRequests } from "@toplo/api";

    const res = await HotRequests.get({
        url: "https://wisdoms-app.herokuapp.com/api/{myPath}",
        options: {
            timeout: 400,
            pathParams: { myPath: "getWisdom" },
            queryParams: { lang: "en" }
        }
    });

  // A successful response results in the following
  res: {
    success: true,
    status: 200,
    result: {
      sucess: true,
      wisdom: 'But he who gives them to him, the bad guys get along easily, one does not live on bread alone.',
      lang: 'en'
    },
    elapsed: 374
  }
  // Or if it times out
  res: {
    success: false,
    error: 'The operation was aborted.',
    status: 500,
    elapsed: 422
  }

Response is one of the two:

type HttpSuccessResponse<T> = {
    success: true;
    status: number;
    elapsed: number;
    result: T;
};

type HttpErrorResponse<T> = {
    success: false;
    error: string;
    elapsed: number;
    status: number;
    result?: T;
};

HotWatch

⬆️Top

For timing


import { HotWatch } from "@toplo/api";

const myWatch = new HotWatch();

(() => Promise)(); // Some action

myWatch.getElapsedMs(); // elapsed miliseconds since construction
myWatch.getElapsedS(); // elapsed seconds since construction

HotUrl

⬆️Top

Build your URL from an already existing URL or a string with optional query params


import { HotUrl } from "@toplo/api";

// Results in "http://localhost:4444/base/path/somedynamicpath/?someQ=1"
HotUrl.build({
    base: "http://localhost:4444/{someBasePath}",
    path: "/path/{dynamic}/",
    pathParams: { someBasePath: "base", dynamic: "somedynamicpath" },
    queryParams: { someQ: "1"}
});

// Results in "Some text."
HotUrl.replacePathParams("Some {replacement}.", { replacement: "text" });

// All three result in http://localhost:4444/?query1=val1&query2=true
HotUrl.buildQuery("http://localhost:4444/", { query1: "val1", query2: true  });
HotUrl.buildQuery("http://localhost:4444", { query1: "val1", query2: true  });
HotUrl.buildQuery(new URL("http://localhost:4444/"), { query1: "val1", query2: true  });

// Nullables are ignored
// Results in http://localhost:4444/?query1=val1
HotUrl.buildQuery(new URL("http://localhost:4444/"), { query1: "val1", query2: undefined  });

// Domain can end with / or not
// Path can start with / or not
// Both result in "http://localhost:4444/some/path/params/"
HotUrl.buildFromString("http://localhost:4444/", "/some/path/params/");
HotUrl.buildFromString("http://localhost:4444", "some/path/params/");

HotLogger

⬆️Top

Log all you need


Example config:

    log: {
        level: "DEBUG",
        filters: [{
            key: "eventName",
            values: [
                "/_filterRoute"
            ]
        }],
        serializers: [{
            key: "eventName",
            values: ["/serializeThisEvent"],
            modifiers: [{ properties: ["data.smh"] }]
        }]
    }
import { HotLogger } from "@toplo/api";

const myLogger = HotLogger.createLogger("MyLoggerContext");

myLogger.trace("Some trace msg");
// Will not be logged due to the log.level = "DEBUG" from the above configuration

myLogger.debug("Some trace filter route", { someKey: "/_filterRoute" });
// Will not be logged due to the log.filters[0].key = "someKey" with value "/_filterRoute"

myLogger.debug("Some info msg", { data: { smh: "ye"}, someKey: "/serializeThisEvent" });
// [{"Message":"Some info msg","LogLevel":"Debug","SourceContext":"MyLoggerContext","Properties":{"ProcessID":22172,"AppVersion":"1.0.3","AppName":"@toplo/api","AppId":"development-@toplo/api","Env":"development","data":{"smh":"********"},"someKey":"/serializeThisEvent"},"LogTimestamp":"2021-12-10T06:46:17.478Z"}]

myLogger.error("Some err msg", { err: new Error("Test err"), data: { smh: "ye"}, someKey: "/serializeThisEvent" });
//[{"Message":"Some err msg","LogLevel":"Error","SourceContext":"MyLoggerContext","ExceptionMessage":"Test err","ExceptionStacktrace":"Error: Test err\n    at Object.<anonymous> (G:\\hehe\\@toplo/api\\@toplo/api\\index.js:19:39)\n    at Module._compile (internal/modules/cjs/loader.js:1068:30)\n    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)\n    at Module.load (internal/modules/cjs/loader.js:933:32)\n    at Function.Module._load (internal/modules/cjs/loader.js:774:14)\n    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)\n    at internal/main/run_main_module.js:17:47","Properties":{"ProcessID":4444,"AppVersion":"1.0.3","AppName":"@toplo/api","AppId":"development-@toplo/api","Env":"development","data":{"smh":"********"},"someKey":"/serializeThisEvent"},"LogTimestamp":"2021-12-10T06:51:21.375Z"}]

HotObj

⬆️Top

Object utils


import { HotObj } from "@toplo/api";

const a = { 1: "one", "one": 1 };
const b = { 1: "one", "one": 1 };

HotObj.shallowEquals(a, b); // true

const someObj = {
    prop: "val",
    propTwo: "val2",
    propThree: "val3"
};
const result = HotObj.extract(someObj, ["propTwo", "propThree"]);; // { propTwo: "val2", propThree: "val3" }

// Type def for extract is inferred
(method) HotObj.extract<{
    prop: string;
    propTwo: string;
    propThree: string;
}, "propTwo" | "propThree">(obj: {
    prop: string;
    propTwo: string;
    propThree: string;
}, keys: ("propTwo" | "propThree")[]): {
    propTwo: string;
    propThree: string;
}

HotObj.hasProp(a, 1); // true
HotObj.hasProp(a, "one"); // true
HotObj.getValue(a, "one"); // 1
HotObj.getValue(a, "e"); // Argument of type '"e"' is not assignable to parameter of type '"one" | 1'.
// Type definition is inferred:
HotObj.getValue<{
    1: string;
    one: number;
}, "one" | 1>(obj: {
    1: string;
    one: number;
}, key: "one" | 1): string | number | undefined


const nullableObj = {
    ble: "undefined",
    notaNum: Number("undefined"),
    thisIsFine: 1
};

HotObj.cleanUpNullables(nullableObj); // { thisIsFine: 1 }

HotPromise

⬆️Top

Promise utils


import { HotPromise } from "@toplo/api";

// Results in
// {
//  isGood: false,
//  error: Timed out in 1000 ms.
// }
//
const promiseTimeout = async () => {
    try {
        await HotPromise.promiseTimeout(HotPromise.delay(1010), 1000);
        return { isGood: true, result: "good" };
    } catch (error) {
        return { isGood: false, result: error };
    }
};


// Results in
// {
//  isGood: false,
//  error: Error: Fail, total tries: 5
// }
//
const runTillSuccess = async () => {
    try {
        // Default retry times are 5, you can pass in "forever" to retry indefinitely
        // retries will s⬆️Top as soon as isGood: true has been returned by the retried action
        const ehee = await HotPromise.runTillSuccess(promiseTimeout);
        return { isGood: true, result: { code: "OK", ehee } };
    } catch (error) {
        return { isGood: false, error };
    }
};

HotServer

⬆️Top

Simple http server

Please check HotServer.e2e.test.ts for a more broad example usage.

import { HotServer } from "@toplo/api";

new HotServer({
    host: "localhost", // if not passed, taken from config
    port: 5433, // if not passed, taken from config
    staticRoute: {
        html: "./tests/mocks/test.html",
        route: "/staticHtml"
    },
    routes: {
        "/json": {
            onSuccess: () => {
                return {
                    result: {
                        some: "record"
                    }
                };
            }
        },
        "/text": {
            responseHeaders: {
                "Content-Type": "text/plain"
            },
            onSuccess: () => {
                return {
                    result: "My text response."
                };
            }
        }
    }
});

release/1.4.1

1.2.0

11 months ago

1.1.8

1 year ago

1.1.7

1 year ago

1.1.6

1 year ago

1.1.5

1 year ago

1.1.4

1 year ago

1.1.3

2 years ago

1.1.2

2 years ago

1.1.1

2 years ago

1.1.0

2 years ago

1.0.9

2 years ago

1.0.8

2 years ago

1.0.7

2 years ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.3

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

0.0.1

2 years ago