Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .commitlintrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# @see https://commitlint.js.org/reference/configuration.html

extends:
["@commitlint/config-conventional"]
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# @see https://editorconfig.org
# @see https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig

charset = utf-8
[*]
root = true
[*.{cjs,es,es6,js,jsm,json,json5,json6,jsonc,jsox,jsx,mjs,node,ts,tsx}]
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 120
trim_trailing_whitespace = true
[*.md]
# @see https://github.com/Microsoft/vscode/issues/1679#issuecomment-323608456
trim_trailing_whitespace = false
5 changes: 5 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"printWidth": 100,
"singleQuote": true,
"trailingComma": "all"
}
60 changes: 51 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,63 @@
# API Tools

Tools to work with a REST API (WebSocket and GraphQL support is on the way).

This package allows to:
* Request specific endpoint with parameters and options.
* Specify parameters and options within the settings or directly in CLI.
* Set default parameters and options.
* Validate parameters and options before a request.
* Parse API response by filtering, searching and mapping JSON data.
* Debug signature, request headers, submit data,
* Analyze API response time, HTTP status and returned code-description.
* Take snapshots of API response with timestamp to track structure changes.
* Test API response by validating the structure of an API response against a JSON-schema.

## Setup

### Clone

Clone Git repository:
```bash
git clone
```

### Node.js

Use appropriate Node.js version:
```bash
nvm use
```

### Install

Install modules for usage:
```bash
npm i --production
```

Install modules for development:
```bash
nvm i
```

Install modules for pull requests:
```bash
npm ci
```

## Usage

General syntax of commands:
```bash
node <api> <handler>[ <params>][ <key=value>][ <flag>]
node <api> <handler>[ <parameter>][ <parameterKey=parameterValue>][ --<option>]
```

Full list of commands, params and options depends on implementation.
Full list of commands, params and options depends on API implementation.

## Request
### Request

To run a scenario related to request processing of an API, change directory:
To run a scenario related to API request processing, change directory:
```bash
cd request
```
Expand All @@ -25,13 +68,12 @@ node bybit.mjs
node bybit.mjs orderAll
node bybit.mjs order 1234567890123456789
node bybit.mjs order 1234567890123456789 symbol=BTC
node bybit.mjs order 1234567890123456789 symbol=BTC --snapshot
node bybit.mjs order 1234567890123456789 symbol=BTC --snap
```

### Response

## Response

To run a scenario related to response processing of an API, change directory:
To run a scenario related to API response processing, change directory:
```bash
cd response
```
Expand All @@ -42,5 +84,5 @@ node bybit.mjs
node bybit.mjs orderAll
node bybit.mjs order 1234567890123456789
node bybit.mjs order 1234567890123456789 symbol=BTC
node bybit.mjs order 1234567890123456789 symbol=BTC --snapshot
node bybit.mjs order 1234567890123456789 symbol=BTC --snap
```
17 changes: 17 additions & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"baseUrl": ".",
"checkJs": true,
"lib": [
"es5", "es6", "dom", "dom.iterable"
],
"module": "Node16",
"moduleResolution": "Node16",
"paths": {
"types/*": ["./types/*"]
},
"target": "ES6"
},
"exclude": ["node_modules"],
"include": ["**/*.mjs"]
}
6 changes: 3 additions & 3 deletions lib/authentication.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**!
* Sign a request by various methods.
* Sign a request by the specified method.
*
* @module lib/authentication
* @see https://nodejs.org/api/buffer.html#buffers-and-character-encodings
Expand All @@ -26,7 +26,7 @@ export const blind = (secret, hidden = "full", visibility = 2) => {
};

/**
* Sign a request with Hash-based Message Authentication Code.
* Sign a request by Hash-based Message Authentication Code.
*/
export const signHmac = (encoding, payload, secret, hidden) => {
const nonce = nodeCrypto.createHmac("sha256", secret).update(payload),
Expand All @@ -44,7 +44,7 @@ export const signHmac = (encoding, payload, secret, hidden) => {
};

/**
* Sign a request with JSON Web Token.
* Sign a request by JSON Web Token.
*/
export const signJwt = (encoding, payload, secret, key) => {
const nonce = nodeCrypto.randomBytes(16).toString(encoding),
Expand Down
9 changes: 2 additions & 7 deletions lib/fetch.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**!
* Fetch data from an endpoint with parameters.
* Fetch data from a REST API endpoint with parameters.
*
* @module lib/fetch
*/
Expand Down Expand Up @@ -50,11 +50,6 @@ export const fetchData = (method, url, data, headers) => {
try {
json = JSON.parse(text);
} catch (error) {
/* json = {
result: {},
retCode: -1,
retMsg: text || error.message
}; */
json = text || error.message;
}

Expand All @@ -68,7 +63,7 @@ export const fetchData = (method, url, data, headers) => {
entryHeaders = (response) => {
const entries = response.headers.entries(),
/**
* Create new shallow-copied Array instance from Headers iterator object to map lower cased header keys.
* Create new shallow-copied array from Headers iterator object to map lower cased header keys.
*/
array = Array.from(entries, ([key, value]) => [toPascalCase(key), value]),
headers = Object.fromEntries(array)
Expand Down
56 changes: 21 additions & 35 deletions lib/string.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**!
* String related methods for common application wide use cases.
* String related methods for common application use cases.
*
* @format
*/
Expand All @@ -11,57 +11,43 @@
* @returns {object} Complementary expressions.
*/
export const complementary = (template, expressions) => {
const complementaryExpressions = Object.keys(expressions).reduce((accum, key) =>
const result = Object.keys(expressions).reduce((accum, key) =>
(template.match(/{[A-z_]+}/g)?.includes("{" + key + "}") ? accum[key] = expressions[key] : accum, accum)
, {})

return complementaryExpressions
return result
}

/**
* Find supplementary expressions (not found in a template).
* Interpolate a string as template literal.
* @param {string} template String as template literal.
* @param {object} expressions Expressions to be embedded within a template.
* @returns {object} Supplementary expressions.
* @returns {string} Interpolated string.
*/
export const supplementary = (template, expressions) => {
const supplementaryExpressions = Object.keys(expressions).reduce((accum, key) =>
(!template.match(/{[A-z_]+}/g)?.includes("{" + key + "}") ? accum[key] = expressions[key] : accum, accum)
, {})
export const interpolate = (template, expressions) => {
const result = template.replace(/\${[^}]+}/g, (match) => expressions[match.slice(2, -1)]);

return supplementaryExpressions
return result
}

/**
* Interpolate a string as template literal.
* Find supplementary expressions (not found in a template).
* @param {string} template String as template literal.
* @param {object} expressions Expressions to be embedded within a template.
* @returns {string} Interpolated string.
* @returns {object} Supplementary expressions.
*/
export const interpolate = (template, expressions) => {
const interpolatedString = template.replace(/\${[^}]+}/g, (match) => expressions[match.slice(2, -1)]);
export const supplementary = (template, expressions) => {
const result = Object.keys(expressions).reduce((accum, key) =>
(!template.match(/{[A-z_]+}/g)?.includes("{" + key + "}") ? accum[key] = expressions[key] : accum, accum)
, {})

return interpolatedString
return result
}

/**
* Splice (remove or replace) characters from a string and/or adding new characters.
* The method results differ from the native array splice for edge cases.
*
* @public
* @param {string} str Source string to be spliced.
* @param {number} [start] Index at which to start splicing.
* @param {number} [count] Number of characters in string to remove from start.
* @param {string} [chars] Characters to add to string, beginning from start.
* @returns {string} Spliced string.
*/
export function splice(str, start = 0, count = 0, chars = "") {
return str.slice(0, start) + chars + str.slice(start + count);
}
export const toPascalCase = (string) => {
const result = string.replace(/\w+/g, (word) =>
word[0].toUpperCase() + word.slice(1).toLowerCase()
);

export default {
encodeToDataUri,
formatGroup,
interpolate,
splice,
};
return result;
}
2 changes: 1 addition & 1 deletion lib/template.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**!
* Collection of commonly used template literals for dynamic filling.
* Commonly used template literals for dynamic filling.
*
* @module lib/template
*/
Expand Down
21 changes: 10 additions & 11 deletions lib/utility.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**!
* Utility methods for common tasks.
*
* Utility methods for common application use cases.
*
* @module lib/utility
*/

Expand All @@ -21,17 +21,14 @@ export const obtainName = (path, pathAll) => {
* Parse process argument vectors to usable handler, parameters and options.
*/
export const parseArguments = () => {
const options = {};
let args = process.argv.slice(3).map(param => {
/** Param with defined value. */
const options = {},
args = process.argv.slice(3).map(param => {
/** A param with defined value. */
if (param.includes("=")) {
const [key, value] = param.split("=");

return { [key]: value };
}
/* if (!global.apiTools) {
global.apiTools = {}
} */
if (param.includes("--head")) {
/** @todo Resolve side effect. */
options.isHeaders = true
Expand All @@ -53,12 +50,14 @@ export const parseArguments = () => {
, {});

if (Object.keys(paramsDefined).length) params.push(paramsDefined);
args = {

const result = {
handler: process.argv[2],
options,
params
};
dirObject("arguments", args);

return args
dirObject("arguments", result);

return result
}
2 changes: 1 addition & 1 deletion request.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Do requests for specified exchanges.
* Do API requests for specified exchanges.
*
* @module request
*/
Expand Down
2 changes: 1 addition & 1 deletion response.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Do response aggregation from snapshots for specified exchanges.
* Do API response aggregation from snapshots for specified exchanges.
*
* @module response
*/
Expand Down
2 changes: 1 addition & 1 deletion response/coinbase/schema/market/history.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Market history schema for Coinbase Advanced API response structure.
* Market history JSON-schema for Coinbase Advanced API response structure.
*
* @module response/coinbase/market/history
* @see https://json-schema.org/draft/2020-12/release-notes
Expand Down
4 changes: 2 additions & 2 deletions response/validate.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Validate the structure of Coinbase Advanced API response against a schema.
*
* Test API response by validating the structure of an API response against a JSON-schema.
*
* @module request/validate
* @see https://ajv.js.org/guide/schema-language.html#draft-2019-09-and-draft-2020-12
*/
Expand Down