logixlysia 2.3.0 → 3.0.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/CHANGELOG.md +18 -0
- package/README.md +11 -4
- package/package.json +4 -2
- package/src/index.ts +3 -20
- package/src/logger.ts +56 -59
- package/src/types.ts +62 -0
- package/src/utils/colorMapping.ts +1 -1
- package/src/utils/path.ts +1 -1
- package/src/utils/start.ts +1 -1
- package/test/logixlysia.test.ts +99 -30
- package/test/types/ColorMap.test.ts +1 -1
- package/test/types/HttpError.test.ts +15 -0
- package/test/types/Logger.test.ts +1 -3
- package/test/types/RequestInfo.test.ts +1 -1
- package/test/types/Server.test.ts +1 -1
- package/test/types/StoreData.test.ts +1 -1
- package/test/utils/path.test.ts +1 -1
- package/test/utils/start.test.ts +1 -1
- package/.czrc +0 -3
- package/src/options.ts +0 -11
- package/src/types/ColorMap.ts +0 -12
- package/src/types/HttpError.ts +0 -11
- package/src/types/Logger.ts +0 -40
- package/src/types/RequestInfo.ts +0 -16
- package/src/types/Server.ts +0 -16
- package/src/types/StoreData.ts +0 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.0.0](https://github.com/PunGrumpy/logixlysia/compare/v2.3.1...v3.0.0) (2024-04-08)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### ⚠ BREAKING CHANGES
|
|
7
|
+
|
|
8
|
+
* **options:**
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* **options:** add support for custom log format ([acc9380](https://github.com/PunGrumpy/logixlysia/commit/acc9380ea25691e7d7fec175094cb6a9878b6c69))
|
|
13
|
+
|
|
14
|
+
## [2.3.1](https://github.com/PunGrumpy/logixlysia/compare/v2.3.0...v2.3.1) (2024-04-07)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* **index:** remove duplicate logging when options IP enabled ([2e99bd6](https://github.com/PunGrumpy/logixlysia/commit/2e99bd628b7160fb43161ca08e49f711b74e8666))
|
|
20
|
+
|
|
3
21
|
## [2.3.0](https://github.com/PunGrumpy/logixlysia/compare/v2.2.3...v2.3.0) (2024-04-06)
|
|
4
22
|
|
|
5
23
|
|
package/README.md
CHANGED
|
@@ -18,7 +18,13 @@ import { logger } from 'logixlysia'
|
|
|
18
18
|
|
|
19
19
|
const app = new Elysia({
|
|
20
20
|
name: 'Logixlysia Example'
|
|
21
|
-
}).use(
|
|
21
|
+
}).use(
|
|
22
|
+
logger({
|
|
23
|
+
ip: false,
|
|
24
|
+
customLogMessage:
|
|
25
|
+
'🦊 {now} {level} {duration} {method} {pathname} {status} {message} {ip}'
|
|
26
|
+
})
|
|
27
|
+
)
|
|
22
28
|
|
|
23
29
|
app.listen(3000)
|
|
24
30
|
```
|
|
@@ -27,9 +33,10 @@ app.listen(3000)
|
|
|
27
33
|
|
|
28
34
|
### Options
|
|
29
35
|
|
|
30
|
-
| Option
|
|
31
|
-
|
|
|
32
|
-
| `ip`
|
|
36
|
+
| Option | Type | Description | Default |
|
|
37
|
+
| ------------------ | --------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
38
|
+
| `ip` | `boolean` | Display the incoming IP address based on the `X-Forwarded-For` header | `false` |
|
|
39
|
+
| `customLogMessage` | `string` | Custom log message to display | `🦊 {now} {level} {duration} {method} {pathname} {status} {message} {ip}` |
|
|
33
40
|
|
|
34
41
|
## `📄` License
|
|
35
42
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "logixlysia",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "🦊 Logixlysia is a logger for Elysia",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "src/index.ts",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"test:ci": "bun test --timeout 5000 --coverage",
|
|
22
22
|
"publish": "npm publish",
|
|
23
23
|
"dev": "bun run --watch example/basic.ts",
|
|
24
|
-
"prepare": "husky
|
|
24
|
+
"prepare": "husky",
|
|
25
25
|
"lint:staged": "lint-staged",
|
|
26
26
|
"prettier": "prettier --write ."
|
|
27
27
|
},
|
|
@@ -77,6 +77,8 @@
|
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"@elysiajs/eden": "^1.0.4",
|
|
79
79
|
"bun-types": "^1.0.22",
|
|
80
|
+
"commitizen": "^4.3.0",
|
|
81
|
+
"cz-conventional-changelog": "^3.3.0",
|
|
80
82
|
"husky": "^9.0.7",
|
|
81
83
|
"lint-staged": "^15.2.0",
|
|
82
84
|
"prettier": "^3.1.1"
|
package/src/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import Elysia from 'elysia'
|
|
|
2
2
|
import { createLogger, handleHttpError } from './logger'
|
|
3
3
|
import startString from './utils/start'
|
|
4
4
|
import { Server } from 'bun'
|
|
5
|
-
import { Options } from './
|
|
5
|
+
import { Options } from './types'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Creates a logger.
|
|
@@ -20,7 +20,7 @@ import { Options } from './options'
|
|
|
20
20
|
* @returns {Elysia} The logger.
|
|
21
21
|
*/
|
|
22
22
|
export const logger = (options?: Options): Elysia => {
|
|
23
|
-
const log = createLogger()
|
|
23
|
+
const log = createLogger(options)
|
|
24
24
|
|
|
25
25
|
const elysia = new Elysia({
|
|
26
26
|
name: 'Logixlysia'
|
|
@@ -32,26 +32,9 @@ export const logger = (options?: Options): Elysia => {
|
|
|
32
32
|
ctx.store = { beforeTime: process.hrtime.bigint() }
|
|
33
33
|
})
|
|
34
34
|
.onAfterHandle({ as: 'global' }, ({ request, store }) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (options?.ip) {
|
|
38
|
-
const forwardedFor = request.headers.get('x-forwarded-for')
|
|
39
|
-
if (forwardedFor) {
|
|
40
|
-
logStr.push(`IP: ${forwardedFor}`)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
log.log(
|
|
45
|
-
'INFO',
|
|
46
|
-
request,
|
|
47
|
-
{
|
|
48
|
-
message: logStr.join(' ')
|
|
49
|
-
},
|
|
50
|
-
store as { beforeTime: bigint }
|
|
51
|
-
)
|
|
35
|
+
log.log('INFO', request, { status: 200 }, store as { beforeTime: bigint })
|
|
52
36
|
})
|
|
53
37
|
.onError({ as: 'global' }, ({ request, error, store }) => {
|
|
54
|
-
// log.log('ERROR', request, error, store as { beforeTime: bigint })
|
|
55
38
|
handleHttpError(request, error, store as { beforeTime: bigint })
|
|
56
39
|
})
|
|
57
40
|
|
package/src/logger.ts
CHANGED
|
@@ -4,51 +4,45 @@ import methodString from './utils/method'
|
|
|
4
4
|
import logString from './utils/log'
|
|
5
5
|
import pathString from './utils/path'
|
|
6
6
|
import statusString from './utils/status'
|
|
7
|
-
import { RequestInfo } from './types
|
|
8
|
-
import {
|
|
9
|
-
import { StoreData } from './types/StoreData'
|
|
10
|
-
import { HttpError } from './types/HttpError'
|
|
7
|
+
import { HttpError, RequestInfo } from './types'
|
|
8
|
+
import { LogLevel, LogData, Logger, StoreData, Options } from './types'
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
|
-
*
|
|
11
|
+
* Logs a message.
|
|
14
12
|
*
|
|
15
|
-
* @
|
|
16
|
-
* @param {
|
|
17
|
-
* @param {
|
|
18
|
-
* @param {
|
|
19
|
-
* @param {
|
|
20
|
-
*
|
|
21
|
-
* @returns {Promise<void>}
|
|
13
|
+
* @param {LogLevel} level The log level.
|
|
14
|
+
* @param {RequestInfo} request The request.
|
|
15
|
+
* @param {LogData} data The log data.
|
|
16
|
+
* @param {StoreData} store The store data.
|
|
17
|
+
* @param {Options} options The options.
|
|
22
18
|
*/
|
|
23
|
-
|
|
19
|
+
function log(
|
|
24
20
|
level: LogLevel,
|
|
25
21
|
request: RequestInfo,
|
|
26
22
|
data: LogData,
|
|
27
|
-
store: StoreData
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
} catch (error) {
|
|
33
|
-
console.error('Error logging message:', error)
|
|
34
|
-
}
|
|
23
|
+
store: StoreData,
|
|
24
|
+
options?: Options
|
|
25
|
+
): void {
|
|
26
|
+
const logMessage = buildLogMessage(level, request, data, store, options)
|
|
27
|
+
console.log(logMessage)
|
|
35
28
|
}
|
|
36
29
|
|
|
37
30
|
/**
|
|
38
|
-
* Builds
|
|
39
|
-
*
|
|
40
|
-
* @param {LogLevel} level - The log level.
|
|
41
|
-
* @param {RequestInfo} request - The request information.
|
|
42
|
-
* @param {LogData} data - The log data.
|
|
43
|
-
* @param {StoreData} store - The store data.
|
|
31
|
+
* Builds a log message.
|
|
44
32
|
*
|
|
45
|
-
* @
|
|
33
|
+
* @param {LogLevel} level The log level.
|
|
34
|
+
* @param {RequestInfo} request The request.
|
|
35
|
+
* @param {LogData} data The log data.
|
|
36
|
+
* @param {StoreData} store The store data.
|
|
37
|
+
* @param {Options} options The options.
|
|
38
|
+
* @returns {string} The log message.
|
|
46
39
|
*/
|
|
47
40
|
function buildLogMessage(
|
|
48
41
|
level: LogLevel,
|
|
49
42
|
request: RequestInfo,
|
|
50
43
|
data: LogData,
|
|
51
|
-
store: StoreData
|
|
44
|
+
store: StoreData,
|
|
45
|
+
options?: Options
|
|
52
46
|
): string {
|
|
53
47
|
const nowStr = chalk.bgYellow(chalk.black(new Date().toLocaleString()))
|
|
54
48
|
const levelStr = logString(level)
|
|
@@ -57,57 +51,60 @@ function buildLogMessage(
|
|
|
57
51
|
const pathnameStr = pathString(request)
|
|
58
52
|
const statusStr = statusString(data.status || 200)
|
|
59
53
|
const messageStr = data.message || ''
|
|
54
|
+
const ipStr =
|
|
55
|
+
options?.ip && request.headers.get('x-forwarded-for')
|
|
56
|
+
? `IP: ${request.headers.get('x-forwarded-for')}`
|
|
57
|
+
: ''
|
|
60
58
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
function writeToLogAsync(message: string): Promise<void> {
|
|
74
|
-
return new Promise((resolve, reject) => {
|
|
75
|
-
console.log(message)
|
|
76
|
-
resolve()
|
|
59
|
+
const logFormat =
|
|
60
|
+
options?.customLogFormat ||
|
|
61
|
+
'🦊 {now} {level} {duration} {method} {pathname} {status} {message} {ip}'
|
|
62
|
+
const logMessage = logFormat
|
|
63
|
+
.replace('{now}', nowStr)
|
|
64
|
+
.replace('{level}', levelStr)
|
|
65
|
+
.replace('{duration}', durationStr)
|
|
66
|
+
.replace('{method}', methodStr)
|
|
67
|
+
.replace('{pathname}', pathnameStr || '')
|
|
68
|
+
.replace('{status}', statusStr)
|
|
69
|
+
.replace('{message}', messageStr)
|
|
70
|
+
.replace('{ip}', ipStr || '')
|
|
77
71
|
|
|
78
|
-
|
|
79
|
-
reject(new Error('Timed out while writing to log.'))
|
|
80
|
-
})
|
|
81
|
-
})
|
|
72
|
+
return logMessage
|
|
82
73
|
}
|
|
83
74
|
|
|
84
75
|
/**
|
|
85
|
-
* Creates a logger
|
|
76
|
+
* Creates a logger.
|
|
86
77
|
*
|
|
87
|
-
* @
|
|
78
|
+
* @param {Options} options The options.
|
|
79
|
+
* @returns {Logger} The logger.
|
|
88
80
|
*/
|
|
89
|
-
export const createLogger = (): Logger => ({
|
|
90
|
-
log: (level, request, data, store) =>
|
|
81
|
+
export const createLogger = (options?: Options): Logger => ({
|
|
82
|
+
log: (level, request, data, store) =>
|
|
83
|
+
log(level, request, data, store, options),
|
|
84
|
+
customLogFormat: options?.customLogFormat
|
|
91
85
|
})
|
|
92
86
|
|
|
93
87
|
/**
|
|
94
|
-
*
|
|
88
|
+
* Handles an HTTP error.
|
|
95
89
|
*
|
|
96
|
-
* @param {RequestInfo} request
|
|
97
|
-
* @param {Error} error
|
|
98
|
-
* @param {StoreData} store
|
|
90
|
+
* @param {RequestInfo} request The request.
|
|
91
|
+
* @param {Error} error The error.
|
|
92
|
+
* @param {StoreData} store The store data.
|
|
93
|
+
* @param {Options} options The options.
|
|
99
94
|
*/
|
|
100
95
|
export const handleHttpError = (
|
|
101
96
|
request: RequestInfo,
|
|
102
97
|
error: Error,
|
|
103
|
-
store: StoreData
|
|
98
|
+
store: StoreData,
|
|
99
|
+
options?: Options
|
|
104
100
|
): void => {
|
|
105
101
|
const statusCode = error instanceof HttpError ? error.status : 500
|
|
106
102
|
const logMessage = buildLogMessage(
|
|
107
103
|
'ERROR',
|
|
108
104
|
request,
|
|
109
105
|
{ status: statusCode },
|
|
110
|
-
store
|
|
106
|
+
store,
|
|
107
|
+
options
|
|
111
108
|
)
|
|
112
109
|
console.error(logMessage)
|
|
113
110
|
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
interface RequestInfo {
|
|
2
|
+
headers: { get: (key: string) => any }
|
|
3
|
+
method: string
|
|
4
|
+
url: string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface Server {
|
|
8
|
+
hostname?: string
|
|
9
|
+
port?: number
|
|
10
|
+
protocol?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface ColorMap {
|
|
14
|
+
[key: string]: (str: string) => string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type LogLevel = 'INFO' | 'WARNING' | 'ERROR' | string
|
|
18
|
+
|
|
19
|
+
interface LogData {
|
|
20
|
+
status?: number
|
|
21
|
+
message?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface Logger {
|
|
25
|
+
log(
|
|
26
|
+
level: LogLevel,
|
|
27
|
+
request: RequestInfo,
|
|
28
|
+
data: LogData,
|
|
29
|
+
store: StoreData
|
|
30
|
+
): void
|
|
31
|
+
customLogFormat?: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface StoreData {
|
|
35
|
+
beforeTime: bigint
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
class HttpError extends Error {
|
|
39
|
+
status: number
|
|
40
|
+
|
|
41
|
+
constructor(status: number, message: string) {
|
|
42
|
+
super(message)
|
|
43
|
+
this.status = status
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface Options {
|
|
48
|
+
ip?: boolean
|
|
49
|
+
customLogFormat?: string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export {
|
|
53
|
+
RequestInfo,
|
|
54
|
+
Server,
|
|
55
|
+
ColorMap,
|
|
56
|
+
LogLevel,
|
|
57
|
+
LogData,
|
|
58
|
+
Logger,
|
|
59
|
+
StoreData,
|
|
60
|
+
HttpError,
|
|
61
|
+
Options
|
|
62
|
+
}
|
package/src/utils/path.ts
CHANGED
package/src/utils/start.ts
CHANGED
package/test/logixlysia.test.ts
CHANGED
|
@@ -3,51 +3,120 @@ import { edenTreaty } from '@elysiajs/eden'
|
|
|
3
3
|
import { describe, it, expect, beforeAll, beforeEach } from 'bun:test'
|
|
4
4
|
import { logger } from '../src'
|
|
5
5
|
|
|
6
|
-
describe('Logixlysia', () => {
|
|
6
|
+
describe('Logixlysia with IP logging enabled', () => {
|
|
7
7
|
let server: Elysia
|
|
8
8
|
let app: any
|
|
9
9
|
let logs: string[] = []
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
beforeAll(() => {
|
|
12
|
+
server = new Elysia()
|
|
13
|
+
.use(
|
|
14
|
+
logger({
|
|
15
|
+
ip: true,
|
|
16
|
+
customLogFormat:
|
|
17
|
+
'🦊 {now} {duration} {level} {method} {pathname} {status} {message} {ip}'
|
|
18
|
+
})
|
|
19
|
+
)
|
|
20
|
+
.get('/', ctx => {
|
|
21
|
+
const ipAddress = ctx.request.headers.get('x-forwarded-for') || 'null'
|
|
22
|
+
return '🦊 Logixlysia Getting'
|
|
23
|
+
})
|
|
24
|
+
.post('logixlysia', () => '🦊 Logixlysia Posting')
|
|
25
|
+
.listen(3000)
|
|
26
|
+
|
|
27
|
+
app = edenTreaty<typeof server>('http://127.0.0.1:3000')
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
logs = []
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it("Logs incoming IP address for GET '/' requests when X-Forwarded-For header is present", async () => {
|
|
35
|
+
const requestCount = 5
|
|
36
|
+
|
|
37
|
+
for (let i = 0; i < requestCount; i++) {
|
|
38
|
+
await app.get('/', {
|
|
39
|
+
headers: { 'X-Forwarded-For': '192.168.1.1' }
|
|
40
|
+
})
|
|
41
|
+
}
|
|
18
42
|
|
|
19
|
-
|
|
43
|
+
logs.forEach(log => {
|
|
44
|
+
expect(log).toMatch(
|
|
45
|
+
/^🦊 .+ INFO .+ .+ GET \/ .+ IP: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
|
|
46
|
+
)
|
|
20
47
|
})
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it("Logs 'null' for GET '/' requests when X-Forwarded-For header is not present", async () => {
|
|
51
|
+
const requestCount = 5
|
|
52
|
+
|
|
53
|
+
for (let i = 0; i < requestCount; i++) {
|
|
54
|
+
const response = await app.get('/')
|
|
55
|
+
}
|
|
21
56
|
|
|
22
|
-
|
|
23
|
-
|
|
57
|
+
logs.forEach(log => {
|
|
58
|
+
expect(log).toMatch(/^🦊 .+ INFO .+ .+ GET \/ .+ IP: null$/)
|
|
24
59
|
})
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
describe('Logixlysia with IP logging disabled', () => {
|
|
64
|
+
let server: Elysia
|
|
65
|
+
let app: any
|
|
66
|
+
let logs: string[] = []
|
|
25
67
|
|
|
26
|
-
|
|
27
|
-
|
|
68
|
+
beforeAll(() => {
|
|
69
|
+
server = new Elysia()
|
|
70
|
+
.use(
|
|
71
|
+
logger({
|
|
72
|
+
ip: false,
|
|
73
|
+
customLogFormat:
|
|
74
|
+
'🦊 {now} {duration} {level} {method} {pathname} {status} {message} {ip}'
|
|
75
|
+
})
|
|
76
|
+
)
|
|
77
|
+
.get('/', () => '🦊 Logixlysia Getting')
|
|
78
|
+
.post('logixlysia', () => '🦊 Logixlysia Posting')
|
|
79
|
+
.listen(3000)
|
|
28
80
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
81
|
+
app = edenTreaty<typeof server>('http://127.0.0.1:3000')
|
|
82
|
+
})
|
|
32
83
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
84
|
+
beforeEach(() => {
|
|
85
|
+
logs = []
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it("Responds correctly to GET '/' requests", async () => {
|
|
89
|
+
const requestCount = 5
|
|
90
|
+
|
|
91
|
+
for (let i = 0; i < requestCount; i++) {
|
|
92
|
+
logs.push((await app.get('/')).data)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
logs.forEach(log => {
|
|
96
|
+
expect(log).toBe('🦊 Logixlysia Getting')
|
|
36
97
|
})
|
|
98
|
+
})
|
|
37
99
|
|
|
38
|
-
|
|
39
|
-
|
|
100
|
+
it("Responds correctly to POST '/logixlysia' requests", async () => {
|
|
101
|
+
const requestCount = 5
|
|
40
102
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
103
|
+
for (let i = 0; i < requestCount; i++) {
|
|
104
|
+
const postResponse = await app.logixlysia.post({})
|
|
105
|
+
logs.push(
|
|
106
|
+
postResponse.status === 200 ? postResponse.data : postResponse.error
|
|
107
|
+
)
|
|
108
|
+
}
|
|
47
109
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
})
|
|
110
|
+
logs.forEach(log => {
|
|
111
|
+
expect(log).toBe('🦊 Logixlysia Posting')
|
|
51
112
|
})
|
|
52
113
|
})
|
|
114
|
+
|
|
115
|
+
it('Throws an error when attempting to post to an undefined route', async () => {
|
|
116
|
+
const response = await app.undefinedRoute.post({})
|
|
117
|
+
const error = response.error
|
|
118
|
+
|
|
119
|
+
expect(response.status).toBe(404)
|
|
120
|
+
expect(error).toBeInstanceOf(Error)
|
|
121
|
+
})
|
|
53
122
|
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test'
|
|
2
|
+
import { HttpError } from '~/types'
|
|
3
|
+
|
|
4
|
+
describe('HttpError', () => {
|
|
5
|
+
it('Should create an instance with correct status and message', () => {
|
|
6
|
+
const status = 404
|
|
7
|
+
const message = 'Not Found'
|
|
8
|
+
const error = new HttpError(status, message)
|
|
9
|
+
|
|
10
|
+
expect(error).toBeInstanceOf(Error)
|
|
11
|
+
expect(error).toBeInstanceOf(HttpError)
|
|
12
|
+
expect(error.status).toBe(status)
|
|
13
|
+
expect(error.message).toBe(message)
|
|
14
|
+
})
|
|
15
|
+
})
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it, jest } from 'bun:test'
|
|
2
|
-
import { LogData } from '~/types
|
|
3
|
-
import { RequestInfo } from '~/types/RequestInfo'
|
|
4
|
-
import { StoreData } from '~/types/StoreData'
|
|
2
|
+
import { RequestInfo, LogData, StoreData } from '~/types'
|
|
5
3
|
|
|
6
4
|
interface Logger {
|
|
7
5
|
info(request: RequestInfo, data: LogData, store: StoreData): void
|
package/test/utils/path.test.ts
CHANGED
package/test/utils/start.test.ts
CHANGED
package/.czrc
DELETED
package/src/options.ts
DELETED
package/src/types/ColorMap.ts
DELETED
package/src/types/HttpError.ts
DELETED
package/src/types/Logger.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { RequestInfo } from './RequestInfo'
|
|
2
|
-
import { StoreData } from './StoreData'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* The log level, including standard and custom levels.
|
|
6
|
-
*
|
|
7
|
-
* @type {string}
|
|
8
|
-
*/
|
|
9
|
-
type LogLevel = 'INFO' | 'WARNING' | 'ERROR' | string
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* The log data interface.
|
|
13
|
-
*
|
|
14
|
-
* @interface LogData
|
|
15
|
-
*
|
|
16
|
-
* @property {number} status - The status code.
|
|
17
|
-
* @property {string} message - The message.
|
|
18
|
-
*/
|
|
19
|
-
interface LogData {
|
|
20
|
-
status?: number
|
|
21
|
-
message?: string
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* The logger interface.
|
|
26
|
-
*
|
|
27
|
-
* @interface Logger
|
|
28
|
-
*
|
|
29
|
-
* @property {Function} log - Logs a message with a given log level.
|
|
30
|
-
*/
|
|
31
|
-
interface Logger {
|
|
32
|
-
log(
|
|
33
|
-
level: LogLevel,
|
|
34
|
-
request: RequestInfo,
|
|
35
|
-
data: LogData,
|
|
36
|
-
store: StoreData
|
|
37
|
-
): void
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export { LogLevel, LogData, Logger }
|
package/src/types/RequestInfo.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The request info.
|
|
3
|
-
*
|
|
4
|
-
* @interface RequestInfo
|
|
5
|
-
*
|
|
6
|
-
* @property {Object} headers The request headers.
|
|
7
|
-
* @property {string} method The request method.
|
|
8
|
-
* @property {string} url The request URL.
|
|
9
|
-
*/
|
|
10
|
-
interface RequestInfo {
|
|
11
|
-
headers: { get: (key: string) => any }
|
|
12
|
-
method: string
|
|
13
|
-
url: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export { RequestInfo }
|
package/src/types/Server.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The server information.
|
|
3
|
-
*
|
|
4
|
-
* @interface Server
|
|
5
|
-
*
|
|
6
|
-
* @property {string} hostname The server hostname.
|
|
7
|
-
* @property {number} port The server port.
|
|
8
|
-
* @property {string} protocol The server protocol.
|
|
9
|
-
*/
|
|
10
|
-
interface Server {
|
|
11
|
-
hostname?: string
|
|
12
|
-
port?: number
|
|
13
|
-
protocol?: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export { Server }
|