@codeleap/logger 5.0.10 → 5.0.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeleap/logger",
3
- "version": "5.0.10",
3
+ "version": "5.0.12",
4
4
  "main": "src/index.ts",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -9,9 +9,9 @@
9
9
  "directory": "packages/logger"
10
10
  },
11
11
  "devDependencies": {
12
- "@codeleap/types": "5.0.10",
13
- "@codeleap/utils": "5.0.10",
14
- "@codeleap/config": "5.0.10",
12
+ "@codeleap/types": "5.0.12",
13
+ "@codeleap/utils": "5.0.12",
14
+ "@codeleap/config": "5.0.12",
15
15
  "ts-node-dev": "1.1.8",
16
16
  "@sentry/types": "8.40.0"
17
17
  },
@@ -19,8 +19,8 @@
19
19
  "build": "echo 'No build needed'"
20
20
  },
21
21
  "peerDependencies": {
22
- "@codeleap/types": "5.0.10",
23
- "@codeleap/utils": "5.0.10",
22
+ "@codeleap/types": "5.0.12",
23
+ "@codeleap/utils": "5.0.12",
24
24
  "typescript": "5.5.2",
25
25
  "react": "18.2.0"
26
26
  },
package/package.json.bak CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeleap/logger",
3
- "version": "5.0.10",
3
+ "version": "5.0.12",
4
4
  "main": "src/index.ts",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
package/src/index.ts CHANGED
@@ -1,5 +1,2 @@
1
- export * as LoggerTypes from './types'
2
- export * as LoggerAnalytics from './Analytics'
3
- export * from './Logger'
4
- export * from './silentLogger'
5
- export * from './performance'
1
+ export * from './lib'
2
+ export * from './types'
@@ -0,0 +1,72 @@
1
+ import { LoggerConfig } from '../types'
2
+ import { SentryService } from './Sentry'
3
+ import { SlackService } from './Slack'
4
+ import { PerformanceService } from './performance'
5
+
6
+ export class Logger {
7
+ static initialized = false
8
+
9
+ private config: LoggerConfig
10
+
11
+ slack: SlackService
12
+
13
+ sentry: SentryService
14
+
15
+ perf: PerformanceService
16
+
17
+ private overrideConsoleMethod(args: unknown[], originalConsole: Console['log']) {
18
+ if (!Logger.initialized) return
19
+
20
+ const ignoreLogs = this.config.Logger.ignoreLogs
21
+ const shouldIgnore = typeof args[0] === 'string' && ignoreLogs.some(ignoredWarning => args.join(' ').includes(ignoredWarning))
22
+
23
+ if (shouldIgnore) return
24
+
25
+ return originalConsole.apply(console, args)
26
+ }
27
+
28
+ constructor() {
29
+ const consoles = ['log', 'warn', 'error']
30
+
31
+ consoles.forEach(level => {
32
+ const consoleRef = console[level]
33
+ console[level] = (...args: unknown[]) => this.overrideConsoleMethod(args, consoleRef)
34
+ })
35
+ }
36
+
37
+ initialize<T extends LoggerConfig>(config: T) {
38
+ if (Logger.initialized) return
39
+
40
+ this.config = config
41
+
42
+ this.sentry = new SentryService(config)
43
+
44
+ this.slack = new SlackService(config)
45
+
46
+ this.perf = new PerformanceService(config)
47
+
48
+ Logger.initialized = true
49
+ }
50
+
51
+ info(...args: unknown[]) {
52
+ throw new Error('Logger: implement the method "info"')
53
+ }
54
+
55
+ error(...args: unknown[]) {
56
+ throw new Error('Logger: implement the method "error"')
57
+ }
58
+
59
+ warn(...args: unknown[]) {
60
+ throw new Error('Logger: implement the method "warn"')
61
+ }
62
+
63
+ log(...args: unknown[]) {
64
+ throw new Error('Logger: implement the method "log"')
65
+ }
66
+
67
+ debug(...args: unknown[]) {
68
+ throw new Error('Logger: implement the method "debug"')
69
+ }
70
+ }
71
+
72
+ export const logger = new Logger()
@@ -0,0 +1,62 @@
1
+ import type { Breadcrumb, ClientOptions, SeverityLevel, Client } from '@sentry/types'
2
+ import { LoggerConfig } from '../types'
3
+
4
+ const SentrySeverityMap: Record<string, SeverityLevel> = {
5
+ debug: 'debug',
6
+ error: 'error',
7
+ info: 'info',
8
+ log: 'log',
9
+ warn: 'warning',
10
+ silent: 'log',
11
+ }
12
+
13
+ type SentryProvider = {
14
+ addBreadcrumb: (args: Breadcrumb) => void
15
+ init(options: ClientOptions): Client
16
+ captureException(err: any): void
17
+ }
18
+
19
+ export class SentryService {
20
+ get provider(): SentryProvider {
21
+ return this.config.Sentry.provider
22
+ }
23
+
24
+ private get enabled() {
25
+ return this.config.Sentry.enabled
26
+ }
27
+
28
+ constructor(private config: LoggerConfig) {
29
+ if (config.Sentry.enabled) {
30
+ const initOptions: ClientOptions = {
31
+ dsn: config.Sentry.dsn,
32
+ debug: config.Sentry.debug,
33
+ beforeBreadcrumb: config.Sentry.beforeBreadcrumb,
34
+ integrations: [],
35
+ enabled: this.enabled,
36
+ ...config.Sentry.initArgs,
37
+ }
38
+
39
+ this.provider?.init?.(initOptions)
40
+ }
41
+ }
42
+
43
+ captureBreadcrumb(type: string, msg: string, data: any, category = `logger:${type}`) {
44
+ if (!this.enabled) return
45
+
46
+ const sentryArgs: Breadcrumb = {
47
+ message: msg,
48
+ data,
49
+ category,
50
+ level: SentrySeverityMap[type],
51
+ type: '',
52
+ }
53
+
54
+ this.provider.addBreadcrumb(sentryArgs)
55
+ }
56
+
57
+ captureException(err: any) {
58
+ if (!this.enabled) return
59
+
60
+ this.provider.captureException(err)
61
+ }
62
+ }
@@ -1,7 +1,6 @@
1
1
  import { inspect } from 'util'
2
- import { TypeGuards, AppSettings } from '@codeleap/types'
3
-
4
- type EchoSlackConfig = AppSettings['Slack']['echo']
2
+ import { TypeGuards } from '@codeleap/types'
3
+ import { LoggerConfig } from '../types'
5
4
 
6
5
  type EchoSlack = {
7
6
  label: string
@@ -20,21 +19,26 @@ type EchoSlackOptions = {
20
19
  }
21
20
 
22
21
  const DEFAULT_CHANNEL = '#_dev_logs'
22
+
23
23
  const DEFAULT_BASE_URL = 'https://slack.com/api/chat.postMessage'
24
24
 
25
25
  export class SlackService {
26
- private echoConfig: EchoSlackConfig
26
+ private echoConfig: LoggerConfig['Slack']['echo']
27
27
 
28
- private isDev: boolean
28
+ private isDev: LoggerConfig['Environment']['IsDev']
29
29
 
30
- private appName: string
30
+ private appName: LoggerConfig['AppName']
31
31
 
32
- public api
32
+ private api
33
33
 
34
- constructor(settings: AppSettings) {
35
- this.echoConfig = settings?.Slack?.echo as EchoSlackConfig
36
- this.isDev = settings?.Environment?.IsDev
37
- this.appName = settings?.AppName
34
+ constructor(private config: LoggerConfig) {
35
+ this.echoConfig = config.Slack.echo
36
+ this.isDev = config.Environment.IsDev
37
+ this.appName = config.AppName
38
+ }
39
+
40
+ setApi(fetcher: any) {
41
+ this.api = fetcher
38
42
  }
39
43
 
40
44
  async echo(
@@ -55,7 +59,7 @@ export class SlackService {
55
59
  try {
56
60
  const data = {
57
61
  'channel': this?.echoConfig?.channel ?? DEFAULT_CHANNEL,
58
- text: slack,
62
+ 'text': slack,
59
63
  'username': `${this.appName} Log`,
60
64
  'icon_url': this?.echoConfig?.icon,
61
65
  ...settingsData,
@@ -135,4 +139,4 @@ export class SlackService {
135
139
 
136
140
  return slack
137
141
  }
138
- }
142
+ }
@@ -0,0 +1 @@
1
+ export * from './Logger'
@@ -1,4 +1,4 @@
1
- import { InspectRenderOptions } from '.'
1
+ import { InspectRenderOptions } from './types'
2
2
 
3
3
  type ErrorArgs = InspectRenderOptions & {
4
4
  name: string
@@ -23,4 +23,4 @@ export class PerformanceError extends Error {
23
23
  super(defineError(errorName, args))
24
24
  this.name = 'Codeleap:Perf'
25
25
  }
26
- }
26
+ }
@@ -0,0 +1,79 @@
1
+ import { throttle } from '@codeleap/utils'
2
+ import { useEffect } from 'react'
3
+ import { PerformanceError } from './errors'
4
+ import { InspectRenderOptions } from './types'
5
+ import { LoggerConfig } from '../../types'
6
+
7
+ export * from './types'
8
+
9
+ export class PerformanceService {
10
+ renderCounter: Record<string, number> = {}
11
+
12
+ constructor(private config: LoggerConfig) { }
13
+
14
+ /**
15
+ * inspectRender monitors how much time a component render per second.
16
+ * Use logger.perf.inspectRender('ComponentName') inside a component to monitor it.
17
+ * @param {string} name - Component name
18
+ * @param {PerformanceInspector} options - Some options for the inspector
19
+ * @returns
20
+ */
21
+ inspectRender = (
22
+ name: string,
23
+ options: InspectRenderOptions = {
24
+ noHooks: false,
25
+ logMode: 'summarized',
26
+ throttleInterval: 1000,
27
+ },
28
+ ) => {
29
+ const config = this.config.Logger.performanceInspector
30
+
31
+ const blacklist = config.blacklist || []
32
+
33
+ if (blacklist.some((item) => name.startsWith(item))) return
34
+
35
+ const { noHooks, logMode, throttleInterval, maxRenders = config.maxRenders } = options
36
+
37
+ if (!config.enabled || !this.config.Environment.IsDev) {
38
+ return
39
+ }
40
+
41
+ if (!noHooks) {
42
+ useEffect(() => {
43
+ console.log(`[PerformanceInspector] Mounted -> ${name}`)
44
+
45
+ return () => {
46
+ console.log(`[PerformanceInspector] Unmounted -> ${name}`)
47
+ }
48
+ })
49
+ }
50
+
51
+ this.renderCounter[name] = this.renderCounter[name] ? this.renderCounter[name] + 1 : 1
52
+
53
+ const renders = this.renderCounter[name]
54
+
55
+ if (renders > maxRenders) {
56
+ this.renderCounter[name] = 0
57
+
58
+ throw new PerformanceError('maxRenders', {
59
+ name,
60
+ throttleInterval,
61
+ maxRenders,
62
+ })
63
+ }
64
+
65
+ if (logMode === 'raw') {
66
+ console.log(`[PerformanceInspector] Rendered -> ${name}: ${renders}`)
67
+ return
68
+ }
69
+
70
+ function logSummary() {
71
+ if (renders <= 0) return
72
+
73
+ console.log(`[PerformanceInspector] Render summary -> ${name}: ${renders}`)
74
+ this.renderCounter[name] = 0
75
+ }
76
+
77
+ throttle(logSummary, name, throttleInterval)
78
+ }
79
+ }
@@ -0,0 +1,6 @@
1
+ export type InspectRenderOptions = {
2
+ noHooks?: boolean
3
+ logMode?: 'raw' | 'summarized'
4
+ throttleInterval?: number
5
+ maxRenders?: number
6
+ }
package/src/types.ts CHANGED
@@ -1,45 +1,38 @@
1
- import { FunctionType } from '@codeleap/types'
2
- import { colors, foregroundColors } from './constants'
3
1
 
4
- import type { SeverityLevel, Client, ClientOptions, Breadcrumb } from '@sentry/types'
2
+ export type LoggerConfig = {
3
+ AppName: string
4
+
5
+ Environment: {
6
+ IsDev: boolean
7
+ }
8
+
9
+ Slack: {
10
+ echo: {
11
+ channel?: string
12
+ icon: string
13
+ token: string
14
+ baseURL?: string
15
+ enabled?: boolean
16
+ options?: Record<string, any>
17
+ }
18
+ }
5
19
 
6
- export type LogType = 'info' | 'debug' | 'warn' | 'error' | 'log' | 'silent'
20
+ Logger: {
21
+ ignoreLogs: string[]
7
22
 
8
- export type LogFunctionArgs = [
9
- description?: any,
10
- value?:any,
11
- category?:string
12
- ]
13
- export type ConsoleColor = keyof typeof colors
14
- export type DebugColors = {
15
- [Property in keyof typeof foregroundColors as `${Lowercase<
16
- string & Property
17
- >}`]: (...args: LogFunctionArgs) => void;
18
- }
19
- export type DebugColor = keyof DebugColors
20
- export type LogToTerminalArgs = {
21
- logType: LogType
22
- args: LogFunctionArgs
23
- color?: keyof DebugColors
24
- deviceIdentifier?: string
25
- stringify?: boolean
26
- logKeys?: boolean
27
- }
28
- export type LogToTerminal = FunctionType<[LogToTerminalArgs], void>
23
+ performanceInspector: {
24
+ enabled: boolean
25
+ maxRenders: number
26
+ blacklist: string[]
27
+ }
28
+ }
29
29
 
30
- export const SentrySeverityMap: Record<LogType, SeverityLevel> = {
31
- debug: 'debug',
32
- error: 'error',
33
- info: 'info',
34
- log: 'log',
35
- warn: 'warning',
36
- silent: 'log',
37
- }
38
-
39
- export type SentryProvider = {
40
- addBreadcrumb: FunctionType<[Breadcrumb], void>
41
- init(options: ClientOptions): Client
42
- captureException(err: any): void
43
- }
44
-
45
- export type LoggerMiddleware = FunctionType<[arguments: LogToTerminalArgs, formattedContent: string[]], any>
30
+ Sentry: {
31
+ enabled: boolean
32
+ dsn: string
33
+ provider: any
34
+ debug?: boolean
35
+ initArgs?: any
36
+ beforeBreadcrumb?: any
37
+ }
38
+ }
package/src/Analytics.ts DELETED
@@ -1,67 +0,0 @@
1
- import { obfuscate } from './obfuscate'
2
- import { FunctionType, AnyFunction, AppSettings } from '@codeleap/types'
3
-
4
- export type AnalyticsObject = {
5
- name: string
6
- type: 'interaction' | 'event'
7
- data: any
8
- }
9
-
10
- type IAnalyticsArgs = {
11
- init(): any
12
- prepareData: () => any
13
- error?: (err: any) => any
14
- } & Record<`on${Capitalize<AnalyticsObject['type']>}`, FunctionType<[AnalyticsObject], void>>
15
-
16
- export class Analytics {
17
-
18
- constructor(private callers: IAnalyticsArgs, private settings: AppSettings) {
19
- this.callers.init()
20
-
21
- }
22
-
23
- private prepare() {
24
- const data = this.callers.prepareData()
25
-
26
- return data
27
- }
28
-
29
- obfuscate(data) {
30
- return obfuscate({
31
- object: data,
32
- keys: this?.settings?.Logger?.Obfuscate?.keys || [],
33
- values: this?.settings?.Logger?.Obfuscate?.values || [],
34
- })
35
- }
36
-
37
- event(name: string, data = {}) {
38
- this.handle(name, data, 'event', this.callers.onEvent)
39
- }
40
-
41
- interaction(name: string, data = {}) {
42
- this.handle(name, data, 'interaction', this.callers.onInteraction)
43
-
44
- }
45
-
46
- onError(cb) {
47
- this.callers.error = cb
48
- }
49
-
50
- private handle(name: string, data: any, type: AnalyticsObject['type'], fn: AnyFunction) {
51
- try {
52
-
53
- const obfuscated = this.obfuscate({
54
- ...data,
55
- ...this.prepare(),
56
- })
57
-
58
- fn({
59
- name,
60
- type,
61
- data: obfuscated,
62
- })
63
- } catch (e) {
64
- this.callers.error(e)
65
- }
66
- }
67
- }
package/src/Logger.ts DELETED
@@ -1,223 +0,0 @@
1
- import { inspect } from 'util'
2
- import { TypeGuards, LogType, AppSettings } from '@codeleap/types'
3
- import { Analytics } from './Analytics'
4
- import { SentryService } from './Sentry'
5
- import { SlackService } from './Slack'
6
- import { LogToTerminal, LogFunctionArgs, LogToTerminalArgs, LoggerMiddleware } from './types'
7
-
8
- const logLevels: LogType[] = ['debug', 'info', 'log', 'warn', 'error']
9
-
10
- const emptyFunction = () => { }
11
-
12
- const hollowAnalytics = new Analytics({
13
- init: emptyFunction,
14
- onEvent: emptyFunction,
15
- onInteraction: emptyFunction,
16
- prepareData: () => ({}),
17
- }, {})
18
-
19
- export class Logger {
20
- static settings: AppSettings
21
-
22
- settings: AppSettings
23
-
24
- sentry: SentryService
25
-
26
- slack: SlackService
27
-
28
- middleware: LoggerMiddleware[] = []
29
-
30
- constructor(settings: AppSettings, middleware?: LoggerMiddleware[], public analytics?: Analytics) {
31
- this.settings = settings
32
- this.middleware = middleware || []
33
- if (settings.Logger.isMain) {
34
- Logger.settings = settings
35
- }
36
-
37
- if (settings?.Logger?.IgnoreWarnings?.length) {
38
- const newConsole = (args, oldConsole) => {
39
- const shouldIgnore = typeof args[0] === 'string' &&
40
- settings.Logger.IgnoreWarnings.some(ignoredWarning => args.join(' ').includes(ignoredWarning))
41
- if (shouldIgnore) return
42
- else return oldConsole.apply(console, args)
43
- }
44
- const consoles = ['log', 'warn', 'error']
45
-
46
- consoles.forEach(t => {
47
- const tmp = console[t]
48
- console[t] = (...args) => newConsole(args, tmp)
49
- })
50
- }
51
-
52
- this.sentry = new SentryService(settings)
53
-
54
- this.slack = new SlackService(settings)
55
-
56
- if (!analytics) {
57
- this.analytics = hollowAnalytics
58
- }
59
-
60
- this.analytics.onError((err) => {
61
- this.logToTerminal({
62
- logType: 'error',
63
- args: ['Error on analytics event', err, 'Internal'],
64
- })
65
- })
66
-
67
- }
68
-
69
- static formatContent(logArgs: LogToTerminalArgs) {
70
- const { logType, args: content, deviceIdentifier: deviceId, stringify, logKeys = true } = logArgs
71
-
72
- const [descriptionOrValue, value, category] = content
73
-
74
- const nArgs = content.length
75
- let logContent = content
76
-
77
- const logValue = nArgs === 1 ? descriptionOrValue : value
78
-
79
- const shouldStringify = stringify && !!logValue && TypeGuards.isObject(logValue) && !(logValue instanceof Error)
80
- const inspectOptions = Logger?.settings?.Logger?.inspect || {}
81
-
82
- const displayValue = shouldStringify ? inspect(logValue, {
83
- depth: 5,
84
- showHidden: true,
85
- ...inspectOptions,
86
- }) : logValue
87
-
88
- if (nArgs === 3) {
89
- logContent = [
90
- `(${category}) ${descriptionOrValue}${displayValue ? ' ->' : ''}`,
91
- displayValue,
92
- ]
93
- }
94
-
95
- if (nArgs === 2) {
96
- logContent = [
97
- `${descriptionOrValue}${displayValue ? ' ->' : ''}`,
98
- displayValue,
99
- ]
100
- }
101
-
102
- if (nArgs === 1) {
103
- const isObj = typeof descriptionOrValue === 'object' && !(descriptionOrValue instanceof Error)
104
- const keys = isObj ? Object.keys(descriptionOrValue) : null
105
- const title = isObj && keys.length && logKeys ?
106
- `${keys.filter(i => !!i).slice(0, 3).join(', ')}${keys.length > 3 ? '...' : ''} ->`
107
- : null
108
-
109
- if (title) {
110
- logContent = [
111
- title,
112
- displayValue,
113
- ]
114
- } else {
115
- logContent = [
116
- displayValue,
117
- ]
118
- }
119
- }
120
-
121
- return logContent
122
- }
123
-
124
- static coloredLog: LogToTerminal = (logArgs) => {
125
- const { logType, args: content, deviceIdentifier: deviceId, stringify } = logArgs
126
-
127
- const logContent = Logger.formatContent(logArgs)
128
-
129
- const displayLog = logType === 'error' ? 'warn' : logType
130
-
131
- console[displayLog](deviceId, ...logContent)
132
-
133
- return logContent
134
- }
135
-
136
- private logToTerminal: LogToTerminal = (logArgs) => {
137
- const { logType, args, color } = logArgs
138
-
139
- if (this.settings.Logger.Level === 'silent') return
140
-
141
- const shouldLog = TypeGuards.isString(this.settings.Logger.Level) ?
142
- logLevels.indexOf(logType) >=
143
- logLevels.indexOf(this.settings.Logger.Level) : this.settings.Logger.Level.includes(logType)
144
- if (!shouldLog) return
145
-
146
- const content = Logger.formatContent(logArgs)
147
-
148
- if (this.settings.Environment.IsDev) {
149
-
150
- const deviceId = this.settings.Logger?.DeviceIdentifier ?
151
- `[${this.settings.Logger.DeviceIdentifier}]` : ''
152
-
153
- const stringify = this.settings.Logger?.StringifyObjects
154
-
155
- this.middleware.forEach(m => m(logArgs, content))
156
-
157
- Logger.coloredLog(
158
- {
159
- logType: logType as LogType,
160
- args,
161
- color,
162
- deviceIdentifier: deviceId,
163
- stringify,
164
- },
165
- )
166
-
167
- }
168
-
169
- if (!this.settings.Environment.IsDev || this.settings.Logger.alwaysSendToSentry) {
170
- try {
171
-
172
- this.middleware.forEach(m => m(logArgs, content))
173
- if (['info', 'log'].includes(logType)) {
174
-
175
- this.sentry.captureBreadcrumb(
176
- logType,
177
- content,
178
- )
179
- }
180
- if (['error'].includes(logType)) {
181
- this.sentry.sendLog(args?.[1] || args?.[0])
182
- }
183
- } catch (e) {
184
- // Nothing
185
- }
186
- }
187
- }
188
-
189
- info(...args: LogFunctionArgs) {
190
- this.logToTerminal({
191
- args,
192
- logType: 'info',
193
- })
194
- }
195
-
196
- error(...args: LogFunctionArgs) {
197
- this.logToTerminal({
198
- args,
199
- logType: 'error',
200
- })
201
- }
202
-
203
- warn(...args: LogFunctionArgs) {
204
- this.logToTerminal({
205
- args,
206
- logType: 'warn',
207
- })
208
- }
209
-
210
- log(...args: LogFunctionArgs) {
211
- this.logToTerminal({
212
- args,
213
- logType: 'log',
214
- })
215
- }
216
-
217
- debug(...args: LogFunctionArgs) {
218
- this.logToTerminal({
219
- args,
220
- logType: 'debug',
221
- })
222
- }
223
- }
package/src/Sentry.ts DELETED
@@ -1,54 +0,0 @@
1
- import type { Breadcrumb, ClientOptions } from '@sentry/types'
2
- import { AppSettings } from '@codeleap/types'
3
- import {
4
- LogFunctionArgs,
5
- LogType,
6
- SentrySeverityMap,
7
- SentryProvider,
8
- } from './types'
9
-
10
- export class SentryService {
11
- private sentry: SentryProvider
12
-
13
- private use: boolean
14
-
15
- constructor(settings: AppSettings) {
16
- this.use = settings?.Sentry?.enable
17
- this.sentry = settings?.Sentry?.provider as SentryProvider
18
- if (this.use) {
19
- const isDebug = settings?.Sentry?.debug || false
20
- if (isDebug) console.log('> > > Initializing Sentry', settings.Sentry)
21
- const initObj:ClientOptions = {
22
- dsn: settings.Sentry.dsn,
23
- debug: isDebug,
24
- integrations: [],
25
- ...settings?.Sentry?.initArgs,
26
- }
27
- if (settings?.Sentry?.beforeBreadcrumb) {
28
- initObj.beforeBreadcrumb = settings?.Sentry?.beforeBreadcrumb
29
- }
30
- this.sentry?.init?.(initObj)
31
- }
32
- }
33
-
34
- captureBreadcrumb(type: LogType, content: LogFunctionArgs) {
35
- if (!this.use) return
36
-
37
- const [message, data, category] = content
38
-
39
- const sentryArgs: Breadcrumb = {
40
- message,
41
- data,
42
- category,
43
- level: SentrySeverityMap[type],
44
- type: '',
45
- }
46
-
47
- this.sentry.addBreadcrumb(sentryArgs)
48
- }
49
-
50
- sendLog(err?: any) {
51
- if (!this.use) return
52
- this.sentry.captureException(err)
53
- }
54
- }
package/src/constants.ts DELETED
@@ -1,37 +0,0 @@
1
- import { ConsoleColor } from './types'
2
- import { LogType } from '@codeleap/types'
3
-
4
- export const foregroundColors = {
5
- Black: '\x1b[30m',
6
- Red: '\x1b[31m',
7
- Green: '\x1b[32m',
8
- Yellow: '\x1b[33m',
9
- Blue: '\x1b[34m',
10
- Magenta: '\x1b[35m',
11
- Cyan: '\x1b[36m',
12
- White: '\x1b[37m',
13
- } as const
14
-
15
- export const formatColors = {
16
- Reset: '\x1b[0m',
17
- Bright: '\x1b[1m',
18
- Dim: '\x1b[2m',
19
- Underscore: '\x1b[4m',
20
- Blink: '\x1b[5m',
21
- Reverse: '\x1b[7m',
22
- Hidden: '\x1b[8m',
23
- } as const
24
-
25
- export const colors = {
26
- ...foregroundColors,
27
- ...formatColors,
28
- }
29
-
30
- export const logColors: Record<LogType, ConsoleColor> = {
31
- error: 'Red',
32
- info: 'White',
33
- warn: 'Yellow',
34
- debug: 'Magenta',
35
- log: 'White',
36
- silent: 'Green',
37
- }
package/src/obfuscate.ts DELETED
@@ -1,76 +0,0 @@
1
- import { cloneDeep } from '@codeleap/utils'
2
- import { Matcher } from '@codeleap/types'
3
- import { inspect } from 'util'
4
- import parse from 'url-parse'
5
-
6
- type ObfuscateArgs = {
7
- object: any
8
- keys: (Matcher<'key'>)[]
9
- values: (Matcher<'value'>)[]
10
- }
11
-
12
- function removeKey(obj, key) {
13
- if (obj?.hasOwnProperty(key)) {
14
- obj[key] = '[secret]'
15
- }
16
- for (const subObj in obj) {
17
- if (typeof obj[subObj] == 'object') {
18
- removeKey(obj[subObj], key)
19
- }
20
- }
21
- }
22
-
23
- function removeValue(obj, value) {
24
- for (const subObj in obj) {
25
- const isString = typeof obj[subObj] == 'string'
26
- if (isString) {
27
- const isRegex = value instanceof RegExp
28
- const match = isRegex ? value.test(obj[subObj]) : obj[subObj].includes(value)
29
- if (match) {
30
- if (obj[subObj].startsWith('http')) {
31
- const url = parse(obj[subObj])
32
- obj[subObj] = `${url.origin}${url.pathname}/[secret]`
33
- } else {
34
- obj[subObj] = '[secret]'
35
- }
36
- }
37
- }
38
- if (typeof obj[subObj] == 'object') {
39
- removeValue(obj[subObj], value)
40
- }
41
- }
42
- }
43
-
44
- export function obfuscate(args: ObfuscateArgs) {
45
- const { object, keys, values } = args
46
-
47
- let isCircular = false
48
- try {
49
- JSON.stringify(args)
50
- } catch (e) {
51
- isCircular = true
52
- }
53
-
54
- if (typeof object === 'object' && !isCircular) {
55
- let cleanData = {}
56
- try {
57
- cleanData = cloneDeep(object)
58
- keys.forEach(fieldName => removeKey(cleanData, fieldName))
59
- values.forEach(fieldName => removeValue(cleanData, fieldName))
60
- } catch (err1) {
61
- try {
62
- cleanData = inspect(object, { depth: 1 })
63
- } catch (err2) {
64
- cleanData = { value: `Couldn't process data` }
65
- }
66
- }
67
- const result = cleanData
68
- return result
69
- } else {
70
- if (isCircular) {
71
- return { ...args.object, WARNING: 'Circular reference detected' }
72
- } else {
73
- return args.object
74
- }
75
- }
76
- }
@@ -1,86 +0,0 @@
1
- import { throttle } from '@codeleap/utils'
2
- import { useEffect } from 'react'
3
- import { AppSettings } from '@codeleap/types'
4
- import { PerformanceError } from './errors'
5
-
6
- export type InspectRenderOptions = {
7
- noHooks?: boolean
8
- logMode?: 'raw' | 'summarized'
9
- throttleInterval?: number
10
- maxRenders?: number
11
- }
12
-
13
- export type PerformanceInspector = {
14
- inspectRender: (name: string, options?: InspectRenderOptions) => void
15
- }
16
-
17
- const renderCounter: Record<string, number> = {}
18
-
19
- export function makePerformanceInspector(settings: AppSettings) {
20
- /**
21
- * inspectRender monitors how much time a component render per second.
22
- * Use perf.inspectRender('ComponentName') inside a component to monitor it.
23
- * @param {string} name - Component name
24
- * @param {PerformanceInspector} options - Some options for the inspector
25
- * @returns
26
- */
27
- const inspectRender = (
28
- name: string,
29
- options: InspectRenderOptions = {
30
- noHooks: false,
31
- logMode: 'summarized',
32
- throttleInterval: 1000,
33
- maxRenders: settings?.PerformanceInspector.maxRenders,
34
- },
35
- ) => {
36
- const blacklist = settings?.PerformanceInspector.blacklist || []
37
- if (blacklist.some((item) => name.startsWith(item))) return
38
-
39
- const { noHooks, logMode, throttleInterval, maxRenders } = options
40
-
41
- if (
42
- !settings?.PerformanceInspector.enable ||
43
- !settings?.Environment.IsDev
44
- ) {
45
- return
46
- }
47
-
48
- if (!noHooks) {
49
- useEffect(() => {
50
- console.log(`[PerformanceInspector] Mounted -> ${name}`)
51
-
52
- return () => {
53
- console.log(`[PerformanceInspector] Unmounted -> ${name}`)
54
- }
55
- })
56
- }
57
-
58
- renderCounter[name] = renderCounter[name] ? renderCounter[name] + 1 : 1
59
- const renders = renderCounter[name]
60
-
61
- if (renders > maxRenders) {
62
- renderCounter[name] = 0
63
- throw new PerformanceError('maxRenders', {
64
- name,
65
- throttleInterval,
66
- maxRenders,
67
- })
68
- }
69
-
70
- if (logMode === 'raw') {
71
- console.log(`[PerformanceInspector] Rendered -> ${name}: ${renders}`)
72
- return
73
- }
74
-
75
- function logSummary() {
76
- if (renders <= 0) return
77
-
78
- console.log(`[PerformanceInspector] Render summary -> ${name}: ${renders}`)
79
- renderCounter[name] = 0
80
- }
81
-
82
- throttle(logSummary, name, throttleInterval)
83
- }
84
-
85
- return { inspectRender }
86
- }
@@ -1,11 +0,0 @@
1
- import { Logger } from './Logger'
2
-
3
- export const silentLogger = new Logger({
4
- Logger: {
5
- Level: 'silent',
6
- IgnoreWarnings: [
7
- `Require cycle:`,
8
- `Require cycles are allowed`,
9
- ],
10
- },
11
- })