barehttp 1.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +185 -28
- package/lib/context/execution.d.ts +7 -0
- package/lib/context/execution.js +14 -0
- package/lib/context/index.d.ts +10 -0
- package/lib/context/index.js +46 -0
- package/lib/env.d.ts +5 -0
- package/lib/env.js +5 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +3 -0
- package/lib/logger/index.d.ts +16 -0
- package/lib/logger/index.js +26 -0
- package/lib/logger/serializers.d.ts +28 -0
- package/lib/logger/serializers.js +78 -0
- package/lib/middlewares/cookies/cookie-manager.d.ts +25 -0
- package/lib/middlewares/cookies/cookie-manager.js +68 -0
- package/lib/middlewares/cookies/signer.d.ts +8 -0
- package/lib/middlewares/cookies/signer.js +25 -0
- package/lib/middlewares/cors/cors.d.ts +38 -0
- package/lib/middlewares/cors/cors.js +164 -0
- package/lib/request.d.ts +84 -0
- package/lib/request.js +260 -0
- package/lib/schemas/custom-schema.d.ts +32 -0
- package/lib/schemas/custom-schema.js +62 -0
- package/lib/schemas/dirty-tsm.d.ts +1 -0
- package/lib/schemas/dirty-tsm.js +199 -0
- package/lib/schemas/generator.d.ts +7 -0
- package/lib/schemas/generator.js +179 -0
- package/lib/schemas/helpers.d.ts +27 -0
- package/lib/schemas/helpers.js +40 -0
- package/lib/schemas/json-schema.d.ts +2 -0
- package/lib/schemas/json-schema.js +48 -0
- package/lib/schemas/openami-schema.d.ts +2 -0
- package/lib/schemas/openami-schema.js +59 -0
- package/lib/schemas/project.d.ts +1 -0
- package/lib/schemas/project.js +1 -0
- package/lib/server.d.ts +154 -0
- package/lib/server.js +396 -0
- package/lib/utils/content-type.d.ts +54 -0
- package/lib/utils/content-type.js +54 -0
- package/lib/utils/http-methods.d.ts +11 -0
- package/lib/utils/http-methods.js +9 -0
- package/lib/utils/index.d.ts +4 -0
- package/lib/utils/index.js +4 -0
- package/lib/utils/safe-json.d.ts +2 -0
- package/lib/utils/safe-json.js +18 -0
- package/lib/utils/status-codes.d.ts +339 -0
- package/lib/utils/status-codes.js +339 -0
- package/lib/utils/status-phrases.d.ts +338 -0
- package/lib/utils/status-phrases.js +339 -0
- package/lib/websocket.d.ts +36 -0
- package/lib/websocket.js +176 -0
- package/package.json +65 -33
- package/.eslintrc.js +0 -47
- package/.github/workflows/release.yml +0 -27
- package/.jest-setup.js +0 -1
- package/jest.config.js +0 -8
- package/prettier.config.js +0 -6
- package/src/context/context.test.ts +0 -30
- package/src/context/execution.ts +0 -17
- package/src/context/index.ts +0 -61
- package/src/env.ts +0 -5
- package/src/examples/bare-http.ts +0 -36
- package/src/examples/express.ts +0 -11
- package/src/examples/fastify.ts +0 -18
- package/src/index.ts +0 -4
- package/src/logger/index.ts +0 -67
- package/src/logger/serializers.test.ts +0 -186
- package/src/logger/serializers.ts +0 -109
- package/src/middlewares/cookies/cookie-manager.ts +0 -86
- package/src/middlewares/cookies/signer.ts +0 -30
- package/src/report.ts +0 -25
- package/src/request.test.ts +0 -143
- package/src/request.ts +0 -277
- package/src/server.integration.test.ts +0 -296
- package/src/server.middlewares.test.ts +0 -93
- package/src/server.routes.test.ts +0 -71
- package/src/server.ts +0 -450
- package/src/utils/content-type.ts +0 -59
- package/src/utils/index.ts +0 -2
- package/src/utils/safe-json.ts +0 -17
- package/src/utils/status-codes.ts +0 -339
- package/src/utils/status-phrases.ts +0 -339
- package/tsconfig.json +0 -24
package/package.json
CHANGED
|
@@ -1,16 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "barehttp",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "Lightweight and fast
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Lightweight and fast Node.js web server",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./lib/index.d.ts",
|
|
10
|
+
"import": "./lib/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
6
13
|
"directories": {
|
|
7
14
|
"lib": "lib",
|
|
8
15
|
"test": "__tests__"
|
|
9
16
|
},
|
|
17
|
+
"files": [
|
|
18
|
+
"lib"
|
|
19
|
+
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=22"
|
|
23
|
+
},
|
|
10
24
|
"scripts": {
|
|
11
|
-
"build": "rm -rf ./lib && tsc",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
25
|
+
"build": "rm -rf ./lib && tsc -p tsconfig.build.json",
|
|
26
|
+
"build:dev": "rm -rf ./dev-lib && tsc -p tsconfig.dev.json",
|
|
27
|
+
"test": "jest --coverage",
|
|
28
|
+
"lint": "eslint ./src --fix",
|
|
29
|
+
"release": "semantic-release -e ./.releaserc.json"
|
|
14
30
|
},
|
|
15
31
|
"keywords": [
|
|
16
32
|
"nodejs",
|
|
@@ -21,37 +37,53 @@
|
|
|
21
37
|
"lightweight",
|
|
22
38
|
"fast"
|
|
23
39
|
],
|
|
24
|
-
"author": "Konstantin
|
|
40
|
+
"author": "Konstantin <29006524+sckv@users.noreply.github.com>",
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git+https://github.com/sckv/barehttp.git"
|
|
44
|
+
},
|
|
25
45
|
"license": "MIT",
|
|
26
46
|
"dependencies": {
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"cookie
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
47
|
+
"ajv": "^8.17.1",
|
|
48
|
+
"callsites": "^4.2.0",
|
|
49
|
+
"cookie": "^1.1.1",
|
|
50
|
+
"cookie-signature": "^1.2.2",
|
|
51
|
+
"find-my-way": "^9.3.0",
|
|
52
|
+
"hyperid": "^3.3.0",
|
|
53
|
+
"lodash": "^4.17.21",
|
|
54
|
+
"pino": "^10.1.0",
|
|
55
|
+
"pino-pretty": "^13.1.3",
|
|
56
|
+
"ts-morph": "^27.0.2",
|
|
57
|
+
"ws": "^8.18.3"
|
|
34
58
|
},
|
|
35
59
|
"devDependencies": {
|
|
36
|
-
"@
|
|
37
|
-
"@
|
|
38
|
-
"@
|
|
39
|
-
"@types/
|
|
40
|
-
"@types/
|
|
41
|
-
"@types/jest": "^
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
44
|
-
"
|
|
45
|
-
"eslint": "^
|
|
46
|
-
"eslint
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"jest": "^
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
60
|
+
"@semantic-release/git": "^10.0.1",
|
|
61
|
+
"@semantic-release/github": "^12.0.2",
|
|
62
|
+
"@ts-morph/bootstrap": "^0.28.1",
|
|
63
|
+
"@types/cookie": "^0.6.0",
|
|
64
|
+
"@types/cookie-signature": "^1.1.2",
|
|
65
|
+
"@types/jest": "^30.0.0",
|
|
66
|
+
"@types/node": "^25.0.3",
|
|
67
|
+
"@types/pino": "^7.0.4",
|
|
68
|
+
"@types/ws": "^8.18.1",
|
|
69
|
+
"@typescript-eslint/eslint-plugin": "^8.50.1",
|
|
70
|
+
"@typescript-eslint/parser": "^8.50.1",
|
|
71
|
+
"axios": "^1.13.2",
|
|
72
|
+
"eslint": "^9.39.2",
|
|
73
|
+
"eslint-plugin-import": "^2.32.0",
|
|
74
|
+
"eslint-plugin-jest": "^29.11.0",
|
|
75
|
+
"express": "^5.2.1",
|
|
76
|
+
"fastify": "^5.6.2",
|
|
77
|
+
"jest": "^30.2.0",
|
|
78
|
+
"prettier": "^3.7.4",
|
|
79
|
+
"semantic-release": "^25.0.2",
|
|
80
|
+
"supertest": "^7.1.4",
|
|
81
|
+
"ts-jest": "^29.4.6",
|
|
82
|
+
"ts-node-dev": "^2.0.0",
|
|
83
|
+
"typescript": "^5.9.3"
|
|
84
|
+
},
|
|
85
|
+
"optionalDependencies": {
|
|
86
|
+
"bufferutil": "^4.1.0",
|
|
87
|
+
"utf-8-validate": "^6.0.6"
|
|
56
88
|
}
|
|
57
89
|
}
|
package/.eslintrc.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
parser: '@typescript-eslint/parser',
|
|
3
|
-
plugins: ['@typescript-eslint', 'jest', 'import'],
|
|
4
|
-
extends: [
|
|
5
|
-
'plugin:@typescript-eslint/eslint-recommended',
|
|
6
|
-
'plugin:@typescript-eslint/recommended',
|
|
7
|
-
'plugin:import/errors',
|
|
8
|
-
'plugin:import/warnings',
|
|
9
|
-
'plugin:import/typescript',
|
|
10
|
-
],
|
|
11
|
-
rules: {
|
|
12
|
-
// TS
|
|
13
|
-
'@typescript-eslint/no-var-requires': 0,
|
|
14
|
-
'@typescript-eslint/no-explicit-any': 0,
|
|
15
|
-
'@typescript-eslint/no-empty-function': 0,
|
|
16
|
-
'@typescript-eslint/generic-type-naming': 0,
|
|
17
|
-
'@typescript-eslint/explicit-function-return-type': 0,
|
|
18
|
-
'@typescript-eslint/explicit-module-boundary-types': 0,
|
|
19
|
-
'@typescript-eslint/prefer-namespace-keyword': 0,
|
|
20
|
-
'@typescript-eslint/no-non-null-assertion': 0,
|
|
21
|
-
'@typescript-eslint/no-use-before-define': 0,
|
|
22
|
-
'max-classes-per-file': ['error', 1],
|
|
23
|
-
// IMPORT
|
|
24
|
-
'import/prefer-default-export': 0,
|
|
25
|
-
'import/no-dynamic-require': 0,
|
|
26
|
-
'import/named': 2,
|
|
27
|
-
'import/namespace': 2,
|
|
28
|
-
'import/default': 2,
|
|
29
|
-
'import/export': 2,
|
|
30
|
-
'import/no-unresolved': 0,
|
|
31
|
-
'import/order': [
|
|
32
|
-
'error',
|
|
33
|
-
{
|
|
34
|
-
'newlines-between': 'always',
|
|
35
|
-
groups: ['external', 'internal', 'index', 'sibling', 'parent', 'builtin'],
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
'import/no-extraneous-dependencies': [
|
|
39
|
-
'error',
|
|
40
|
-
{
|
|
41
|
-
devDependencies: true,
|
|
42
|
-
optionalDependencies: false,
|
|
43
|
-
peerDependencies: false,
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
},
|
|
47
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
name: Release
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches:
|
|
5
|
-
- master
|
|
6
|
-
jobs:
|
|
7
|
-
release:
|
|
8
|
-
name: Release
|
|
9
|
-
runs-on: ubuntu-latest
|
|
10
|
-
steps:
|
|
11
|
-
- name: Checkout
|
|
12
|
-
uses: actions/checkout@v2
|
|
13
|
-
with:
|
|
14
|
-
fetch-depth: 0
|
|
15
|
-
- name: Setup Node.js
|
|
16
|
-
uses: actions/setup-node@v1
|
|
17
|
-
with:
|
|
18
|
-
node-version: 14.15.1
|
|
19
|
-
- name: Install dependencies
|
|
20
|
-
run: npm ci
|
|
21
|
-
- name: Run tests
|
|
22
|
-
run: npm test
|
|
23
|
-
- name: Release
|
|
24
|
-
env:
|
|
25
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
26
|
-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
27
|
-
run: npm run release
|
package/.jest-setup.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
process.setMaxListeners(999);
|
package/jest.config.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
preset: 'ts-jest',
|
|
3
|
-
testEnvironment: 'node',
|
|
4
|
-
collectCoverageFrom: ['<rootDir>/src/**/*.ts'],
|
|
5
|
-
coveragePathIgnorePatterns: ['<rootDir>/src/examples'],
|
|
6
|
-
testMatch: ['<rootDir>/src/**/**.test.ts'],
|
|
7
|
-
setupFiles: ['<rootDir>/.jest-setup.js'],
|
|
8
|
-
};
|
package/prettier.config.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { context, enableContext, newContext } from './index';
|
|
2
|
-
|
|
3
|
-
test("Do not create execution if it's not enabled", () => {
|
|
4
|
-
newContext('newContext');
|
|
5
|
-
|
|
6
|
-
expect(context.current).toBeUndefined();
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
test('Starts context and attaches an Execution class', () => {
|
|
10
|
-
const hook = enableContext();
|
|
11
|
-
|
|
12
|
-
newContext('newContext');
|
|
13
|
-
|
|
14
|
-
expect(context.current?.id).toEqual(expect.any(String));
|
|
15
|
-
expect(context.current?.type).toBe('newContext');
|
|
16
|
-
|
|
17
|
-
hook.disable();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
test('Execution class store exists and can store values', () => {
|
|
21
|
-
const hook = enableContext();
|
|
22
|
-
|
|
23
|
-
newContext('newContext');
|
|
24
|
-
|
|
25
|
-
context.current?.store.set('store', 'value');
|
|
26
|
-
|
|
27
|
-
expect(context.current?.store.get('store')).toBe('value');
|
|
28
|
-
|
|
29
|
-
hook.disable();
|
|
30
|
-
});
|
package/src/context/execution.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import hyperid from 'hyperid';
|
|
2
|
-
|
|
3
|
-
const generateId = hyperid();
|
|
4
|
-
|
|
5
|
-
export class Execution {
|
|
6
|
-
id: string;
|
|
7
|
-
type: string;
|
|
8
|
-
store: Map<string, string | number>;
|
|
9
|
-
headers: Map<string, string | number>;
|
|
10
|
-
|
|
11
|
-
constructor(type: string) {
|
|
12
|
-
this.id = generateId();
|
|
13
|
-
this.type = type;
|
|
14
|
-
this.store = new Map<string, string>();
|
|
15
|
-
this.headers = new Map<string, string>();
|
|
16
|
-
}
|
|
17
|
-
}
|
package/src/context/index.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { Execution } from './execution';
|
|
2
|
-
|
|
3
|
-
import asyncHooks from 'async_hooks';
|
|
4
|
-
|
|
5
|
-
const running = new Map<number, Execution>();
|
|
6
|
-
const previous = new Map<number, Execution>();
|
|
7
|
-
|
|
8
|
-
type Context = {
|
|
9
|
-
current?: Execution;
|
|
10
|
-
enabled: boolean;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const newContext = (type: string) => {
|
|
14
|
-
if (!context.enabled) return;
|
|
15
|
-
context.current = new Execution(type);
|
|
16
|
-
running.set(asyncHooks.executionAsyncId(), context.current);
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const context: Context = {
|
|
20
|
-
enabled: false,
|
|
21
|
-
} as any;
|
|
22
|
-
|
|
23
|
-
function init(asyncId: number, _type: string, triggerAsyncId: number) {
|
|
24
|
-
if (running.get(triggerAsyncId)) {
|
|
25
|
-
running.set(asyncId, running.get(triggerAsyncId)!);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function before(asyncId: number) {
|
|
30
|
-
if (!running.get(asyncId)) return;
|
|
31
|
-
|
|
32
|
-
previous.set(asyncId, context.current!);
|
|
33
|
-
context.current = running.get(asyncId);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function after(asyncId: number) {
|
|
37
|
-
if (!running.get(asyncId)) return;
|
|
38
|
-
|
|
39
|
-
context.current = previous.get(asyncId);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function destroy(asyncId: number) {
|
|
43
|
-
if (running.get(asyncId)) {
|
|
44
|
-
running.delete(asyncId);
|
|
45
|
-
previous.delete(asyncId);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const hook = asyncHooks.createHook({
|
|
50
|
-
init,
|
|
51
|
-
before,
|
|
52
|
-
after,
|
|
53
|
-
destroy,
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
const enableContext = () => {
|
|
57
|
-
context.enabled = true;
|
|
58
|
-
return hook.enable();
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export { context, newContext, enableContext };
|
package/src/env.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { BareHttp, logMe, context } from '../index';
|
|
2
|
-
|
|
3
|
-
const app = new BareHttp({ logging: true });
|
|
4
|
-
|
|
5
|
-
const wait = () => new Promise((resolve) => setTimeout(resolve, 5000));
|
|
6
|
-
app.route.get({
|
|
7
|
-
route: '/route',
|
|
8
|
-
options: { timeout: 2000 },
|
|
9
|
-
handler: async (flow) => {
|
|
10
|
-
flow.cm?.setCookie('MY KOOKIE', 'value', { domain: 'localhost' });
|
|
11
|
-
await wait();
|
|
12
|
-
// throw new Error('just fail');
|
|
13
|
-
return 'JUST MESSAGE 2';
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
app.route.post({
|
|
18
|
-
route: '/route',
|
|
19
|
-
handler: async function routeV1(flow) {
|
|
20
|
-
return 'JUST MESSAGE';
|
|
21
|
-
},
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
app
|
|
25
|
-
.use((flow) => {
|
|
26
|
-
return;
|
|
27
|
-
})
|
|
28
|
-
.use(async (flow) => {
|
|
29
|
-
return;
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
console.log(app.getRoutes());
|
|
33
|
-
|
|
34
|
-
app.start((address) => {
|
|
35
|
-
console.log(`BareHttp started at ${address}`);
|
|
36
|
-
});
|
package/src/examples/express.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const express = require('express');
|
|
2
|
-
const app = express();
|
|
3
|
-
const port = 3001;
|
|
4
|
-
|
|
5
|
-
app.get('/route', (req, res) => {
|
|
6
|
-
res.send('JUST RESPONSE');
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
app.listen(port, () => {
|
|
10
|
-
console.log(`Example app listening at http://localhost:${port}`);
|
|
11
|
-
});
|
package/src/examples/fastify.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
const fastify = require('fastify')({
|
|
2
|
-
logger: true,
|
|
3
|
-
});
|
|
4
|
-
|
|
5
|
-
// Declare a route
|
|
6
|
-
fastify.get('/route', function (request, reply) {
|
|
7
|
-
reply.send('JUST RESPONSE');
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
// Run the server!
|
|
11
|
-
fastify.listen(3002, function (err, address) {
|
|
12
|
-
if (err) {
|
|
13
|
-
fastify.log.error(err);
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
16
|
-
console.log('rutting server');
|
|
17
|
-
fastify.log.info(`server listening on ${address}`);
|
|
18
|
-
});
|
package/src/index.ts
DELETED
package/src/logger/index.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import pino, { destination } from 'pino';
|
|
2
|
-
|
|
3
|
-
import { serializeLog, serializeHttp } from './serializers';
|
|
4
|
-
|
|
5
|
-
import { envs } from '../env';
|
|
6
|
-
|
|
7
|
-
const asyncDest = envs.isProd ? [destination({ sync: false })] : [];
|
|
8
|
-
|
|
9
|
-
const pinoCommonOptions = {
|
|
10
|
-
timestamp: () => `,"time":"${new Date()[envs.isProd ? 'toISOString' : 'toLocaleTimeString']()}"`,
|
|
11
|
-
formatters: {
|
|
12
|
-
level: (label: string) => ({ level: label }),
|
|
13
|
-
},
|
|
14
|
-
messageKey: 'message',
|
|
15
|
-
prettyPrint: !envs.isProd,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const logger = pino(pinoCommonOptions, asyncDest[0]);
|
|
19
|
-
|
|
20
|
-
if (envs.isProd) {
|
|
21
|
-
setInterval(function () {
|
|
22
|
-
logger.flush();
|
|
23
|
-
}, 10000).unref();
|
|
24
|
-
|
|
25
|
-
const handler = pino.final(logger, (err, finalLogger, evt) => {
|
|
26
|
-
finalLogger.info(`${evt} caught`);
|
|
27
|
-
if (err) finalLogger.error(err, 'error caused exit');
|
|
28
|
-
process.exit(err ? 1 : 0);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
// catch all the ways node might exit
|
|
32
|
-
process.on('beforeExit', () => handler(null, 'beforeExit'));
|
|
33
|
-
process.on('exit', () => handler(null, 'exit'));
|
|
34
|
-
process.on('uncaughtException', (err) => handler(err, 'uncaughtException'));
|
|
35
|
-
process.on('SIGINT', () => handler(null, 'SIGINT'));
|
|
36
|
-
process.on('SIGQUIT', () => handler(null, 'SIGQUIT'));
|
|
37
|
-
process.on('SIGTERM', () => handler(null, 'SIGTERM'));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
interface LogMeFn {
|
|
41
|
-
(obj: unknown, ...args: []): void;
|
|
42
|
-
(msg: string, ...args: any[]): void;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
type LogMe = {
|
|
46
|
-
info: LogMeFn;
|
|
47
|
-
warn: LogMeFn;
|
|
48
|
-
error: LogMeFn;
|
|
49
|
-
fatal: LogMeFn;
|
|
50
|
-
debug: LogMeFn;
|
|
51
|
-
trace: LogMeFn;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export const logHttp = (...params: Parameters<typeof serializeHttp>) => {
|
|
55
|
-
const { level, logObject } = serializeHttp(...params);
|
|
56
|
-
logger[level](logObject);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// TODO: remove the test condition
|
|
60
|
-
export const logMe: LogMe = {
|
|
61
|
-
debug: (...args) => !envs.isTest && logger.debug(serializeLog(...args)),
|
|
62
|
-
info: (...args) => !envs.isTest && logger.info(serializeLog(...args)),
|
|
63
|
-
warn: (...args) => !envs.isTest && logger.warn(serializeLog(...args)),
|
|
64
|
-
error: (...args) => !envs.isTest && logger.error(serializeLog(...args)),
|
|
65
|
-
fatal: (...args) => !envs.isTest && logger.fatal(serializeLog(...args)),
|
|
66
|
-
trace: (...args) => !envs.isTest && logger.trace(serializeLog(...args)),
|
|
67
|
-
};
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { getStatusLevel, parseError, serializeHttp, serializeLog } from './serializers';
|
|
2
|
-
|
|
3
|
-
describe('logger - loglevel', () => {
|
|
4
|
-
test('Correctly gets http log level from the returning http status <300', () => {
|
|
5
|
-
expect(getStatusLevel(200)).toBe('info');
|
|
6
|
-
});
|
|
7
|
-
test('Correctly gets http log level from the returning http status >=400 && <500', () => {
|
|
8
|
-
expect(getStatusLevel(422)).toBe('warn');
|
|
9
|
-
});
|
|
10
|
-
test('Correctly gets http log level from the returning http status >=500', () => {
|
|
11
|
-
expect(getStatusLevel(500)).toBe('error');
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
const req = {
|
|
15
|
-
socket: { remoteAddress: '123.123.123.123' },
|
|
16
|
-
method: 'POST',
|
|
17
|
-
url: '/route',
|
|
18
|
-
httpVersionMajor: 1,
|
|
19
|
-
httpVersionMinor: 1,
|
|
20
|
-
headers: { 'request-header': 'JAS(D*8y2joidA&T12' },
|
|
21
|
-
httpVersion: '1.1',
|
|
22
|
-
};
|
|
23
|
-
const res = {
|
|
24
|
-
statusCode: 200,
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
describe('logger - http call serializer', () => {
|
|
28
|
-
test('Correctly serializes an req/res for an http log', () => {
|
|
29
|
-
expect(
|
|
30
|
-
serializeHttp(
|
|
31
|
-
{ 'my-header': 'header-value' },
|
|
32
|
-
{ toISOString: () => 'SOME_DATE' } as any,
|
|
33
|
-
'remote.client',
|
|
34
|
-
req as any,
|
|
35
|
-
res as any,
|
|
36
|
-
),
|
|
37
|
-
).toEqual({
|
|
38
|
-
level: 'info',
|
|
39
|
-
logObject: {
|
|
40
|
-
message: '123.123.123.123 remote.client SOME_DATE "POST /route HTTP/1.1" 200 -',
|
|
41
|
-
timestamp: expect.any(Number),
|
|
42
|
-
trace: undefined,
|
|
43
|
-
request: {
|
|
44
|
-
headers: { 'request-header': 'JAS(D*8y2joidA&T12' },
|
|
45
|
-
http_version: '1.1',
|
|
46
|
-
id: 'unknown',
|
|
47
|
-
method: 'POST',
|
|
48
|
-
url: '/route',
|
|
49
|
-
},
|
|
50
|
-
response: {
|
|
51
|
-
status_code: res.statusCode,
|
|
52
|
-
headers: { 'my-header': 'header-value' },
|
|
53
|
-
},
|
|
54
|
-
duration: 'unknown',
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
describe('logger - parse error with fields', () => {
|
|
61
|
-
test('Correctly parses an error with additional enumerable fields', () => {
|
|
62
|
-
const customError = new Error('custom error message') as any;
|
|
63
|
-
customError.additionalProp = 'value';
|
|
64
|
-
expect(parseError(customError, {})).toEqual({
|
|
65
|
-
error: {
|
|
66
|
-
additionalProp: 'value',
|
|
67
|
-
kind: 'Error',
|
|
68
|
-
stack: expect.any(String),
|
|
69
|
-
},
|
|
70
|
-
message: 'custom error message',
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
// common logger
|
|
76
|
-
describe('logger - common logger serializer', () => {
|
|
77
|
-
test('Correctly serializes log for only text', () => {
|
|
78
|
-
expect(serializeLog('just log message')).toEqual({
|
|
79
|
-
location: expect.any(String),
|
|
80
|
-
logger: {
|
|
81
|
-
method_name: 'asyncJestTest',
|
|
82
|
-
name: 'pino',
|
|
83
|
-
version: 'v1.0.0',
|
|
84
|
-
},
|
|
85
|
-
message: 'just log message',
|
|
86
|
-
timestamp: expect.any(Number),
|
|
87
|
-
trace: undefined,
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test('Correctly serializes log for text + object', () => {
|
|
92
|
-
expect(serializeLog('just log message', { obj: 'to_log' })).toEqual({
|
|
93
|
-
location: expect.any(String),
|
|
94
|
-
logger: {
|
|
95
|
-
method_name: 'asyncJestTest',
|
|
96
|
-
name: 'pino',
|
|
97
|
-
version: 'v1.0.0',
|
|
98
|
-
},
|
|
99
|
-
message: 'just log message',
|
|
100
|
-
timestamp: expect.any(Number),
|
|
101
|
-
trace: undefined,
|
|
102
|
-
args: [{ obj: 'to_log' }],
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
test('Correctly serializes log for object', () => {
|
|
107
|
-
expect(serializeLog({ obj: 'to_log', anotherKey: 9839485 })).toEqual({
|
|
108
|
-
location: expect.any(String),
|
|
109
|
-
logger: {
|
|
110
|
-
method_name: 'asyncJestTest',
|
|
111
|
-
name: 'pino',
|
|
112
|
-
version: 'v1.0.0',
|
|
113
|
-
},
|
|
114
|
-
message: 'EMPTY_MESSAGE',
|
|
115
|
-
timestamp: expect.any(Number),
|
|
116
|
-
trace: undefined,
|
|
117
|
-
args: { obj: 'to_log', anotherKey: 9839485 },
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
test('Correctly serializes log for multiple objects', () => {
|
|
122
|
-
expect(
|
|
123
|
-
serializeLog({ obj: 'to_log', anotherKey: 9839485 }, { additional: 'properties' }),
|
|
124
|
-
).toEqual({
|
|
125
|
-
location: expect.any(String),
|
|
126
|
-
logger: {
|
|
127
|
-
method_name: 'asyncJestTest',
|
|
128
|
-
name: 'pino',
|
|
129
|
-
version: 'v1.0.0',
|
|
130
|
-
},
|
|
131
|
-
message: 'EMPTY_MESSAGE',
|
|
132
|
-
timestamp: expect.any(Number),
|
|
133
|
-
trace: undefined,
|
|
134
|
-
args: [{ obj: 'to_log', anotherKey: 9839485 }, { additional: 'properties' }],
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
test('Correctly serializes log for error', () => {
|
|
139
|
-
const customError = new Error('custom error message') as any;
|
|
140
|
-
customError.additionalProp = 'value';
|
|
141
|
-
|
|
142
|
-
expect(serializeLog(customError)).toEqual({
|
|
143
|
-
location: expect.any(String),
|
|
144
|
-
logger: {
|
|
145
|
-
method_name: 'asyncJestTest',
|
|
146
|
-
name: 'pino',
|
|
147
|
-
version: 'v1.0.0',
|
|
148
|
-
},
|
|
149
|
-
message: 'custom error message',
|
|
150
|
-
timestamp: expect.any(Number),
|
|
151
|
-
trace: undefined,
|
|
152
|
-
error: {
|
|
153
|
-
additionalProp: 'value',
|
|
154
|
-
kind: 'Error',
|
|
155
|
-
stack: expect.any(String),
|
|
156
|
-
},
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
test('Correctly serializes log for error when error is not first argument', () => {
|
|
161
|
-
const customError = new Error('custom error message') as any;
|
|
162
|
-
customError.additionalProp = 'value';
|
|
163
|
-
|
|
164
|
-
expect(serializeLog('message for the log', customError)).toEqual({
|
|
165
|
-
location: expect.any(String),
|
|
166
|
-
logger: {
|
|
167
|
-
method_name: 'asyncJestTest',
|
|
168
|
-
name: 'pino',
|
|
169
|
-
version: 'v1.0.0',
|
|
170
|
-
},
|
|
171
|
-
message: 'message for the log',
|
|
172
|
-
timestamp: expect.any(Number),
|
|
173
|
-
trace: undefined,
|
|
174
|
-
args: [
|
|
175
|
-
{
|
|
176
|
-
error: {
|
|
177
|
-
additionalProp: 'value',
|
|
178
|
-
kind: 'Error',
|
|
179
|
-
stack: expect.any(String),
|
|
180
|
-
},
|
|
181
|
-
message: 'custom error message',
|
|
182
|
-
},
|
|
183
|
-
],
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
});
|