logixlysia 4.1.2 → 4.2.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.
Files changed (34) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +1 -31
  3. package/package.json +14 -28
  4. package/src/extensions/index.ts +1 -0
  5. package/src/{plugins/startServer.ts → extensions/start-server.ts} +1 -1
  6. package/src/{utils/colorMapping.ts → helpers/color-mapping.ts} +1 -1
  7. package/src/{utils → helpers}/index.ts +1 -1
  8. package/src/{utils → helpers}/log.ts +2 -2
  9. package/src/{utils → helpers}/method.ts +1 -1
  10. package/src/{utils → helpers}/path.ts +1 -1
  11. package/src/{utils → helpers}/status.ts +18 -6
  12. package/src/{utils → helpers}/timestamp.ts +1 -1
  13. package/src/index.ts +9 -7
  14. package/src/{types → interfaces}/index.ts +9 -11
  15. package/src/{core/buildLogMessage.ts → logger/build-log-message.ts} +10 -10
  16. package/src/{core/createLogger.ts → logger/create-logger.ts} +10 -9
  17. package/src/{core → logger}/filter.ts +5 -3
  18. package/src/{core/handleHttpError.ts → logger/handle-http-error.ts} +4 -4
  19. package/src/logger/index.ts +2 -0
  20. package/src/{transports → output}/console.ts +8 -2
  21. package/src/{transports → output}/file.ts +11 -6
  22. package/.gitmodules +0 -3
  23. package/src/core/index.ts +0 -2
  24. package/src/plugins/index.ts +0 -1
  25. package/tests/__mocks__/fs.ts +0 -9
  26. package/tests/core/buildLogMessage.test.ts +0 -45
  27. package/tests/core/filter.test.ts +0 -35
  28. package/tests/helpers.ts +0 -19
  29. package/tests/logixlysia.test.ts +0 -8
  30. package/tests/transports/logToTransports.test.ts +0 -29
  31. package/tests/utils/status.test.ts +0 -46
  32. package/tests/utils/timestamp.test.ts +0 -35
  33. /package/src/{utils → helpers}/duration.ts +0 -0
  34. /package/src/{transports → output}/index.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.2.0](https://github.com/PunGrumpy/logixlysia/compare/v4.1.2...v4.2.0) (2025-04-13)
4
+
5
+
6
+ ### Features
7
+
8
+ * **docs:** add screenshot to documentation introduction ([800bb17](https://github.com/PunGrumpy/logixlysia/commit/800bb17dcfda88699cd7a0a2dc2e199e5704ce61))
9
+ * **website:** add new components and integrate react-fast-marquee ([6332f62](https://github.com/PunGrumpy/logixlysia/commit/6332f622c22fccf4cbadfb2a0099b9fac723f61a))
10
+ * **website:** add Open Graph image for enhanced social sharing ([de35d41](https://github.com/PunGrumpy/logixlysia/commit/de35d413bf6a10b06933eb2619d3cb6459618c3e))
11
+ * **website:** add transparent mode to navigation title ([9c01757](https://github.com/PunGrumpy/logixlysia/commit/9c01757f8808b5792b792fc1ed56e5b6e26603d2))
12
+ * **website:** add website documentation ([82e281c](https://github.com/PunGrumpy/logixlysia/commit/82e281cd5c08fa948ecf103eb70f218e61029142))
13
+ * **website:** enhance logging features and update documentation ([fa7ea45](https://github.com/PunGrumpy/logixlysia/commit/fa7ea45ae8c535a22b52e94a46df5931009e013f))
14
+ * **website:** initialize new documentation website with Fumadocs ([c864d9f](https://github.com/PunGrumpy/logixlysia/commit/c864d9f00ea6d0250f2db8b20a994975da18185e))
15
+ * **website:** integrate GitHub info component into layout ([5cd282c](https://github.com/PunGrumpy/logixlysia/commit/5cd282c072e56d90a7554a78dad1f27e8eb13400))
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **docs:** correct license information in documentation ([e64f156](https://github.com/PunGrumpy/logixlysia/commit/e64f1565a2100a08ee324ddf68769726dcc6d9ff))
21
+ * **docs:** update file logging examples for clarity and consistency ([1d8653f](https://github.com/PunGrumpy/logixlysia/commit/1d8653f5aa97f8b6d829a10c0a510fc5a5b7dcae))
22
+ * **docs:** update help section for user support ([84e5052](https://github.com/PunGrumpy/logixlysia/commit/84e5052ddf4ef8e636d68be113d866df2d13fd09))
23
+ * **playground:** correct class name syntax for overflow visibility ([25ed919](https://github.com/PunGrumpy/logixlysia/commit/25ed919c1592129d8495afbc2927befb0c431fa0))
24
+ * **website:** adjust z-index for background image and hero component ([af593a7](https://github.com/PunGrumpy/logixlysia/commit/af593a709d625df06f2f0e7ecff55764be46cdd5))
25
+ * **website:** adjust z-index for hero component to improve visibility ([4cc144e](https://github.com/PunGrumpy/logixlysia/commit/4cc144e50c5e0e869e62c3821edd2216acf4cacd))
26
+ * **website:** simplify sidebar configuration in layout component ([dc7e479](https://github.com/PunGrumpy/logixlysia/commit/dc7e47962085c4922dcfaad83e1ce0e38dcfeff0))
27
+ * **website:** update logo assets and adjust class names ([18c8c57](https://github.com/PunGrumpy/logixlysia/commit/18c8c57a2337f3242e77eb0234afee487039f554))
28
+ * **website:** update sidebar configuration to include collapsible property ([2d27ee3](https://github.com/PunGrumpy/logixlysia/commit/2d27ee31b3eeb79505a70dee2fef214a45fb1a9e))
29
+
3
30
  ## [4.1.2](https://github.com/PunGrumpy/logixlysia/compare/v4.1.1...v4.1.2) (2025-02-24)
4
31
 
5
32
 
package/README.md CHANGED
@@ -42,39 +42,9 @@ const app = new Elysia({
42
42
  app.listen(3000)
43
43
  ```
44
44
 
45
- > [!NOTE]
46
- > You can discover more about example in the [example](example) directory.
47
-
48
- > [!TIP]
49
- > Also, you can play my example with Swagger UI on `http://localhost:3000/swagger`.
50
-
51
45
  ## `📚` Documentation
52
46
 
53
- ### Options
54
-
55
- | Option | Type | Description | Default |
56
- | ---------------------- | ------------------------ | --------------------------------------------------------------------- | ------------------------------------------------------------------------- |
57
- | `showStartupMessage` | `boolean` | Display the startup message | `true` |
58
- | `startupMessageFormat` | `"banner"` \| `"simple"` | Choose the startup message format | `"banner"` |
59
- | `timestamp` | `object` | Display the timestamp in the logs | `{ translateTime: 'yyyy-mm-dd HH:MM:ss' }` |
60
- | `ip` | `boolean` | Display the incoming IP address based on the `X-Forwarded-For` header | `false` |
61
- | `customLogMessage` | `string` | Custom log message to display | `🦊 {now} {level} {duration} {method} {pathname} {status} {message} {ip}` |
62
- | `logFilter` | `object` | Filter the logs based on the level, method, and status | `null` |
63
- | `logFilePath` | `string` | Path to the log file | `./logs/elysia.log` |
64
-
65
- ### Custom Log Message
66
-
67
- | Placeholder | Description |
68
- | ------------ | --------------------------------------------------------------------------- |
69
- | `{now}` | Current date and time in `YYYY-MM-DD HH:mm:ss` format |
70
- | `{level}` | Log level (`INFO`, `WARNING`, `ERROR`) |
71
- | `{duration}` | Request duration in milliseconds |
72
- | `{method}` | Request method (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`, `OPTIONS`) |
73
- | `{pathname}` | Request pathname |
74
- | `{status}` | Response status code |
75
- | `{message}` | Custom message |
76
- | `{ip}` | Incoming IP address |
77
- | `{epoch}` | Current date and time in Unix epoch format (seconds since January 1, 1970 |
47
+ Check out the [website](https://logixlysia.vercel.app) for more detailed documentation and examples.
78
48
 
79
49
  ## `📄` License
80
50
 
package/package.json CHANGED
@@ -1,15 +1,13 @@
1
1
  {
2
2
  "name": "logixlysia",
3
- "version": "4.1.2",
3
+ "version": "4.2.0",
4
4
  "description": "🦊 Logixlysia is a logger for Elysia",
5
5
  "type": "module",
6
6
  "module": "src/index.ts",
7
7
  "main": "src/index.ts",
8
8
  "author": "PunGrumpy",
9
9
  "publisher": "PunGrumpy",
10
- "maintainers": [
11
- "PunGrumpy"
12
- ],
10
+ "maintainers": ["PunGrumpy"],
13
11
  "contributors": [
14
12
  {
15
13
  "name": "n0ky4",
@@ -21,23 +19,17 @@
21
19
  },
22
20
  "license": "MIT",
23
21
  "scripts": {
24
- "lint": "eslint .",
25
- "lint:fix": "eslint . --fix",
26
- "test": "bun test --timeout 5000 --coverage",
22
+ "lint": "ultracite lint",
23
+ "format": "ultracite format",
24
+ "test": "bun test --timeout 5000",
27
25
  "test:ci": "bun test --timeout 5000 --coverage --coverage-reporter=lcov",
28
26
  "publish": "npm publish",
29
- "dev": "bun run --watch example/basic.ts",
27
+ "dev": "cd website && bun dev",
30
28
  "prepare": "husky",
31
- "lint:staged": "lint-staged",
32
- "format": "prettier --write --config .trunk/configs/.prettierrc.yaml .",
33
- "trunk:check": "trunk check",
34
- "trunk:fmt": "trunk fmt"
29
+ "test:coverage": "bun test --timeout 5000 --coverage",
30
+ "clean": "git clean -fdx && rm -rf node_modules && rm -rf logs && cd website && rm -rf node_modules && rm -rf .next && rm -rf .source"
35
31
  },
36
- "os": [
37
- "darwin",
38
- "linux",
39
- "win32"
40
- ],
32
+ "os": ["darwin", "linux", "win32"],
41
33
  "badges": [
42
34
  {
43
35
  "name": "npm",
@@ -65,7 +57,7 @@
65
57
  "bugs": {
66
58
  "url": "https://github.com/PunGrumpy/logixlysia/issues"
67
59
  },
68
- "homepage": "https://github.com/PunGrumpy/logixlysia#readme",
60
+ "homepage": "https://logixlysia.vercel.app",
69
61
  "keywords": [
70
62
  "web",
71
63
  "logging",
@@ -80,19 +72,13 @@
80
72
  "elysia": "^1.1.23"
81
73
  },
82
74
  "devDependencies": {
83
- "@elysiajs/swagger": "^1.2.0",
75
+ "@biomejs/biome": "^1.9.4",
84
76
  "@elysiajs/eden": "^1.1.3",
85
- "@eslint/js": "^9.13.0",
86
- "@trunkio/launcher": "^1.3.2",
87
- "@typescript-eslint/eslint-plugin": "^8.11.0",
88
- "@typescript-eslint/parser": "^8.11.0",
77
+ "@elysiajs/swagger": "^1.2.0",
89
78
  "bun-types": "^1.1.33",
90
- "eslint-plugin-simple-import-sort": "^12.1.1",
91
- "globals": "^15.11.0",
79
+ "globals": "^16.0.0",
92
80
  "husky": "^9.1.6",
93
- "lint-staged": "^15.2.10",
94
- "prettier": "^3.3.3",
95
- "typescript-eslint": "^8.11.0"
81
+ "ultracite": "^4.2.1"
96
82
  },
97
83
  "peerDependencies": {
98
84
  "typescript": "^5.2.2"
@@ -0,0 +1 @@
1
+ export { default as startServer } from './start-server'
@@ -1,4 +1,4 @@
1
- import { Options, Server } from '../types'
1
+ import type { Options, Server } from '../interfaces'
2
2
 
3
3
  const createBoxText = (text: string, width: number): string => {
4
4
  const paddingLength = Math.max(0, (width - text.length) / 2)
@@ -1,6 +1,6 @@
1
1
  import chalk from 'chalk'
2
2
 
3
- import { ColorMap } from '../types'
3
+ import type { ColorMap } from '../interfaces'
4
4
 
5
5
  export const LogLevelColorMap: ColorMap = {
6
6
  INFO: chalk.bgGreen.black,
@@ -1,4 +1,4 @@
1
- export { HttpMethodColorMap, LogLevelColorMap } from './colorMapping'
1
+ export { HttpMethodColorMap, LogLevelColorMap } from './color-mapping'
2
2
  export { default as durationString } from './duration'
3
3
  export { default as logString } from './log'
4
4
  export { default as methodString } from './method'
@@ -1,5 +1,5 @@
1
- import { LogLevel } from '../types'
2
- import { LogLevelColorMap } from './colorMapping'
1
+ import type { LogLevel } from '../interfaces'
2
+ import { LogLevelColorMap } from './color-mapping'
3
3
 
4
4
  export default function logString(level: LogLevel, useColors: boolean): string {
5
5
  const levelStr = level.toUpperCase()
@@ -1,4 +1,4 @@
1
- import { HttpMethodColorMap } from './colorMapping'
1
+ import { HttpMethodColorMap } from './color-mapping'
2
2
 
3
3
  export default function methodString(
4
4
  method: string,
@@ -1,4 +1,4 @@
1
- import { RequestInfo } from '../types'
1
+ import type { RequestInfo } from '../interfaces'
2
2
 
3
3
  export default function pathString(
4
4
  requestInfo: RequestInfo
@@ -2,7 +2,9 @@ import chalk from 'chalk'
2
2
  import { StatusMap } from 'elysia'
3
3
 
4
4
  export function getStatusCode(status: string | number): number {
5
- if (typeof status === 'number') return status
5
+ if (typeof status === 'number') {
6
+ return status
7
+ }
6
8
  return (StatusMap as Record<string, number>)[status] || 500
7
9
  }
8
10
 
@@ -11,11 +13,21 @@ export default function statusString(
11
13
  useColors: boolean
12
14
  ): string {
13
15
  const statusStr = status.toString()
14
- if (!useColors) return statusStr
16
+ if (!useColors) {
17
+ return statusStr
18
+ }
15
19
 
16
- if (status >= 500) return chalk.red(statusStr)
17
- if (status >= 400) return chalk.yellow(statusStr)
18
- if (status >= 300) return chalk.cyan(statusStr)
19
- if (status >= 200) return chalk.green(statusStr)
20
+ if (status >= 500) {
21
+ return chalk.red(statusStr)
22
+ }
23
+ if (status >= 400) {
24
+ return chalk.yellow(statusStr)
25
+ }
26
+ if (status >= 300) {
27
+ return chalk.cyan(statusStr)
28
+ }
29
+ if (status >= 200) {
30
+ return chalk.green(statusStr)
31
+ }
20
32
  return chalk.white(statusStr)
21
33
  }
@@ -1,4 +1,4 @@
1
- import { TimestampConfig } from '../types'
1
+ import type { TimestampConfig } from '../interfaces'
2
2
 
3
3
  // const DEFAULT_TIMESTAMP_FORMAT = 'yyyy-mm-dd HH:MM:ss'
4
4
  const SYS_TIME = 'SYS:STANDARD'
package/src/index.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { Elysia } from 'elysia'
2
2
 
3
- import { createLogger } from './core'
4
- import { startServer } from './plugins'
5
- import { HttpError, Options, Server } from './types'
6
- import { getStatusCode } from './utils/status'
3
+ import { startServer } from './extensions'
4
+ import { getStatusCode } from './helpers/status'
5
+ import type { HttpError, Options, Server } from './interfaces'
6
+ import { createLogger } from './logger'
7
7
 
8
8
  export default function logixlysia(options?: Options): Elysia {
9
9
  const log = createLogger(options)
@@ -13,7 +13,9 @@ export default function logixlysia(options?: Options): Elysia {
13
13
  })
14
14
  .onStart(ctx => {
15
15
  const showStartupMessage = options?.config?.showStartupMessage ?? true
16
- if (showStartupMessage) startServer(ctx.server as Server, options)
16
+ if (showStartupMessage) {
17
+ startServer(ctx.server as Server, options)
18
+ }
17
19
  })
18
20
  .onRequest(ctx => {
19
21
  ctx.store = { beforeTime: process.hrtime.bigint() }
@@ -40,5 +42,5 @@ export default function logixlysia(options?: Options): Elysia {
40
42
  })
41
43
  }
42
44
 
43
- export { createLogger, handleHttpError } from './core'
44
- export { logToTransports } from './transports'
45
+ export { createLogger, handleHttpError } from './logger'
46
+ export { logToTransports } from './output'
@@ -61,17 +61,15 @@ export class HttpError extends Error {
61
61
  }
62
62
  }
63
63
 
64
- export interface TransportFunction {
65
- (
66
- level: LogLevel,
67
- message: string,
68
- meta: {
69
- request: RequestInfo
70
- data: LogData
71
- store: StoreData
72
- }
73
- ): Promise<void> | void
74
- }
64
+ export type TransportFunction = (
65
+ level: LogLevel,
66
+ message: string,
67
+ meta: {
68
+ request: RequestInfo
69
+ data: LogData
70
+ store: StoreData
71
+ }
72
+ ) => Promise<void> | void
75
73
 
76
74
  export interface Transport {
77
75
  log: TransportFunction
@@ -1,13 +1,5 @@
1
1
  import chalk from 'chalk'
2
2
 
3
- import {
4
- LogComponents,
5
- LogData,
6
- LogLevel,
7
- Options,
8
- RequestInfo,
9
- StoreData
10
- } from '../types'
11
3
  import {
12
4
  durationString,
13
5
  formatTimestamp,
@@ -15,7 +7,15 @@ import {
15
7
  methodString,
16
8
  pathString,
17
9
  statusString
18
- } from '../utils'
10
+ } from '../helpers'
11
+ import type {
12
+ LogComponents,
13
+ LogData,
14
+ LogLevel,
15
+ Options,
16
+ RequestInfo,
17
+ StoreData
18
+ } from '../interfaces'
19
19
 
20
20
  const defaultLogFormat =
21
21
  '🦊 {now} {level} {duration} {method} {pathname} {status} {message} {ip}'
@@ -33,7 +33,7 @@ export function buildLogMessage(
33
33
  data: LogData,
34
34
  store: StoreData,
35
35
  options?: Options,
36
- useColors: boolean = true
36
+ useColors = true
37
37
  ): string {
38
38
  const actuallyUseColors = shouldUseColors(useColors, options)
39
39
  const now = new Date()
@@ -1,16 +1,15 @@
1
- import { logToTransports } from '../transports'
2
- import { logToFile } from '../transports'
3
- import {
1
+ import type {
4
2
  LogData,
5
- Logger,
6
3
  LogLevel,
4
+ Logger,
7
5
  Options,
8
6
  RequestInfo,
9
7
  StoreData
10
- } from '../types'
11
- import { buildLogMessage } from './buildLogMessage'
8
+ } from '../interfaces'
9
+ import { logToFile, logToTransports } from '../output'
10
+ import { buildLogMessage } from './build-log-message'
12
11
  import { filterLog } from './filter'
13
- import { handleHttpError } from './handleHttpError'
12
+ import { handleHttpError } from './handle-http-error'
14
13
 
15
14
  async function log(
16
15
  level: LogLevel,
@@ -19,12 +18,14 @@ async function log(
19
18
  store: StoreData,
20
19
  options?: Options
21
20
  ): Promise<void> {
22
- if (!filterLog(level, data.status || 200, request.method, options)) return
21
+ if (!filterLog(level, data.status || 200, request.method, options)) {
22
+ return
23
+ }
23
24
 
24
25
  const logMessage = buildLogMessage(level, request, data, store, options, true)
25
26
  console.log(logMessage)
26
27
 
27
- const promises = []
28
+ const promises: Promise<void>[] = []
28
29
 
29
30
  if (options?.config?.logFilePath) {
30
31
  promises.push(
@@ -1,6 +1,6 @@
1
- import { LogLevel, Options } from '../types'
1
+ import type { LogLevel, Options } from '../interfaces'
2
2
 
3
- const checkFilter = (filterValue: any, value: any) =>
3
+ const checkFilter = (filterValue: unknown, value: unknown) =>
4
4
  Array.isArray(filterValue)
5
5
  ? filterValue.includes(value)
6
6
  : filterValue === value
@@ -12,7 +12,9 @@ export function filterLog(
12
12
  options?: Options
13
13
  ): boolean {
14
14
  const filter = options?.config?.logFilter
15
- if (!filter) return true
15
+ if (!filter) {
16
+ return true
17
+ }
16
18
 
17
19
  return (
18
20
  (!filter.level || checkFilter(filter.level, logLevel)) &&
@@ -1,6 +1,6 @@
1
- import { logToFile } from '../transports'
2
- import { HttpError, Options, RequestInfo, StoreData } from '../types'
3
- import { buildLogMessage } from './buildLogMessage'
1
+ import type { HttpError, Options, RequestInfo, StoreData } from '../interfaces'
2
+ import { logToFile } from '../output'
3
+ import { buildLogMessage } from './build-log-message'
4
4
 
5
5
  export function handleHttpError(
6
6
  request: RequestInfo,
@@ -13,7 +13,7 @@ export function handleHttpError(
13
13
  buildLogMessage('ERROR', request, { status: statusCode }, store, options)
14
14
  )
15
15
 
16
- const promises = []
16
+ const promises: Promise<void>[] = []
17
17
 
18
18
  if (options?.config?.logFilePath) {
19
19
  promises.push(
@@ -0,0 +1,2 @@
1
+ export { createLogger } from './create-logger'
2
+ export { handleHttpError } from './handle-http-error'
@@ -1,5 +1,11 @@
1
- import { buildLogMessage } from '../core/buildLogMessage'
2
- import { LogData, LogLevel, Options, RequestInfo, StoreData } from '../types'
1
+ import type {
2
+ LogData,
3
+ LogLevel,
4
+ Options,
5
+ RequestInfo,
6
+ StoreData
7
+ } from '../interfaces'
8
+ import { buildLogMessage } from '../logger/build-log-message'
3
9
 
4
10
  export async function logToTransports(
5
11
  level: LogLevel,
@@ -1,8 +1,14 @@
1
- import { promises as fs } from 'fs'
2
- import { dirname } from 'path'
1
+ import { promises as fs } from 'node:fs'
2
+ import { dirname } from 'node:path'
3
3
 
4
- import { buildLogMessage } from '../core/buildLogMessage'
5
- import { LogData, LogLevel, Options, RequestInfo, StoreData } from '../types'
4
+ import type {
5
+ LogData,
6
+ LogLevel,
7
+ Options,
8
+ RequestInfo,
9
+ StoreData
10
+ } from '../interfaces'
11
+ import { buildLogMessage } from '../logger/build-log-message'
6
12
 
7
13
  const dirCache = new Set<string>()
8
14
 
@@ -23,7 +29,6 @@ export async function logToFile(
23
29
  options?: Options
24
30
  ): Promise<void> {
25
31
  await ensureDirectoryExists(filePath)
26
- const logMessage =
27
- buildLogMessage(level, request, data, store, options, false) + '\n'
32
+ const logMessage = `${buildLogMessage(level, request, data, store, options, false)}\n`
28
33
  await fs.appendFile(filePath, logMessage, { flag: 'a' })
29
34
  }
package/.gitmodules DELETED
@@ -1,3 +0,0 @@
1
- [submodule ".trunk/configs"]
2
- path = .trunk/configs
3
- url = git@github.com:PunGrumpy/.trunk.git
package/src/core/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export { createLogger } from './createLogger'
2
- export { handleHttpError } from './handleHttpError'
@@ -1 +0,0 @@
1
- export { default as startServer } from './startServer'
@@ -1,9 +0,0 @@
1
- import { mock } from 'bun:test'
2
-
3
- export const mockAppend = mock(() => Promise.resolve())
4
- export const mockMkdir = mock(() => Promise.resolve())
5
-
6
- export const promises = {
7
- appendFile: mockAppend,
8
- mkdir: mockMkdir
9
- }
@@ -1,45 +0,0 @@
1
- import { expect, test } from 'bun:test'
2
-
3
- import { buildLogMessage } from '../../src/core/buildLogMessage'
4
- import { LogData, LogLevel, Options, StoreData } from '../../src/types'
5
- import { createMockRequest } from '../helpers'
6
-
7
- test('buildLogMessage', () => {
8
- const level: LogLevel = 'INFO'
9
- const request = createMockRequest()
10
- const data: LogData = { status: 200, message: 'Test message' }
11
- const store: StoreData = { beforeTime: BigInt(0) }
12
- const options: Options = {
13
- config: {
14
- ip: true,
15
- customLogFormat: '{level} {message} {ip}'
16
- }
17
- }
18
-
19
- const message = buildLogMessage(level, request, data, store, options, false)
20
- expect(message).toContain('INFO')
21
- expect(message).toContain('Test message')
22
- expect(message).toContain('127.0.0.1')
23
-
24
- const colorMessage = buildLogMessage(
25
- level,
26
- request,
27
- data,
28
- store,
29
- options,
30
- true
31
- )
32
-
33
- expect(colorMessage).toContain('INFO')
34
- expect(colorMessage).toContain('Test message')
35
- expect(colorMessage).toContain('127.0.0.1')
36
-
37
- const hasAnsiCodes = /\\x1B\[[0-9;]*m/.test(colorMessage)
38
- if (hasAnsiCodes) {
39
- expect(colorMessage).not.toBe(message)
40
- } else {
41
- console.warn(
42
- 'No ANSI color codes detected. Colors might be disabled in this environment.'
43
- )
44
- }
45
- })
@@ -1,35 +0,0 @@
1
- import { expect, test } from 'bun:test'
2
-
3
- import { filterLog } from '../../src/core/filter'
4
- import { Options } from '../../src/types'
5
-
6
- test('filterLog', () => {
7
- const options: Options = {
8
- config: {
9
- logFilter: {
10
- level: 'ERROR',
11
- method: 'POST',
12
- status: 500
13
- }
14
- }
15
- }
16
-
17
- expect(filterLog('ERROR', 500, 'POST', options)).toBe(true)
18
- expect(filterLog('INFO', 200, 'GET', options)).toBe(false)
19
- expect(filterLog('WARNING', 400, 'PUT', options)).toBe(false)
20
-
21
- // Test with array filters
22
- const arrayOptions: Options = {
23
- config: {
24
- logFilter: {
25
- level: ['ERROR', 'WARNING'],
26
- method: ['POST', 'PUT'],
27
- status: [500, 400]
28
- }
29
- }
30
- }
31
-
32
- expect(filterLog('ERROR', 500, 'POST', arrayOptions)).toBe(true)
33
- expect(filterLog('WARNING', 400, 'PUT', arrayOptions)).toBe(true)
34
- expect(filterLog('INFO', 200, 'GET', arrayOptions)).toBe(false)
35
- })
package/tests/helpers.ts DELETED
@@ -1,19 +0,0 @@
1
- import { mock } from 'bun:test'
2
-
3
- import { RequestInfo } from '../src/types'
4
-
5
- export function createMockRequest(
6
- method: string = 'GET',
7
- url: string = 'http://localhost:3000/'
8
- ): RequestInfo {
9
- return {
10
- headers: {
11
- get: (key: string) => (key === 'x-forwarded-for' ? '127.0.0.1' : null)
12
- },
13
- method,
14
- url
15
- }
16
- }
17
-
18
- export const mockConsoleLog = mock(() => {})
19
- export const mockConsoleError = mock(() => {})
@@ -1,8 +0,0 @@
1
- import { expect, test } from 'bun:test'
2
-
3
- import logixlysia from '../src/index'
4
-
5
- test('logixlysia', () => {
6
- const elysia = logixlysia()
7
- expect(elysia).toBeDefined()
8
- })
@@ -1,29 +0,0 @@
1
- import { expect, mock, test } from 'bun:test'
2
-
3
- import { logToTransports } from '../../src/transports'
4
- import { LogData, LogLevel, Options, StoreData } from '../../src/types'
5
- import { createMockRequest } from '../helpers'
6
-
7
- test('logToTransports', async () => {
8
- const level: LogLevel = 'INFO'
9
- const request = createMockRequest()
10
- const data: LogData = { status: 200, message: 'Test message' }
11
- const store: StoreData = { beforeTime: BigInt(0) }
12
-
13
- const mockTransport = {
14
- log: mock(() => Promise.resolve())
15
- }
16
-
17
- const options: Options = {
18
- config: {
19
- transports: [mockTransport]
20
- }
21
- }
22
-
23
- await logToTransports(level, request, data, store, options)
24
- expect(mockTransport.log).toHaveBeenCalled()
25
-
26
- // Test with no transports
27
- await logToTransports(level, request, data, store, {})
28
- expect(mockTransport.log).toHaveBeenCalledTimes(1) // Should not be called again
29
- })
@@ -1,46 +0,0 @@
1
- import { expect, test } from 'bun:test'
2
- import { Elysia } from 'elysia'
3
-
4
- import logixlysia from '../../src/index'
5
-
6
- test('handles numeric status codes', async () => {
7
- const app = new Elysia().use(logixlysia()).get('/rate-limited', ({ set }) => {
8
- set.status = 429
9
- return 'Rate Limited'
10
- })
11
-
12
- const res = await app.handle(new Request('http://localhost/rate-limited'))
13
- expect(res.status).toBe(429)
14
- })
15
-
16
- test('handles string status codes', async () => {
17
- const app = new Elysia().use(logixlysia()).get('/not-found', ({ set }) => {
18
- set.status = 'Not Found'
19
- return 'Resource not found'
20
- })
21
-
22
- const res = await app.handle(new Request('http://localhost/not-found'))
23
- expect(res.status).toBe(404)
24
- })
25
-
26
- test('handles custom error status', async () => {
27
- const app = new Elysia().use(logixlysia()).get('/error', ({ set }) => {
28
- set.status = 418
29
- const error = new Error('Custom error')
30
- throw error
31
- })
32
-
33
- const res = await app.handle(new Request('http://localhost/error'))
34
- expect(res.status).toBe(418)
35
- })
36
-
37
- test('handles custom error status with message', async () => {
38
- const app = new Elysia().use(logixlysia()).get('/error', ({ set }) => {
39
- set.status = "I'm a teapot"
40
- const error = new Error('Custom error')
41
- throw error
42
- })
43
-
44
- const res = await app.handle(new Request('http://localhost/error'))
45
- expect(res.status).toBe(418)
46
- })
@@ -1,35 +0,0 @@
1
- import { expect, test } from 'bun:test'
2
-
3
- import { formatTimestamp } from '../../src/utils/timestamp'
4
-
5
- test('formatTimestamp with different configurations', () => {
6
- const testDate = new Date('2024-01-15T14:30:45.123Z')
7
-
8
- // Test default format
9
- expect(formatTimestamp(testDate)).toBe(testDate.toISOString())
10
-
11
- // Test system time format
12
- expect(formatTimestamp(testDate, { translateTime: true })).toMatch(
13
- /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}$/
14
- )
15
-
16
- // Test custom format
17
- expect(
18
- formatTimestamp(testDate, {
19
- translateTime: 'yyyy-mm-dd HH:MM:ss.SSS'
20
- })
21
- ).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}$/)
22
-
23
- // Test different custom formats
24
- expect(
25
- formatTimestamp(testDate, {
26
- translateTime: 'HH:MM:ss'
27
- })
28
- ).toMatch(/^\d{2}:\d{2}:\d{2}$/)
29
-
30
- expect(
31
- formatTimestamp(testDate, {
32
- translateTime: 'yyyy/mm/dd'
33
- })
34
- ).toMatch(/^\d{4}\/\d{2}\/\d{2}$/)
35
- })
File without changes
File without changes