@stacksjs/logging 0.64.5 → 0.65.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/src/index.ts CHANGED
@@ -1,16 +1,13 @@
1
- import { access, appendFile, mkdir } from 'node:fs/promises'
2
- import { dirname } from 'node:path'
1
+ /* eslint no-console: 0 */
3
2
  import process from 'node:process'
4
- import { buddyOptions } from '@stacksjs/cli'
5
- import { config } from '@stacksjs/config'
6
- import { handleError } from '@stacksjs/error-handling'
3
+ import { buddyOptions, stripAnsi } from '@stacksjs/cli'
4
+ import { handleError, writeToLogFile } from '@stacksjs/error-handling'
7
5
  import { ExitCode } from '@stacksjs/types'
8
- import { isString } from '@stacksjs/validation'
9
6
  import { consola, createConsola } from 'consola'
10
7
 
11
8
  // import type { Prompt } from '@stacksjs/cli'
12
9
 
13
- export async function logLevel() {
10
+ export function logLevel(): number {
14
11
  /**
15
12
  * This regex checks for:
16
13
  * - --verbose true or --verbose=true exactly at the end of the string ($ denotes the end of the string).
@@ -19,132 +16,130 @@ export async function logLevel() {
19
16
  *
20
17
  * .trim() is used on options to ensure any trailing spaces in the entire options string do not affect the regex match.
21
18
  */
22
- const verboseRegex = /--verbose(?!(\s*=\s*false|\s+false))(\s+|=true)?($|\s)/
19
+ const verboseRegex = /--verbose(?!\s*=\s*false|\s+false)(?:\s+|=true)?(?:$|\s)/
23
20
  const opts = buddyOptions()
24
21
 
25
- if (verboseRegex.test(opts)) return 4
22
+ if (verboseRegex.test(opts))
23
+ return 4
26
24
 
27
25
  // const config = await import('@stacksjs/config')
28
26
  // console.log('config', config)
29
27
 
30
- return 3
31
28
  // return config.logger.level
29
+ return 3
32
30
  }
33
31
 
34
- export const logger = createConsola({
35
- level: await logLevel(),
36
- // fancy: true,
37
- // formatOptions: {
38
- // columns: 80,
39
- // colors: false,
40
- // compact: false,
41
- // date: false,
42
- // },
43
- })
44
-
45
- export { consola }
46
-
47
- export async function writeToLogFile(message: string) {
48
- const formattedMessage = `[${new Date().toISOString()}] ${message}\n`
49
-
50
- try {
51
- const logFile = config.logging.logsPath ?? 'storage/logs/stacks.log'
52
-
53
- try {
54
- // Check if the file exists
55
- await access(logFile)
56
- } catch {
57
- // File doesn't exist, create the directory
58
- console.log('Creating log file directory...', logFile)
59
- await mkdir(dirname(logFile), { recursive: true })
60
- }
61
-
62
- // Append the message to the log file
63
- await appendFile(logFile, formattedMessage)
64
- } catch (error) {
65
- console.error('Failed to write to log file:', error)
66
- }
32
+ export const logger: Log = {
33
+ ...createConsola({
34
+ level: logLevel(),
35
+ // fancy: true,
36
+ }),
37
+ warning: (message: string) => console.warn(message),
38
+ dump: (...args: any[]) => console.log(...args),
39
+ dd: (...args: any[]) => {
40
+ console.log(...args)
41
+ process.exit(ExitCode.FatalError)
42
+ },
43
+ echo: (message: string) => console.log(message),
67
44
  }
68
45
 
46
+ export { consola, createConsola }
47
+
48
+ type ErrorMessage = string
49
+ export type ErrorOptions =
50
+ | {
51
+ shouldExit: boolean
52
+ silent?: boolean
53
+ message?: ErrorMessage
54
+ }
55
+ | any
56
+ | Error
57
+
69
58
  export interface Log {
70
59
  info: (...args: any[]) => void
71
60
  success: (msg: string) => void
72
- error: (err: string | Error | unknown, options?: any | Error) => void
61
+ error: (err: string | Error | object | unknown, options?: ErrorOptions) => void
73
62
  warn: (arg: string) => void
74
63
  warning: (arg: string) => void
75
64
  debug: (...args: any[]) => void
76
65
  // prompt: Prompt
77
66
  // start: logger.Start
78
67
  // box: logger.Box
79
- start: any
80
- box: any
68
+ // start: any
69
+ // box: any
81
70
  dump: (...args: any[]) => void
82
71
  dd: (...args: any[]) => void
83
72
  echo: (...args: any[]) => void
84
73
  }
85
74
 
86
- export type LogMessageOptions = {
87
- symbol?: string
75
+ export interface LogOptions {
88
76
  styled?: boolean
89
77
  }
90
78
 
91
79
  export const log: Log = {
92
- info: async (message: string) => {
93
- logger.info(message)
94
- await writeToLogFile(`INFO: ${message}`)
80
+ info: async (message: string, options?: LogOptions) => {
81
+ if (options?.styled === false)
82
+ console.log(message)
83
+ else logger.info(message)
84
+ await writeToLogFile(`INFO: ${stripAnsi(message)}`)
95
85
  },
96
86
 
97
- success: async (message: string) => {
98
- logger.success(message)
99
- await writeToLogFile(`SUCCESS: ${message}`)
87
+ success: async (message: string, options?: LogOptions) => {
88
+ if (options?.styled === false)
89
+ console.log(message)
90
+ else logger.success(message)
91
+ await writeToLogFile(`SUCCESS: ${stripAnsi(message)}`)
100
92
  },
101
93
 
102
- warn: async (message: string) => {
103
- logger.warn(message)
104
- await writeToLogFile(`WARN: ${message}`)
94
+ warn: async (message: string, options?: LogOptions) => {
95
+ if (options?.styled === false)
96
+ console.log(message)
97
+ else logger.warn(message)
98
+ await writeToLogFile(`WARN: ${stripAnsi(message)}`)
105
99
  },
106
100
 
107
101
  /** alias for `log.warn()`. */
108
- warning: (message: string) => {
109
- log.warn(message)
102
+ warning: async (message: string, options?: LogOptions) => {
103
+ if (options?.styled === false)
104
+ console.log(message)
105
+ else logger.warn(message)
106
+ await writeToLogFile(`WARN: ${stripAnsi(message)}`)
110
107
  },
111
108
 
112
- error: (err: unknown, options?: any | Error) => {
113
- if (err instanceof Error) handleError(err, options)
114
- else if (err instanceof Error) handleError(options)
115
- else handleError(err, options)
116
-
117
- const errorMessage = isString(err) ? err : err instanceof Error ? err.message : String(err)
118
- logger.error(errorMessage)
119
- writeToLogFile(`ERROR: ${errorMessage}`)
109
+ error: async (err: string | Error | object | unknown, options?: ErrorOptions) => {
110
+ handleError(err, options)
120
111
  },
121
112
 
122
- debug: (...args: any[]) => {
113
+ debug: async (...args: any[]) => {
114
+ const formattedArgs = args.map(arg => (typeof arg === 'object' ? JSON.stringify(arg, null, 2) : arg))
115
+ const message = `DEBUG: ${formattedArgs.join(' ')}`
116
+
123
117
  if (process.env.APP_ENV === 'production' || process.env.APP_ENV === 'prod')
124
- return writeToLogFile(`DEBUG: ${args.join(' ')}`)
118
+ return writeToLogFile(message)
125
119
 
126
- writeToLogFile(`DEBUG: ${args.join(' ')}`)
120
+ logger.debug(message)
121
+ await writeToLogFile(stripAnsi(message))
127
122
  },
128
123
 
129
- dump: (...args: any[]) => args.forEach((arg) => console.log(arg)),
124
+ dump: (...args: any[]) => args.forEach(arg => console.log(arg)),
130
125
  dd: (...args: any[]) => {
131
- args.forEach((arg) => console.log(arg))
126
+ args.forEach(arg => console.log(arg))
132
127
  process.exit(ExitCode.FatalError)
133
128
  },
134
129
  echo: (...args: any[]) => console.log(...args),
135
130
  }
136
131
 
137
- export function dump(...args: any[]) {
138
- args.forEach((arg) => log.debug(arg))
132
+ export function dump(...args: any[]): void {
133
+ args.forEach(arg => log.debug(arg))
139
134
  }
140
135
 
141
- export function dd(...args: any[]) {
142
- args.forEach((arg) => log.debug(arg))
136
+ export function dd(...args: any[]): void {
137
+ log.info(args)
143
138
  // we need to return a non-zero exit code to indicate an error
144
139
  // e.g. if used in a CDK script, we want it to fail the deployment
145
140
  process.exit(ExitCode.FatalError)
146
141
  }
147
142
 
148
- export function echo(...args: any[]) {
143
+ export function echo(...args: any[]): void {
149
144
  console.log(...args)
150
145
  }