logixlysia 2.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 +29 -0
- package/LICENSE +21 -0
- package/README.md +28 -0
- package/lint-staged.config.cjs +21 -0
- package/package.json +85 -0
- package/prettier.config.cjs +11 -0
- package/src/index.ts +48 -0
- package/src/logger.ts +57 -0
- package/src/types/ColorMap.ts +12 -0
- package/src/types/Logger.ts +47 -0
- package/src/types/RequestInfo.ts +16 -0
- package/src/types/Server.ts +16 -0
- package/src/types/StoreData.ts +12 -0
- package/src/utils/duration.ts +38 -0
- package/src/utils/log.ts +27 -0
- package/src/utils/method.ts +31 -0
- package/src/utils/path.ts +15 -0
- package/src/utils/start.ts +45 -0
- package/src/utils/status.ts +27 -0
- package/tsconfig.json +28 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [2.0.0](https://github.com/PunGrumpy/logixlysia/compare/v1.0.0...v2.0.0) (2023-11-19)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **ci/cd:** separate deploy workflows from ci workflows ([e0344ae](https://github.com/PunGrumpy/logixlysia/commit/e0344ae32f711d140b1c914164e8eb7a57181558))
|
|
9
|
+
|
|
10
|
+
## 1.0.0 (2023-11-18)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* add example for test ([8f0f1ee](https://github.com/PunGrumpy/logixlysia/commit/8f0f1ee01de5e5c639687bf0971f0347c3516ed0))
|
|
16
|
+
* add log on start ([f1adeb9](https://github.com/PunGrumpy/logixlysia/commit/f1adeb9c620b42a2639ea6f01fa3e0ebd583ee8f))
|
|
17
|
+
* add logger format and enhance logging functionality ([c0887e8](https://github.com/PunGrumpy/logixlysia/commit/c0887e8eed6142a476d2fd7eb343ef6933e26d31))
|
|
18
|
+
* add new style on logging ([f1d9583](https://github.com/PunGrumpy/logixlysia/commit/f1d95832eacd6528c23454b914c61e09b4c1b83a))
|
|
19
|
+
* **ci:** add google automated workflows ([526e069](https://github.com/PunGrumpy/logixlysia/commit/526e0695029b0235a268445fd1c72b267c030c13))
|
|
20
|
+
* setting environment ([6f5e553](https://github.com/PunGrumpy/logixlysia/commit/6f5e553744999c70de1d8fb1b42a5eb7b75d8798))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* change name ([ee0c164](https://github.com/PunGrumpy/logixlysia/commit/ee0c1645be16a582c4df03874fdf0712e27a9e6a))
|
|
26
|
+
* change to use chalk instead piccolors ([b2fe4f5](https://github.com/PunGrumpy/logixlysia/commit/b2fe4f5a8dce51731e1729b9b0f2c7a15d280978))
|
|
27
|
+
* **types:** add types ([38e1f63](https://github.com/PunGrumpy/logixlysia/commit/38e1f63b4b92f4829772d638d45d7bad8182dbdc))
|
|
28
|
+
* update jsdocs and add new banner ([226c7eb](https://github.com/PunGrumpy/logixlysia/commit/226c7ebac504f661e58a9581c54e1937dfbea4a8))
|
|
29
|
+
* **utils:** update jsdocs ([8cab996](https://github.com/PunGrumpy/logixlysia/commit/8cab996e757d997d3a05183e85d4bfe684fdb11d))
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 PunGrumpy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1><code>🦊</code> Logixlysia</h1>
|
|
3
|
+
<strong>Logixlysia is a logging library for ElysiaJS</strong>
|
|
4
|
+
<img src="./.github/images/screenshot.png" alt="Screenshot of Logixlysia" width="100%" height="auto" />
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
## `📩` Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bun add logixlysia
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## `📝` Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { Elysia } from 'elysia'
|
|
17
|
+
import { logger } from 'logixlysia'
|
|
18
|
+
|
|
19
|
+
const app = new Elysia({
|
|
20
|
+
name: 'Logixlysia Example'
|
|
21
|
+
}).use(logger())
|
|
22
|
+
|
|
23
|
+
app.listen(3000)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## `📄` License
|
|
27
|
+
|
|
28
|
+
Licensed under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
2
|
+
const { existsSync } = require('fs')
|
|
3
|
+
const { join } = require('path')
|
|
4
|
+
|
|
5
|
+
const isBun = existsSync(join(process.cwd(), 'bun.lockb'))
|
|
6
|
+
const isYarn = existsSync(join(process.cwd(), 'yarn.lock'))
|
|
7
|
+
const isPnpm = existsSync(join(process.cwd(), 'pnpm-lock.yaml'))
|
|
8
|
+
|
|
9
|
+
const packageManager = isBun ? 'bun' : isYarn ? 'yarn' : isPnpm ? 'pnpm' : 'npm'
|
|
10
|
+
|
|
11
|
+
const options = {
|
|
12
|
+
'**/*.(ts|tsx)': () => `${packageManager} tsc --noEmit`,
|
|
13
|
+
'**/*.(ts|tsx|js)': filenames => [
|
|
14
|
+
`${packageManager} eslint --fix ${filenames.join(' ')}`,
|
|
15
|
+
`${packageManager} prettier --write ${filenames.join(' ')}`
|
|
16
|
+
],
|
|
17
|
+
'**/*.(md|json)': filenames =>
|
|
18
|
+
`${packageManager} prettier --write ${filenames.join(' ')}`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = options
|
package/package.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "logixlysia",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "🦊 Logixlysia is a logger for Elysia",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"module": "src/index.ts",
|
|
7
|
+
"main": "src/index.ts",
|
|
8
|
+
"author": "PunGrumpy",
|
|
9
|
+
"publisher": "PunGrumpy",
|
|
10
|
+
"maintainers": [
|
|
11
|
+
"PunGrumpy"
|
|
12
|
+
],
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
19
|
+
"dev": "bun run --watch example/basic.ts",
|
|
20
|
+
"prepare": "husky install",
|
|
21
|
+
"lint": "eslint . --ext .ts",
|
|
22
|
+
"lint:fix": "eslint . --ext .ts --fix",
|
|
23
|
+
"lint:staged": "lint-staged",
|
|
24
|
+
"prettier": "prettier --write ."
|
|
25
|
+
},
|
|
26
|
+
"os": [
|
|
27
|
+
"darwin",
|
|
28
|
+
"linux",
|
|
29
|
+
"win32"
|
|
30
|
+
],
|
|
31
|
+
"badges": [
|
|
32
|
+
{
|
|
33
|
+
"name": "npm",
|
|
34
|
+
"url": "https://img.shields.io/npm/v/logixlysia.svg",
|
|
35
|
+
"description": "npm version",
|
|
36
|
+
"href": "https://www.npmjs.com/package/logixlysia"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "npm",
|
|
40
|
+
"url": "https://img.shields.io/npm/dt/logixlysia.svg",
|
|
41
|
+
"description": "npm downloads",
|
|
42
|
+
"href": "https://www.npmjs.com/package/logixlysia"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "GitHub issues",
|
|
46
|
+
"url": "https://img.shields.io/github/issues/PunGrumpy/logixlysia.svg",
|
|
47
|
+
"description": "GitHub issues",
|
|
48
|
+
"href": "https://github.com/PunGrumpy/logixlysia/issues"
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "git+https://github.com/PunGrumpy/logixlysia.git"
|
|
54
|
+
},
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/PunGrumpy/logixlysia/issues"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://github.com/PunGrumpy/logixlysia#readme",
|
|
59
|
+
"keywords": [
|
|
60
|
+
"web",
|
|
61
|
+
"logging",
|
|
62
|
+
"logger",
|
|
63
|
+
"elysia",
|
|
64
|
+
"elysiajs",
|
|
65
|
+
"logixlysia",
|
|
66
|
+
"middleware",
|
|
67
|
+
"middleware"
|
|
68
|
+
],
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"@typescript-eslint/eslint-plugin": "^6.9.1",
|
|
71
|
+
"@typescript-eslint/parser": "^6.9.1",
|
|
72
|
+
"chalk": "^5.3.0",
|
|
73
|
+
"elysia": "^0.7.21",
|
|
74
|
+
"eslint": "^8.53.0"
|
|
75
|
+
},
|
|
76
|
+
"devDependencies": {
|
|
77
|
+
"bun-types": "^1.0.8",
|
|
78
|
+
"husky": "^8.0.3",
|
|
79
|
+
"lint-staged": "^15.0.2",
|
|
80
|
+
"prettier": "^3.0.3"
|
|
81
|
+
},
|
|
82
|
+
"peerDependencies": {
|
|
83
|
+
"typescript": "^5.0.0"
|
|
84
|
+
}
|
|
85
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import Elysia from 'elysia'
|
|
2
|
+
import { createLogger } from './logger'
|
|
3
|
+
import startString from './utils/start'
|
|
4
|
+
import { Server } from 'bun'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a logger.
|
|
8
|
+
*
|
|
9
|
+
* @export {Function} The logger.
|
|
10
|
+
* @module logger
|
|
11
|
+
* @category Logger
|
|
12
|
+
* @subcategory Functions
|
|
13
|
+
*
|
|
14
|
+
* @name Logixlysia
|
|
15
|
+
* @description Logixlysia is a logger plugin for ElysiaJS.
|
|
16
|
+
* @author PunGrumpy
|
|
17
|
+
* @license MIT
|
|
18
|
+
*
|
|
19
|
+
* @returns {Elysia} The logger.
|
|
20
|
+
*/
|
|
21
|
+
export const logger = (): Elysia => {
|
|
22
|
+
const log = createLogger()
|
|
23
|
+
|
|
24
|
+
const elysia = new Elysia({
|
|
25
|
+
name: 'Logixlysia'
|
|
26
|
+
})
|
|
27
|
+
.onStart(ctx => {
|
|
28
|
+
startString(ctx.app.server as Server)
|
|
29
|
+
})
|
|
30
|
+
.onRequest(ctx => {
|
|
31
|
+
ctx.store = { beforeTime: process.hrtime.bigint() } as {
|
|
32
|
+
beforeTime: bigint
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
.onBeforeHandle(ctx => {
|
|
36
|
+
ctx.store = { beforeTime: process.hrtime.bigint() } as {
|
|
37
|
+
beforeTime: bigint
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
.onAfterHandle(({ request, store }) => {
|
|
41
|
+
log.info(request, {}, store as { beforeTime: bigint })
|
|
42
|
+
})
|
|
43
|
+
.onError(({ request, error, store }) => {
|
|
44
|
+
log.error(request, error, store as { beforeTime: bigint })
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
return elysia
|
|
48
|
+
}
|
package/src/logger.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
import durationString from './utils/duration'
|
|
3
|
+
import methodString from './utils/method'
|
|
4
|
+
import logString from './utils/log'
|
|
5
|
+
import pathString from './utils/path'
|
|
6
|
+
import statusString from './utils/status'
|
|
7
|
+
import { RequestInfo } from './types/RequestInfo'
|
|
8
|
+
import { LogData, LogLevel, Logger } from './types/Logger'
|
|
9
|
+
import { StoreData } from './types/StoreData'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Logs a message to the console.
|
|
13
|
+
*
|
|
14
|
+
* @param {LogLevel} level The log level.
|
|
15
|
+
* @param {RequestInfo} request The request information.
|
|
16
|
+
* @param {LogData} data The log data.
|
|
17
|
+
* @param {StoreData} store The store data.
|
|
18
|
+
*
|
|
19
|
+
* @returns {void} The log message.
|
|
20
|
+
*/
|
|
21
|
+
function log(
|
|
22
|
+
level: LogLevel,
|
|
23
|
+
request: RequestInfo,
|
|
24
|
+
data: LogData,
|
|
25
|
+
store: StoreData
|
|
26
|
+
): void {
|
|
27
|
+
const logStr: string[] = []
|
|
28
|
+
const nowStr = chalk.bgYellow(
|
|
29
|
+
chalk.black(
|
|
30
|
+
new Date().toISOString().replace('T', ' ').replace('Z', '').slice(0, -4)
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
const levelStr = logString(level)
|
|
34
|
+
const durationStr = durationString(store.beforeTime)
|
|
35
|
+
const methodStr = methodString(request.method)
|
|
36
|
+
const pathnameStr = pathString(request)
|
|
37
|
+
const statusStr = statusString(data.status || 200)
|
|
38
|
+
const messageStr = data.message || ''
|
|
39
|
+
|
|
40
|
+
logStr.push(
|
|
41
|
+
`🦊 ${nowStr} ${levelStr} ${durationStr} ${methodStr} ${pathnameStr} ${statusStr} ${messageStr}`
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
console.log(logStr.join(' '))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Creates a formatted logger.
|
|
49
|
+
*
|
|
50
|
+
* @returns {Logger} The formatted logger.
|
|
51
|
+
*/
|
|
52
|
+
export const createLogger = (): Logger => ({
|
|
53
|
+
info: (request, data, store) => log(LogLevel.INFO, request, data, store),
|
|
54
|
+
warning: (request, data, store) =>
|
|
55
|
+
log(LogLevel.WARNING, request, data, store),
|
|
56
|
+
error: (request, data, store) => log(LogLevel.ERROR, request, data, store)
|
|
57
|
+
})
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { RequestInfo } from './RequestInfo'
|
|
2
|
+
import { StoreData } from './StoreData'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The log level.
|
|
6
|
+
*
|
|
7
|
+
* @enum {string}
|
|
8
|
+
*
|
|
9
|
+
* @property {string} INFO - The info log level.
|
|
10
|
+
* @property {string} WARNING - The warning log level.
|
|
11
|
+
* @property {string} ERROR - The error log level.
|
|
12
|
+
*/
|
|
13
|
+
enum LogLevel {
|
|
14
|
+
INFO = 'INFO',
|
|
15
|
+
WARNING = 'WARNING',
|
|
16
|
+
ERROR = 'ERROR'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The log data interface.
|
|
21
|
+
*
|
|
22
|
+
* @interface LogData
|
|
23
|
+
*
|
|
24
|
+
* @property {number} status The status code.
|
|
25
|
+
* @property {string} message The message.
|
|
26
|
+
*/
|
|
27
|
+
interface LogData {
|
|
28
|
+
status?: number
|
|
29
|
+
message?: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The logger interface.
|
|
34
|
+
*
|
|
35
|
+
* @interface Logger
|
|
36
|
+
*
|
|
37
|
+
* @property {Function} info Logs an info message.
|
|
38
|
+
* @property {Function} warning Logs a warning message.
|
|
39
|
+
* @property {Function} error Logs an error message.
|
|
40
|
+
*/
|
|
41
|
+
interface Logger {
|
|
42
|
+
info(request: RequestInfo, data: LogData, store: StoreData): void
|
|
43
|
+
warning(request: RequestInfo, data: LogData, store: StoreData): void
|
|
44
|
+
error(request: RequestInfo, data: LogData, store: StoreData): void
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { LogLevel, LogData, Logger }
|
|
@@ -0,0 +1,16 @@
|
|
|
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 }
|
|
@@ -0,0 +1,16 @@
|
|
|
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 }
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Converts the time difference between the start of the request and the end of the request to a formatted string.
|
|
5
|
+
*
|
|
6
|
+
* @param {bigint} beforeTime The timestamp taken before the request.
|
|
7
|
+
*
|
|
8
|
+
* @returns {string} A formatted duration string with a time unit.
|
|
9
|
+
*/
|
|
10
|
+
function durationString(beforeTime: bigint): string {
|
|
11
|
+
const now = process.hrtime.bigint()
|
|
12
|
+
const timeDifference = now - beforeTime
|
|
13
|
+
const nanoseconds = Number(timeDifference)
|
|
14
|
+
|
|
15
|
+
const durationInMicroseconds = (nanoseconds / 1e3).toFixed(0)
|
|
16
|
+
const durationInMilliseconds = (nanoseconds / 1e6).toFixed(0)
|
|
17
|
+
|
|
18
|
+
let timeMessage: string = ''
|
|
19
|
+
|
|
20
|
+
if (nanoseconds >= 1e9) {
|
|
21
|
+
const seconds = (nanoseconds / 1e9).toFixed(2)
|
|
22
|
+
timeMessage = `${seconds}s`
|
|
23
|
+
} else if (nanoseconds >= 1e6) {
|
|
24
|
+
timeMessage = `${durationInMilliseconds}ms`
|
|
25
|
+
} else if (nanoseconds >= 1e3) {
|
|
26
|
+
timeMessage = `${durationInMicroseconds}µs`
|
|
27
|
+
} else {
|
|
28
|
+
timeMessage = `${nanoseconds}ns`
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (timeMessage) {
|
|
32
|
+
timeMessage = chalk.gray(timeMessage).padStart(8).padEnd(16)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return timeMessage
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default durationString
|
package/src/utils/log.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
import { ColorMap } from '~/types/ColorMap'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Converts a log level to a colored string representation.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} log The log level (e.g., 'INFO', 'WARNING').
|
|
8
|
+
*
|
|
9
|
+
* @returns {string} A colored string representing the log level.
|
|
10
|
+
*/
|
|
11
|
+
function logString(log: string): string {
|
|
12
|
+
const colorMap: ColorMap = {
|
|
13
|
+
INFO: chalk.bgGreen,
|
|
14
|
+
WARNING: chalk.bgYellow,
|
|
15
|
+
ERROR: chalk.bgRed
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const colorFunction = colorMap[log]
|
|
19
|
+
|
|
20
|
+
if (colorFunction) {
|
|
21
|
+
return colorFunction(chalk.black(log.padEnd(7)))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return log
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default logString
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
import { ColorMap } from '~/types/ColorMap'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Converts an HTTP request method to a colored string representation.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} method The HTTP request method (e.g., 'GET', 'POST').
|
|
8
|
+
*
|
|
9
|
+
* @returns {string} A colored string representing the method.
|
|
10
|
+
*/
|
|
11
|
+
function methodString(method: string): string {
|
|
12
|
+
const colorMap: ColorMap = {
|
|
13
|
+
GET: chalk.white,
|
|
14
|
+
POST: chalk.yellow,
|
|
15
|
+
PUT: chalk.blue,
|
|
16
|
+
DELETE: chalk.red,
|
|
17
|
+
PATCH: chalk.green,
|
|
18
|
+
OPTIONS: chalk.cyan,
|
|
19
|
+
HEAD: chalk.magenta
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const colorFunction = colorMap[method]
|
|
23
|
+
|
|
24
|
+
if (colorFunction) {
|
|
25
|
+
return colorFunction(method.padEnd(7))
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return method
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default methodString
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RequestInfo } from '~/types/RequestInfo'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns the path string.
|
|
5
|
+
*
|
|
6
|
+
* @param {RequestInfo} path The request information.
|
|
7
|
+
*
|
|
8
|
+
* @returns {string} The path string.
|
|
9
|
+
*/
|
|
10
|
+
function pathString(path: RequestInfo): string {
|
|
11
|
+
const url = new URL(path?.url).pathname
|
|
12
|
+
return url
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default pathString
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Server } from '~/types/Server'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates a box text.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} text The text.
|
|
7
|
+
* @param {number} width The box width.
|
|
8
|
+
*
|
|
9
|
+
* @returns {string} The box text.
|
|
10
|
+
*/
|
|
11
|
+
function createBoxText(text: string, width: number): string {
|
|
12
|
+
const padding = ' '.repeat((width - text.length) / 2)
|
|
13
|
+
return `${padding}${text}${padding}`
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Starts the server string.
|
|
18
|
+
*
|
|
19
|
+
* @param {Server} config The server configuration.
|
|
20
|
+
*
|
|
21
|
+
* @returns {void} The server string.
|
|
22
|
+
*/
|
|
23
|
+
function startString(config: Server): void {
|
|
24
|
+
const { hostname, port, protocol } = config
|
|
25
|
+
const ELYSIA_VERSION = import.meta.require('elysia/package.json').version
|
|
26
|
+
const title = `Elysia v${ELYSIA_VERSION}`
|
|
27
|
+
const message = `🦊 Elysia is running at ${protocol}://${hostname}:${port}`
|
|
28
|
+
const messageWidth = message.length
|
|
29
|
+
const boxWidth = Math.max(title.length, messageWidth) + 4
|
|
30
|
+
const border = '─'.repeat(boxWidth)
|
|
31
|
+
|
|
32
|
+
process.stdout.write('\x1Bc')
|
|
33
|
+
|
|
34
|
+
console.log(`
|
|
35
|
+
┌${border}┐
|
|
36
|
+
│${createBoxText('', boxWidth)} │
|
|
37
|
+
│${createBoxText(title, boxWidth)} │
|
|
38
|
+
│${createBoxText('', boxWidth)} │
|
|
39
|
+
│${createBoxText(message, boxWidth)}│
|
|
40
|
+
│${createBoxText('', boxWidth)} │
|
|
41
|
+
└${border}┘
|
|
42
|
+
`)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default startString
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns the status string.
|
|
5
|
+
*
|
|
6
|
+
* @param {number} status The status code.
|
|
7
|
+
*
|
|
8
|
+
* @returns {string} The status string.
|
|
9
|
+
*/
|
|
10
|
+
function statusString(status: number): string {
|
|
11
|
+
if (status >= 500) {
|
|
12
|
+
return chalk.red(status.toString())
|
|
13
|
+
}
|
|
14
|
+
if (status >= 400) {
|
|
15
|
+
return chalk.yellow(status.toString())
|
|
16
|
+
}
|
|
17
|
+
if (status >= 300) {
|
|
18
|
+
return chalk.cyan(status.toString())
|
|
19
|
+
}
|
|
20
|
+
if (status >= 200) {
|
|
21
|
+
return chalk.green(status.toString())
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return status.toString()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default statusString
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
}
|