logixlysia 3.3.0 → 3.3.1
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/.gitmodules +3 -0
- package/.trunk/trunk.yaml +26 -0
- package/CHANGELOG.md +7 -0
- package/package.json +13 -10
- package/src/index.ts +6 -4
- package/src/logger/{index.ts → buildLogMessage.ts} +5 -54
- package/src/logger/createLogger.ts +49 -0
- package/src/logger/{handle.ts → handleHttpError.ts} +6 -8
- package/src/utils/duration.ts +7 -6
- package/src/utils/path.ts +1 -1
- package/src/utils/start.ts +3 -4
- package/.gitguardian.yml +0 -16
- package/.prettierignore +0 -2
- package/.prettierrc +0 -9
- package/eslint.config.js +0 -25
- package/test/logger/filter.test.ts +0 -62
- package/test/logixlysia.test.ts +0 -223
- package/test/types/ColorMap.test.ts +0 -25
- package/test/types/HttpError.test.ts +0 -16
- package/test/types/Logger.test.ts +0 -91
- package/test/types/RequestInfo.test.ts +0 -23
- package/test/types/Server.test.ts +0 -27
- package/test/types/StoreData.test.ts +0 -17
- package/test/utils/duration.test.ts +0 -37
- package/test/utils/log.test.ts +0 -26
- package/test/utils/method.test.ts +0 -21
- package/test/utils/path.test.ts +0 -36
- package/test/utils/start.test.ts +0 -38
- package/test/utils/status.test.ts +0 -31
- package/tsconfig.json +0 -28
package/.gitmodules
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 0.1
|
|
3
|
+
cli:
|
|
4
|
+
version: 1.22.1
|
|
5
|
+
plugins:
|
|
6
|
+
sources:
|
|
7
|
+
- id: trunk
|
|
8
|
+
ref: v1.5.0
|
|
9
|
+
uri: https://github.com/trunk-io/plugins
|
|
10
|
+
runtimes:
|
|
11
|
+
enabled:
|
|
12
|
+
- node@22.2.0
|
|
13
|
+
lint:
|
|
14
|
+
enabled:
|
|
15
|
+
- oxipng@9.1.1
|
|
16
|
+
- shfmt@3.6.0
|
|
17
|
+
- eslint@9.3.0
|
|
18
|
+
- actionlint@1.7.0
|
|
19
|
+
- git-diff-check
|
|
20
|
+
- markdownlint@0.40.0
|
|
21
|
+
- prettier@3.2.5
|
|
22
|
+
- trufflehog@3.76.3
|
|
23
|
+
- yamllint@1.35.1
|
|
24
|
+
actions:
|
|
25
|
+
enabled:
|
|
26
|
+
- npm-check
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.3.1](https://github.com/PunGrumpy/logixlysia/compare/v3.3.0...v3.3.1) (2024-06-01)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **deps:** move `ESLint` and related packages to dev dependencies ([98de50c](https://github.com/PunGrumpy/logixlysia/commit/98de50c6c3bffc5939963ebd04563204c7c70793)), closes [#46](https://github.com/PunGrumpy/logixlysia/issues/46)
|
|
9
|
+
|
|
3
10
|
## [3.3.0](https://github.com/PunGrumpy/logixlysia/compare/v3.2.0...v3.3.0) (2024-05-22)
|
|
4
11
|
|
|
5
12
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "logixlysia",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"description": "🦊 Logixlysia is a logger for Elysia",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "src/index.ts",
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"dev": "bun run --watch example/basic.ts",
|
|
24
24
|
"prepare": "husky",
|
|
25
25
|
"lint:staged": "lint-staged",
|
|
26
|
-
"prettier": "prettier --write ."
|
|
26
|
+
"prettier": "prettier --write --config .trunk/configs/.prettierrc.yaml .",
|
|
27
|
+
"trunk:check": "trunk check",
|
|
28
|
+
"trunk:fmt": "trunk fmt"
|
|
27
29
|
},
|
|
28
30
|
"os": [
|
|
29
31
|
"darwin",
|
|
@@ -68,23 +70,24 @@
|
|
|
68
70
|
"middleware"
|
|
69
71
|
],
|
|
70
72
|
"dependencies": {
|
|
71
|
-
"@eslint/js": "^9.3.0",
|
|
72
|
-
"@typescript-eslint/eslint-plugin": "^7.10.0",
|
|
73
|
-
"@typescript-eslint/parser": "^7.10.0",
|
|
74
73
|
"chalk": "^5.3.0",
|
|
75
|
-
"elysia": "^1.0.21"
|
|
76
|
-
"eslint": "9.x",
|
|
77
|
-
"eslint-plugin-simple-import-sort": "^12.1.0",
|
|
78
|
-
"typescript-eslint": "^7.10.0"
|
|
74
|
+
"elysia": "^1.0.21"
|
|
79
75
|
},
|
|
80
76
|
"devDependencies": {
|
|
81
77
|
"@elysiajs/eden": "^1.0.13",
|
|
78
|
+
"@eslint/js": "^9.3.0",
|
|
79
|
+
"@trunkio/launcher": "^1.3.1",
|
|
80
|
+
"@typescript-eslint/eslint-plugin": "^7.10.0",
|
|
81
|
+
"@typescript-eslint/parser": "^7.10.0",
|
|
82
82
|
"bun-types": "^1.1.9",
|
|
83
83
|
"commitizen": "^4.3.0",
|
|
84
84
|
"cz-conventional-changelog": "^3.3.0",
|
|
85
|
+
"eslint": "9.x",
|
|
86
|
+
"eslint-plugin-simple-import-sort": "^12.1.0",
|
|
85
87
|
"husky": "^9.0.11",
|
|
86
88
|
"lint-staged": "^15.2.4",
|
|
87
|
-
"prettier": "^3.2.5"
|
|
89
|
+
"prettier": "^3.2.5",
|
|
90
|
+
"typescript-eslint": "^7.10.0"
|
|
88
91
|
},
|
|
89
92
|
"peerDependencies": {
|
|
90
93
|
"typescript": "^5.0.0"
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Server } from 'bun'
|
|
2
2
|
import Elysia from 'elysia'
|
|
3
3
|
|
|
4
|
-
import { createLogger } from './logger'
|
|
5
|
-
import { handleHttpError } from './logger/
|
|
4
|
+
import { createLogger } from './logger/createLogger'
|
|
5
|
+
import { handleHttpError } from './logger/handleHttpError'
|
|
6
6
|
import { HttpError, Options } from './types'
|
|
7
7
|
import startServer from './utils/start'
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Creates a logger.
|
|
10
|
+
* Creates a logger plugin for ElysiaJS.
|
|
11
11
|
*
|
|
12
12
|
* @export
|
|
13
13
|
* @module logger
|
|
@@ -19,7 +19,9 @@ import startServer from './utils/start'
|
|
|
19
19
|
* @author PunGrumpy
|
|
20
20
|
* @license MIT
|
|
21
21
|
*
|
|
22
|
-
* @
|
|
22
|
+
* @param {Options} [options] Configuration options for the logger.
|
|
23
|
+
*
|
|
24
|
+
* @returns {Elysia} The logger plugin for ElysiaJS.
|
|
23
25
|
*/
|
|
24
26
|
export default function logixlysia(options?: Options): Elysia {
|
|
25
27
|
const log = createLogger(options)
|
|
@@ -1,56 +1,23 @@
|
|
|
1
1
|
import chalk from 'chalk'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
LogData,
|
|
5
|
-
Logger,
|
|
6
|
-
LogLevel,
|
|
7
|
-
Options,
|
|
8
|
-
RequestInfo,
|
|
9
|
-
StoreData
|
|
10
|
-
} from '~/types'
|
|
3
|
+
import { LogData, LogLevel, Options, RequestInfo, StoreData } from '~/types'
|
|
11
4
|
import durationString from '~/utils/duration'
|
|
12
5
|
import logString from '~/utils/log'
|
|
13
6
|
import methodString from '~/utils/method'
|
|
14
7
|
import pathString from '~/utils/path'
|
|
15
8
|
import statusString from '~/utils/status'
|
|
16
9
|
|
|
17
|
-
import { filterLog } from './filter'
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Logs a message.
|
|
21
|
-
*
|
|
22
|
-
* @param {LogLevel} level The log level.
|
|
23
|
-
* @param {RequestInfo} request The request.
|
|
24
|
-
* @param {LogData} data The log data.
|
|
25
|
-
* @param {StoreData} store The store data.
|
|
26
|
-
* @param {Options} options The options.
|
|
27
|
-
*/
|
|
28
|
-
function log(
|
|
29
|
-
level: LogLevel,
|
|
30
|
-
request: RequestInfo,
|
|
31
|
-
data: LogData,
|
|
32
|
-
store: StoreData,
|
|
33
|
-
options?: Options
|
|
34
|
-
): void {
|
|
35
|
-
if (!filterLog(level, data.status || 200, request.method, options)) {
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const logMessage = buildLogMessage(level, request, data, store, options)
|
|
40
|
-
console.log(logMessage)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
10
|
/**
|
|
44
11
|
* Builds a log message.
|
|
45
12
|
*
|
|
46
13
|
* @param {LogLevel} level The log level.
|
|
47
|
-
* @param {RequestInfo} request The request.
|
|
14
|
+
* @param {RequestInfo} request The request information.
|
|
48
15
|
* @param {LogData} data The log data.
|
|
49
16
|
* @param {StoreData} store The store data.
|
|
50
|
-
* @param {Options} options The options.
|
|
51
|
-
* @returns {string} The log message.
|
|
17
|
+
* @param {Options} options The logger options.
|
|
18
|
+
* @returns {string} The formatted log message.
|
|
52
19
|
*/
|
|
53
|
-
function buildLogMessage(
|
|
20
|
+
export function buildLogMessage(
|
|
54
21
|
level: LogLevel,
|
|
55
22
|
request: RequestInfo,
|
|
56
23
|
data: LogData,
|
|
@@ -84,19 +51,3 @@ function buildLogMessage(
|
|
|
84
51
|
|
|
85
52
|
return logMessage
|
|
86
53
|
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Creates a logger.
|
|
90
|
-
*
|
|
91
|
-
* @param {Options} options The options.
|
|
92
|
-
* @returns {Logger} The logger.
|
|
93
|
-
*/
|
|
94
|
-
function createLogger(options?: Options): Logger {
|
|
95
|
-
return {
|
|
96
|
-
log: (level, request, data, store) =>
|
|
97
|
-
log(level, request, data, store, options),
|
|
98
|
-
customLogFormat: options?.config?.customLogFormat
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export { buildLogMessage, createLogger, log }
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LogData,
|
|
3
|
+
Logger,
|
|
4
|
+
LogLevel,
|
|
5
|
+
Options,
|
|
6
|
+
RequestInfo,
|
|
7
|
+
StoreData
|
|
8
|
+
} from '~/types'
|
|
9
|
+
|
|
10
|
+
import { buildLogMessage } from './buildLogMessage'
|
|
11
|
+
import { filterLog } from './filter'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Logs a message to the console.
|
|
15
|
+
*
|
|
16
|
+
* @param {LogLevel} level The log level.
|
|
17
|
+
* @param {RequestInfo} request The request information.
|
|
18
|
+
* @param {LogData} data The log data.
|
|
19
|
+
* @param {StoreData} store The store data.
|
|
20
|
+
* @param {Options} options The logger options.
|
|
21
|
+
*/
|
|
22
|
+
async function log(
|
|
23
|
+
level: LogLevel,
|
|
24
|
+
request: RequestInfo,
|
|
25
|
+
data: LogData,
|
|
26
|
+
store: StoreData,
|
|
27
|
+
options?: Options
|
|
28
|
+
): Promise<void> {
|
|
29
|
+
if (!filterLog(level, data.status || 200, request.method, options)) {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const logMessage = buildLogMessage(level, request, data, store, options)
|
|
34
|
+
console.log(logMessage)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Creates a logger instance.
|
|
39
|
+
*
|
|
40
|
+
* @param {Options} options The logger options.
|
|
41
|
+
* @returns {Logger} The logger instance.
|
|
42
|
+
*/
|
|
43
|
+
export function createLogger(options?: Options): Logger {
|
|
44
|
+
return {
|
|
45
|
+
log: async (level, request, data, store) =>
|
|
46
|
+
log(level, request, data, store, options),
|
|
47
|
+
customLogFormat: options?.config?.customLogFormat
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { HttpError, Options, RequestInfo, StoreData } from '~/types'
|
|
2
2
|
|
|
3
|
-
import { buildLogMessage } from '
|
|
3
|
+
import { buildLogMessage } from './buildLogMessage'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Handles an HTTP error.
|
|
6
|
+
* Handles an HTTP error and logs it.
|
|
7
7
|
*
|
|
8
|
-
* @param {RequestInfo} request The request.
|
|
8
|
+
* @param {RequestInfo} request The request information.
|
|
9
9
|
* @param {HttpError} error The HTTP error.
|
|
10
10
|
* @param {StoreData} store The store data.
|
|
11
|
-
* @param {Options} options The options.
|
|
11
|
+
* @param {Options} options The logger options.
|
|
12
12
|
*/
|
|
13
|
-
function handleHttpError(
|
|
13
|
+
export async function handleHttpError(
|
|
14
14
|
request: RequestInfo,
|
|
15
15
|
error: HttpError,
|
|
16
16
|
store: StoreData,
|
|
17
17
|
options?: Options
|
|
18
|
-
): void {
|
|
18
|
+
): Promise<void> {
|
|
19
19
|
const statusCode = error.status || 500
|
|
20
20
|
const logMessage = buildLogMessage(
|
|
21
21
|
'ERROR',
|
|
@@ -26,5 +26,3 @@ function handleHttpError(
|
|
|
26
26
|
)
|
|
27
27
|
console.error(logMessage)
|
|
28
28
|
}
|
|
29
|
-
|
|
30
|
-
export { handleHttpError }
|
package/src/utils/duration.ts
CHANGED
|
@@ -9,17 +9,18 @@ import chalk from 'chalk'
|
|
|
9
9
|
* @returns {string} A formatted duration string including the time unit.
|
|
10
10
|
*/
|
|
11
11
|
function durationString(beforeTime: bigint): string {
|
|
12
|
-
const
|
|
12
|
+
const currentTime = process.hrtime.bigint()
|
|
13
|
+
const nanoseconds = Number(currentTime - beforeTime)
|
|
13
14
|
|
|
14
15
|
const timeUnits = [
|
|
15
|
-
{ unit: 's', threshold: 1e9 },
|
|
16
|
-
{ unit: 'ms', threshold: 1e6 },
|
|
17
|
-
{ unit: 'µs', threshold: 1e3 }
|
|
16
|
+
{ unit: 's', threshold: 1e9, decimalPlaces: 2 },
|
|
17
|
+
{ unit: 'ms', threshold: 1e6, decimalPlaces: 0 },
|
|
18
|
+
{ unit: 'µs', threshold: 1e3, decimalPlaces: 0 }
|
|
18
19
|
]
|
|
19
20
|
|
|
20
|
-
for (const { unit, threshold } of timeUnits) {
|
|
21
|
+
for (const { unit, threshold, decimalPlaces } of timeUnits) {
|
|
21
22
|
if (nanoseconds >= threshold) {
|
|
22
|
-
const value = (nanoseconds / threshold).toFixed(
|
|
23
|
+
const value = (nanoseconds / threshold).toFixed(decimalPlaces)
|
|
23
24
|
return formatTime(value, unit)
|
|
24
25
|
}
|
|
25
26
|
}
|
package/src/utils/path.ts
CHANGED
package/src/utils/start.ts
CHANGED
|
@@ -9,9 +9,9 @@ import { Server } from '~/types'
|
|
|
9
9
|
* @returns {string} The box text.
|
|
10
10
|
*/
|
|
11
11
|
function createBoxText(text: string, width: number): string {
|
|
12
|
-
const paddingLength = Math.max(0, (width - text.length
|
|
12
|
+
const paddingLength = Math.max(0, (width - text.length) / 2)
|
|
13
13
|
const padding = ' '.repeat(paddingLength)
|
|
14
|
-
return `${padding}${text}${padding}`.
|
|
14
|
+
return `${padding}${text}${padding}`.padEnd(width)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -26,8 +26,7 @@ function startServer(config: Server): void {
|
|
|
26
26
|
const ELYSIA_VERSION = import.meta.require('elysia/package.json').version
|
|
27
27
|
const title = `Elysia v${ELYSIA_VERSION}`
|
|
28
28
|
const message = `🦊 Elysia is running at ${protocol}://${hostname}:${port}`
|
|
29
|
-
const
|
|
30
|
-
const boxWidth = Math.max(title.length, messageWidth) + 4
|
|
29
|
+
const boxWidth = Math.max(title.length, message.length) + 4
|
|
31
30
|
const border = '─'.repeat(boxWidth)
|
|
32
31
|
|
|
33
32
|
console.log(`
|
package/.gitguardian.yml
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# Required, otherwise ggshield considers the file to use the deprecated v1 format
|
|
2
|
-
version: 2
|
|
3
|
-
|
|
4
|
-
# Set to true if the desired exit code for the CLI is always 0, otherwise the
|
|
5
|
-
# exit code will be 1 if incidents are found.
|
|
6
|
-
exit-zero: false
|
|
7
|
-
|
|
8
|
-
verbose: false
|
|
9
|
-
|
|
10
|
-
instance: https://dashboard.gitguardian.com
|
|
11
|
-
|
|
12
|
-
# Maximum commits to scan in a hook.
|
|
13
|
-
max-commits-for-hook: 50
|
|
14
|
-
|
|
15
|
-
# Accept self-signed certificates for the API.
|
|
16
|
-
allow-self-signed: false
|
package/.prettierignore
DELETED
package/.prettierrc
DELETED
package/eslint.config.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import pluginJs from '@eslint/js'
|
|
2
|
-
import eslintPlugin from '@typescript-eslint/eslint-plugin'
|
|
3
|
-
import eslintPluginSimpleImportSort from 'eslint-plugin-simple-import-sort'
|
|
4
|
-
import globals from 'globals'
|
|
5
|
-
import tseslint from 'typescript-eslint'
|
|
6
|
-
|
|
7
|
-
export default [
|
|
8
|
-
pluginJs.configs.recommended,
|
|
9
|
-
...tseslint.configs.recommended,
|
|
10
|
-
{
|
|
11
|
-
languageOptions: {
|
|
12
|
-
globals: globals.browser
|
|
13
|
-
},
|
|
14
|
-
plugins: {
|
|
15
|
-
'@typescript-eslint': eslintPlugin,
|
|
16
|
-
'simple-import-sort': eslintPluginSimpleImportSort
|
|
17
|
-
},
|
|
18
|
-
rules: {
|
|
19
|
-
'no-undef': 'off',
|
|
20
|
-
'@typescript-eslint/no-explicit-any': 'off',
|
|
21
|
-
'simple-import-sort/imports': 'error',
|
|
22
|
-
'simple-import-sort/exports': 'error'
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
]
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { filterLog } from '~/logger/filter'
|
|
4
|
-
import { LogLevel, Options } from '~/types'
|
|
5
|
-
|
|
6
|
-
describe('filterLog', () => {
|
|
7
|
-
const logLevel: LogLevel = 'info'
|
|
8
|
-
const status = 200
|
|
9
|
-
const method = 'GET'
|
|
10
|
-
|
|
11
|
-
it('should return true if no filter is provided', () => {
|
|
12
|
-
expect(filterLog(logLevel, status, method)).toBe(true)
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
it('should filter by log level (single value)', () => {
|
|
16
|
-
const options: Options = { config: { logFilter: { level: 'error' } } }
|
|
17
|
-
expect(filterLog(logLevel, status, method, options)).toBe(false)
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('should filter by log level (array)', () => {
|
|
21
|
-
const options: Options = {
|
|
22
|
-
config: { logFilter: { level: ['error', 'info'] } }
|
|
23
|
-
}
|
|
24
|
-
expect(filterLog(logLevel, status, method, options)).toBe(true)
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('should filter by status (single value)', () => {
|
|
28
|
-
const options: Options = { config: { logFilter: { status: 404 } } }
|
|
29
|
-
expect(filterLog(logLevel, status, method, options)).toBe(false)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('should filter by status (array)', () => {
|
|
33
|
-
const options: Options = { config: { logFilter: { status: [200, 404] } } }
|
|
34
|
-
expect(filterLog(logLevel, status, method, options)).toBe(true)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it('should filter by method (single value)', () => {
|
|
38
|
-
const options: Options = { config: { logFilter: { method: 'POST' } } }
|
|
39
|
-
expect(filterLog(logLevel, status, method, options)).toBe(false)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('should filter by method (array)', () => {
|
|
43
|
-
const options: Options = {
|
|
44
|
-
config: { logFilter: { method: ['GET', 'POST'] } }
|
|
45
|
-
}
|
|
46
|
-
expect(filterLog(logLevel, status, method, options)).toBe(true)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('should return false if any filter condition is not met', () => {
|
|
50
|
-
const options: Options = {
|
|
51
|
-
config: { logFilter: { level: 'info', status: 404, method: 'POST' } }
|
|
52
|
-
}
|
|
53
|
-
expect(filterLog(logLevel, status, method, options)).toBe(false)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('should return true if all filter conditions are met', () => {
|
|
57
|
-
const options: Options = {
|
|
58
|
-
config: { logFilter: { level: 'info', status: 200, method: 'GET' } }
|
|
59
|
-
}
|
|
60
|
-
expect(filterLog(logLevel, status, method, options)).toBe(true)
|
|
61
|
-
})
|
|
62
|
-
})
|
package/test/logixlysia.test.ts
DELETED
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
import { edenTreaty } from '@elysiajs/eden'
|
|
2
|
-
import { beforeAll, beforeEach, describe, expect, it } from 'bun:test'
|
|
3
|
-
import { Elysia } from 'elysia'
|
|
4
|
-
|
|
5
|
-
import logixlysia from '../src'
|
|
6
|
-
|
|
7
|
-
describe('Logixlysia with IP logging enabled', () => {
|
|
8
|
-
let server: Elysia
|
|
9
|
-
let app: ReturnType<typeof edenTreaty> | any
|
|
10
|
-
let logs: string[] = []
|
|
11
|
-
|
|
12
|
-
beforeAll(() => {
|
|
13
|
-
server = new Elysia()
|
|
14
|
-
.use(
|
|
15
|
-
logixlysia({
|
|
16
|
-
config: {
|
|
17
|
-
ip: true,
|
|
18
|
-
customLogFormat:
|
|
19
|
-
'🦊 {now} {duration} {level} {method} {pathname} {status} {message} {ip}'
|
|
20
|
-
}
|
|
21
|
-
})
|
|
22
|
-
)
|
|
23
|
-
.get('/', () => {
|
|
24
|
-
return '🦊 Logixlysia Getting'
|
|
25
|
-
})
|
|
26
|
-
.post('logixlysia', () => '🦊 Logixlysia Posting')
|
|
27
|
-
.listen(3000)
|
|
28
|
-
|
|
29
|
-
app = edenTreaty<typeof server>('http://127.0.0.1:3000')
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
beforeEach(() => {
|
|
33
|
-
logs = []
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
it("Logs incoming IP address for GET '/' requests when X-Forwarded-For header is present", async () => {
|
|
37
|
-
const requestCount = 5
|
|
38
|
-
|
|
39
|
-
for (let i = 0; i < requestCount; i++) {
|
|
40
|
-
await app.get('/', {
|
|
41
|
-
headers: { 'X-Forwarded-For': '192.168.1.1' }
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
logs.forEach(log => {
|
|
46
|
-
expect(log).toMatch(
|
|
47
|
-
/^🦊 .+ INFO .+ .+ GET \/ .+ IP: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
|
|
48
|
-
)
|
|
49
|
-
})
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it("Logs 'null' for GET '/' requests when X-Forwarded-For header is not present", async () => {
|
|
53
|
-
logs.forEach(log => {
|
|
54
|
-
expect(log).toMatch(/^🦊 .+ INFO .+ .+ GET \/ .+ IP: null$/)
|
|
55
|
-
})
|
|
56
|
-
})
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
describe('Logixlysia with IP logging disabled', () => {
|
|
60
|
-
let server: Elysia
|
|
61
|
-
let app: ReturnType<typeof edenTreaty> | any
|
|
62
|
-
let logs: string[] = []
|
|
63
|
-
|
|
64
|
-
beforeAll(() => {
|
|
65
|
-
server = new Elysia()
|
|
66
|
-
.use(
|
|
67
|
-
logixlysia({
|
|
68
|
-
config: {
|
|
69
|
-
ip: false,
|
|
70
|
-
customLogFormat:
|
|
71
|
-
'🦊 {now} {duration} {level} {method} {pathname} {status} {message} {ip}'
|
|
72
|
-
}
|
|
73
|
-
})
|
|
74
|
-
)
|
|
75
|
-
.get('/', () => '🦊 Logixlysia Getting')
|
|
76
|
-
.post('logixlysia', () => '🦊 Logixlysia Posting')
|
|
77
|
-
.listen(3000)
|
|
78
|
-
|
|
79
|
-
app = edenTreaty<typeof server>('http://127.0.0.1:3000')
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
beforeEach(() => {
|
|
83
|
-
logs = []
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
it("Responds correctly to GET '/' requests", async () => {
|
|
87
|
-
const requestCount = 5
|
|
88
|
-
|
|
89
|
-
for (let i = 0; i < requestCount; i++) {
|
|
90
|
-
logs.push((await app.get('/')).data)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
logs.forEach(log => {
|
|
94
|
-
expect(log).toBe('🦊 Logixlysia Getting')
|
|
95
|
-
})
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
it("Responds correctly to POST '/logixlysia' requests", async () => {
|
|
99
|
-
const requestCount = 5
|
|
100
|
-
|
|
101
|
-
for (let i = 0; i < requestCount; i++) {
|
|
102
|
-
const postResponse = await app.logixlysia.post({})
|
|
103
|
-
logs.push(
|
|
104
|
-
postResponse.status === 200 ? postResponse.data : postResponse.error
|
|
105
|
-
)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
logs.forEach(log => {
|
|
109
|
-
expect(log).toBe('🦊 Logixlysia Posting')
|
|
110
|
-
})
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it('Throws an error when attempting to post to an undefined route', async () => {
|
|
114
|
-
const response = await app.undefinedRoute.post({})
|
|
115
|
-
const error = response.error
|
|
116
|
-
|
|
117
|
-
expect(response.status).toBe(404)
|
|
118
|
-
expect(error).toBeInstanceOf(Error)
|
|
119
|
-
})
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
describe('Logixlysia with log filtering enabled', () => {
|
|
123
|
-
let server: Elysia
|
|
124
|
-
let app: ReturnType<typeof edenTreaty> | any
|
|
125
|
-
let logs: string[] = []
|
|
126
|
-
|
|
127
|
-
beforeAll(() => {
|
|
128
|
-
server = new Elysia()
|
|
129
|
-
.use(
|
|
130
|
-
logixlysia({
|
|
131
|
-
config: {
|
|
132
|
-
logFilter: {
|
|
133
|
-
level: 'INFO',
|
|
134
|
-
status: [200, 404],
|
|
135
|
-
method: 'GET'
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
})
|
|
139
|
-
)
|
|
140
|
-
.get('/', () => '🦊 Logixlysia Getting')
|
|
141
|
-
.post('logixlysia', () => '🦊 Logixlysia Posting')
|
|
142
|
-
.listen(3000)
|
|
143
|
-
|
|
144
|
-
app = edenTreaty<typeof server>('http://127.0.0.1:3000')
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
beforeEach(() => {
|
|
148
|
-
logs = []
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
it("Logs 'GET' requests with status 200 or 404 when log filtering criteria are met", async () => {
|
|
152
|
-
const requestCount = 5
|
|
153
|
-
|
|
154
|
-
for (let i = 0; i < requestCount; i++) {
|
|
155
|
-
logs.push((await app.get('/')).data)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
expect(logs.length).toBe(requestCount)
|
|
159
|
-
logs.forEach(log => {
|
|
160
|
-
expect(log).toMatch('🦊 Logixlysia Getting')
|
|
161
|
-
})
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
it("Doesn't log 'POST' requests when log filtering criteria are not met", async () => {
|
|
165
|
-
const requestCount = 5
|
|
166
|
-
|
|
167
|
-
for (let i = 0; i < requestCount; i++) {
|
|
168
|
-
await app.post('/logixlysia', {})
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
expect(logs.length).toBe(0)
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
const otherMethods = ['PUT', 'DELETE', 'PATCH', 'HEAD'] // OPTIONS is failed (IDK why)
|
|
175
|
-
otherMethods.forEach(async method => {
|
|
176
|
-
it(`Logs '${method}' requests with status 200 or 404 when log filtering criteria are met`, async () => {
|
|
177
|
-
const requestCount = 5
|
|
178
|
-
|
|
179
|
-
for (let i = 0; i < requestCount; i++) {
|
|
180
|
-
logs.push((await app[method.toLowerCase()]('/')).data)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
expect(logs.length).toBe(requestCount)
|
|
184
|
-
})
|
|
185
|
-
})
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
describe('Logixlysia with log filtering disabled', () => {
|
|
189
|
-
let server: Elysia
|
|
190
|
-
let app: ReturnType<typeof edenTreaty> | any
|
|
191
|
-
let logs: string[] = []
|
|
192
|
-
|
|
193
|
-
beforeAll(() => {
|
|
194
|
-
server = new Elysia()
|
|
195
|
-
.use(
|
|
196
|
-
logixlysia({
|
|
197
|
-
config: {
|
|
198
|
-
logFilter: null
|
|
199
|
-
}
|
|
200
|
-
})
|
|
201
|
-
)
|
|
202
|
-
.get('/', () => '🦊 Logixlysia Getting')
|
|
203
|
-
.post('logixlysia', () => '🦊 Logixlysia Posting')
|
|
204
|
-
.listen(3000)
|
|
205
|
-
|
|
206
|
-
app = edenTreaty<typeof server>('http://127.0.0.1:3000')
|
|
207
|
-
})
|
|
208
|
-
|
|
209
|
-
beforeEach(() => {
|
|
210
|
-
logs = []
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
it('Logs all requests when log filtering is disabled', async () => {
|
|
214
|
-
const requestCount = 5
|
|
215
|
-
|
|
216
|
-
for (let i = 0; i < requestCount; i++) {
|
|
217
|
-
logs.push((await app.get('/')).data)
|
|
218
|
-
logs.push((await app.post('/logixlysia', {})).data)
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
expect(logs.length).toBe(requestCount * 2)
|
|
222
|
-
})
|
|
223
|
-
})
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { ColorMap } from '~/types'
|
|
4
|
-
|
|
5
|
-
describe('Color Mapping Interface', () => {
|
|
6
|
-
it('Defines an object with string keys mapping to functions', () => {
|
|
7
|
-
const colorMap: ColorMap = {
|
|
8
|
-
red: (str: string) => `Red: ${str}`,
|
|
9
|
-
green: (str: string) => `Green: ${str}`,
|
|
10
|
-
blue: (str: string) => `Blue: ${str}`
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
expect(colorMap).toEqual(
|
|
14
|
-
expect.objectContaining({
|
|
15
|
-
red: expect.any(Function),
|
|
16
|
-
green: expect.any(Function),
|
|
17
|
-
blue: expect.any(Function)
|
|
18
|
-
})
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
Object.keys(colorMap).forEach(key => {
|
|
22
|
-
expect(typeof colorMap[key]).toBe('function')
|
|
23
|
-
})
|
|
24
|
-
})
|
|
25
|
-
})
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { HttpError } from '~/types'
|
|
4
|
-
|
|
5
|
-
describe('HttpError', () => {
|
|
6
|
-
it('Should create an instance with correct status and message', () => {
|
|
7
|
-
const status = 404
|
|
8
|
-
const message = 'Not Found'
|
|
9
|
-
const error = new HttpError(status, message)
|
|
10
|
-
|
|
11
|
-
expect(error).toBeInstanceOf(Error)
|
|
12
|
-
expect(error).toBeInstanceOf(HttpError)
|
|
13
|
-
expect(error.status).toBe(status)
|
|
14
|
-
expect(error.message).toBe(message)
|
|
15
|
-
})
|
|
16
|
-
})
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, jest } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { LogData, RequestInfo, StoreData } from '~/types'
|
|
4
|
-
|
|
5
|
-
interface Logger {
|
|
6
|
-
info(request: RequestInfo, data: LogData, store: StoreData): void
|
|
7
|
-
warning(request: RequestInfo, data: LogData, store: StoreData): void
|
|
8
|
-
error(request: RequestInfo, data: LogData, store: StoreData): void
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
describe('Logger interface', () => {
|
|
12
|
-
let logger: Logger
|
|
13
|
-
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
logger = {
|
|
16
|
-
info: jest.fn(),
|
|
17
|
-
warning: jest.fn(),
|
|
18
|
-
error: jest.fn()
|
|
19
|
-
}
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('Defines the Logger interface correctly', () => {
|
|
23
|
-
expect(logger).toEqual(
|
|
24
|
-
expect.objectContaining({
|
|
25
|
-
info: expect.any(Function),
|
|
26
|
-
warning: expect.any(Function),
|
|
27
|
-
error: expect.any(Function)
|
|
28
|
-
})
|
|
29
|
-
)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('Calls the info log function with the correct arguments', () => {
|
|
33
|
-
const request: RequestInfo = {
|
|
34
|
-
url: '/info',
|
|
35
|
-
method: 'GET',
|
|
36
|
-
headers: {
|
|
37
|
-
get: function () {
|
|
38
|
-
throw new Error('Function not implemented.')
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
const data: LogData = { status: 200, message: 'Info log message' }
|
|
43
|
-
const store: StoreData = {
|
|
44
|
-
beforeTime: 0n
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
logger.info(request, data, store)
|
|
48
|
-
|
|
49
|
-
expect(logger.info).toHaveBeenCalledWith(request, data, store)
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('Calls the warning log function with the correct arguments', () => {
|
|
53
|
-
const request: RequestInfo = {
|
|
54
|
-
url: '/warning',
|
|
55
|
-
method: 'POST',
|
|
56
|
-
headers: {
|
|
57
|
-
get: function () {
|
|
58
|
-
throw new Error('Function not implemented.')
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
const data: LogData = { status: 404, message: 'Warning log message' }
|
|
63
|
-
const store: StoreData = {
|
|
64
|
-
beforeTime: 0n
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
logger.warning(request, data, store)
|
|
68
|
-
|
|
69
|
-
expect(logger.warning).toHaveBeenCalledWith(request, data, store)
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('Calls the error log function with the correct arguments', () => {
|
|
73
|
-
const request: RequestInfo = {
|
|
74
|
-
url: '/error',
|
|
75
|
-
method: 'DELETE',
|
|
76
|
-
headers: {
|
|
77
|
-
get: function () {
|
|
78
|
-
throw new Error('Function not implemented.')
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
const data: LogData = { status: 500, message: 'Error log message' }
|
|
83
|
-
const store: StoreData = {
|
|
84
|
-
beforeTime: 0n
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
logger.error(request, data, store)
|
|
88
|
-
|
|
89
|
-
expect(logger.error).toHaveBeenCalledWith(request, data, store)
|
|
90
|
-
})
|
|
91
|
-
})
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { RequestInfo } from '~/types'
|
|
4
|
-
|
|
5
|
-
describe('Request Infomation interface', () => {
|
|
6
|
-
it('Defines the RequestInfo interface correctly', () => {
|
|
7
|
-
const headers = { get: () => 'value' }
|
|
8
|
-
const method = 'GET'
|
|
9
|
-
const url = 'https://example.com/api'
|
|
10
|
-
|
|
11
|
-
const request: RequestInfo = { headers, method, url }
|
|
12
|
-
|
|
13
|
-
expect(request).toEqual(
|
|
14
|
-
expect.objectContaining({
|
|
15
|
-
headers: expect.objectContaining({
|
|
16
|
-
get: expect.any(Function)
|
|
17
|
-
}),
|
|
18
|
-
method: expect.any(String),
|
|
19
|
-
url: expect.any(String)
|
|
20
|
-
})
|
|
21
|
-
)
|
|
22
|
-
})
|
|
23
|
-
})
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { Server } from '~/types'
|
|
4
|
-
|
|
5
|
-
describe('Server interface', () => {
|
|
6
|
-
it('Defines the Server interface correctly', () => {
|
|
7
|
-
const server: Server = {
|
|
8
|
-
hostname: 'example.com',
|
|
9
|
-
port: 8080,
|
|
10
|
-
protocol: 'https'
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
expect(server).toEqual(
|
|
14
|
-
expect.objectContaining({
|
|
15
|
-
hostname: expect.any(String),
|
|
16
|
-
port: expect.any(Number),
|
|
17
|
-
protocol: expect.any(String)
|
|
18
|
-
})
|
|
19
|
-
)
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('Allows optional properties in the Server interface', () => {
|
|
23
|
-
const serverWithoutOptionalProps: Server = {}
|
|
24
|
-
|
|
25
|
-
expect(serverWithoutOptionalProps).toEqual(expect.objectContaining({}))
|
|
26
|
-
})
|
|
27
|
-
})
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { StoreData } from '~/types'
|
|
4
|
-
|
|
5
|
-
describe('Store Data interface', () => {
|
|
6
|
-
it('Defines the StoreData interface correctly', () => {
|
|
7
|
-
const beforeTime: bigint = BigInt(1633393533526) // Example bigint value
|
|
8
|
-
|
|
9
|
-
const storeData: StoreData = { beforeTime }
|
|
10
|
-
|
|
11
|
-
expect(storeData).toEqual(
|
|
12
|
-
expect.objectContaining({
|
|
13
|
-
beforeTime: expect.any(BigInt)
|
|
14
|
-
})
|
|
15
|
-
)
|
|
16
|
-
})
|
|
17
|
-
})
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import durationString from '~/utils/duration'
|
|
4
|
-
|
|
5
|
-
describe('Duration String', () => {
|
|
6
|
-
const testCases = [
|
|
7
|
-
[
|
|
8
|
-
'Generates a string representing the duration in Seconds (s) unit',
|
|
9
|
-
1e9,
|
|
10
|
-
's'
|
|
11
|
-
],
|
|
12
|
-
[
|
|
13
|
-
'Generates a string representing the duration in Milliseconds (ms) unit',
|
|
14
|
-
1e6,
|
|
15
|
-
'ms'
|
|
16
|
-
],
|
|
17
|
-
[
|
|
18
|
-
'Generates a string representing the duration in Microseconds (µs) unit',
|
|
19
|
-
1e3,
|
|
20
|
-
'µs'
|
|
21
|
-
]
|
|
22
|
-
// [
|
|
23
|
-
// 'Generates a string representing the duration in Nanoseconds (ns) unit',
|
|
24
|
-
// 1,
|
|
25
|
-
// 'ns'
|
|
26
|
-
// ]
|
|
27
|
-
]
|
|
28
|
-
|
|
29
|
-
for (const [description, nanoseconds, unit] of testCases) {
|
|
30
|
-
it(`${description}`, () => {
|
|
31
|
-
const beforeTime = process.hrtime.bigint() - BigInt(String(nanoseconds))
|
|
32
|
-
const result = durationString(beforeTime)
|
|
33
|
-
|
|
34
|
-
expect(result).toMatch(String(unit))
|
|
35
|
-
})
|
|
36
|
-
}
|
|
37
|
-
})
|
package/test/utils/log.test.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
import chalk from 'chalk'
|
|
3
|
-
|
|
4
|
-
import logString from '~/utils/log'
|
|
5
|
-
|
|
6
|
-
describe('Log String', () => {
|
|
7
|
-
it('Produces a green background string for INFO log level', () => {
|
|
8
|
-
const result = logString('INFO')
|
|
9
|
-
expect(result).toBe(chalk.bgGreen.black('INFO '))
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
it('Produces a yellow background string for WARNING log leve', () => {
|
|
13
|
-
const result = logString('WARNING')
|
|
14
|
-
expect(result).toBe(chalk.bgYellow.black('WARNING'))
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
it('Produces a red background string for ERROR log level', () => {
|
|
18
|
-
const result = logString('ERROR')
|
|
19
|
-
expect(result).toBe(chalk.bgRed.black('ERROR '))
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('Returns the unmodified input string for unrecognized log levels', () => {
|
|
23
|
-
const result = logString('DEBUG') // Assuming 'DEBUG' is not in the colorMap
|
|
24
|
-
expect(result).toBe('DEBUG') // No coloring, returns the original string
|
|
25
|
-
})
|
|
26
|
-
})
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
import chalk from 'chalk'
|
|
3
|
-
|
|
4
|
-
import methodString from '~/utils/method'
|
|
5
|
-
|
|
6
|
-
describe('Method String', () => {
|
|
7
|
-
it('Displays a colored string for the GET method', () => {
|
|
8
|
-
const result = methodString('GET')
|
|
9
|
-
expect(result).toBe(chalk.green('GET '))
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
it('Displays a colored string for the POST method', () => {
|
|
13
|
-
const result = methodString('POST')
|
|
14
|
-
expect(result).toBe(chalk.yellow('POST '))
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
it('Outputs the original method string if it is not recognized', () => {
|
|
18
|
-
const result = methodString('INVALID_METHOD')
|
|
19
|
-
expect(result).toBe('INVALID_METHOD') // No coloring, returns the original string
|
|
20
|
-
})
|
|
21
|
-
})
|
package/test/utils/path.test.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { RequestInfo } from '~/types'
|
|
4
|
-
import pathString from '~/utils/path'
|
|
5
|
-
|
|
6
|
-
describe('Path String', () => {
|
|
7
|
-
it('Extracts the pathname from a valid URL', () => {
|
|
8
|
-
const testPath: RequestInfo = {
|
|
9
|
-
url: 'https://www.example.com/path/to/resource',
|
|
10
|
-
headers: new Map(),
|
|
11
|
-
method: 'GET'
|
|
12
|
-
}
|
|
13
|
-
const result = pathString(testPath)
|
|
14
|
-
expect(result).toBe('/path/to/resource')
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
it('Handles malformed URL gracefully', () => {
|
|
18
|
-
const testPath: RequestInfo = {
|
|
19
|
-
url: 'invalid url',
|
|
20
|
-
headers: new Map(),
|
|
21
|
-
method: 'GET'
|
|
22
|
-
}
|
|
23
|
-
const result = pathString(testPath)
|
|
24
|
-
expect(result).toBeUndefined()
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('Returns undefined if the URL is missing', () => {
|
|
28
|
-
const testPath: RequestInfo = {
|
|
29
|
-
url: '',
|
|
30
|
-
headers: new Map(),
|
|
31
|
-
method: 'GET'
|
|
32
|
-
}
|
|
33
|
-
const result = pathString(testPath)
|
|
34
|
-
expect(result).toBeUndefined()
|
|
35
|
-
})
|
|
36
|
-
})
|
package/test/utils/start.test.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, jest } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { Server } from '~/types'
|
|
4
|
-
import startServer from '~/utils/start'
|
|
5
|
-
|
|
6
|
-
describe('Start String', () => {
|
|
7
|
-
let originalConsoleLog: typeof console.log
|
|
8
|
-
let mockConsoleLog: jest.Mock
|
|
9
|
-
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
originalConsoleLog = console.log
|
|
12
|
-
mockConsoleLog = jest.fn()
|
|
13
|
-
console.log = mockConsoleLog
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
afterEach(() => {
|
|
17
|
-
console.log = originalConsoleLog
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('Correctly logs the expected message upon server start', () => {
|
|
21
|
-
const config: Server = {
|
|
22
|
-
hostname: 'localhost',
|
|
23
|
-
port: 3000,
|
|
24
|
-
protocol: 'http'
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
startServer(config)
|
|
28
|
-
|
|
29
|
-
const expectedMessage = `🦊 Elysia is running at http://localhost:3000`
|
|
30
|
-
|
|
31
|
-
// Extract the arguments passed to console.log during the function call
|
|
32
|
-
const logMessage = mockConsoleLog.mock.calls
|
|
33
|
-
.map(args => args.join(' '))
|
|
34
|
-
.join(' ')
|
|
35
|
-
|
|
36
|
-
expect(logMessage).toMatch(expectedMessage)
|
|
37
|
-
})
|
|
38
|
-
})
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
import chalk from 'chalk'
|
|
3
|
-
|
|
4
|
-
import statusString from '~/utils/status'
|
|
5
|
-
|
|
6
|
-
describe('Status String', () => {
|
|
7
|
-
it('Presents the status string in green for a 200 status code', () => {
|
|
8
|
-
const result = statusString(200)
|
|
9
|
-
expect(result).toBe(chalk.green('200'))
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
it('Presents the status string in cyan for a 301 status code', () => {
|
|
13
|
-
const result = statusString(301)
|
|
14
|
-
expect(result).toBe(chalk.cyan('301'))
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
it('Presents the status string in yellow for a 404 status code', () => {
|
|
18
|
-
const result = statusString(404)
|
|
19
|
-
expect(result).toBe(chalk.yellow('404'))
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('Presents the status string in red for a 500 status code', () => {
|
|
23
|
-
const result = statusString(500)
|
|
24
|
-
expect(result).toBe(chalk.red('500'))
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('Presents the status string in white for a 100 status code', () => {
|
|
28
|
-
const result = statusString(100)
|
|
29
|
-
expect(result).toBe(chalk.white('100'))
|
|
30
|
-
})
|
|
31
|
-
})
|
package/tsconfig.json
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"noUncheckedIndexedAccess": true,
|
|
5
|
-
"strict": true,
|
|
6
|
-
"allowImportingTsExtensions": true,
|
|
7
|
-
"module": "ESNext",
|
|
8
|
-
"moduleResolution": "Bundler",
|
|
9
|
-
"paths": {
|
|
10
|
-
"~/*": ["./src/*"]
|
|
11
|
-
},
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"types": ["bun-types"],
|
|
14
|
-
"downlevelIteration": true,
|
|
15
|
-
"noEmit": true,
|
|
16
|
-
"allowJs": true,
|
|
17
|
-
"allowSyntheticDefaultImports": true,
|
|
18
|
-
"forceConsistentCasingInFileNames": true,
|
|
19
|
-
"jsx": "react",
|
|
20
|
-
"jsxFactory": "ElysiaJSX",
|
|
21
|
-
"jsxFragmentFactory": "ElysiaJSX.Fragment",
|
|
22
|
-
"lib": ["ESNext"],
|
|
23
|
-
"moduleDetection": "force",
|
|
24
|
-
"target": "ESNext",
|
|
25
|
-
"composite": true,
|
|
26
|
-
"skipLibCheck": true
|
|
27
|
-
}
|
|
28
|
-
}
|