1.2.0 • Published 11 months ago
@toplo/api v1.2.0
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
npm i config
- create a config folder in the root of your project
- create a default.js file in it
- 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