• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taichunmin / chameleon-ultra.js / 16902739519

12 Aug 2025 08:00AM UTC coverage: 68.124% (-1.1%) from 69.192%
16902739519

push

github

web-flow
Add support 9 new cmds (#204)

504 of 658 branches covered (76.6%)

Branch coverage included in aggregate %.

415 of 589 new or added lines in 10 files covered. (70.46%)

9 existing lines in 3 files now uncovered.

2815 of 4214 relevant lines covered (66.8%)

2958829.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.97
/src/plugin/Debug.ts
1
import { type Buffer } from '@taichunmin/buffer'
2
import createDebugger, { type Debugger } from 'debug'
1✔
3
import * as _ from 'lodash-es'
1✔
4
import { setObject } from '../iifeExportHelper'
1✔
5
import { type PluginInstallContext as ChameleonCtx, type UltraPlugin, type DebugFilter } from '../types'
6

7
let Buffer1: typeof Buffer
1✔
8

NEW
9
export default class Debug implements UltraPlugin {
×
10
  debugers = new Map<string, Debugger>()
×
11
  filter?: DebugFilter
×
12
  name = 'debug'
×
13

14
  async install (context: ChameleonCtx): Promise<this> {
×
15
    const { ultra } = context
×
16
    if (_.isNil(Buffer1)) Buffer1 = context.Buffer
×
17
    ultra.emitter.on('error', (err: Error) => {
×
18
      const errJson = errToJson(err)
×
19
      ultra.emitter.emit('debug', 'error', jsonStringify(errJson))
×
20
      console.error(errJson)
×
21
    })
×
22
    ultra.emitter.on('debug', (namespace: string, formatter: any, ...args: [] | any[]) => {
×
23
      if (!(this.filter?.(namespace, formatter, ...args) ?? true)) return
×
24
      const debug = this.debugers.get(namespace) ?? createDebugger(`ultra:${namespace}`)
×
25
      if (!this.debugers.has(namespace)) this.debugers.set(namespace, debug)
×
26
      debug(formatter, ...args)
×
27
    })
×
28
    return this
×
29
  }
×
30
}
×
31

32
setObject(globalThis, ['ChameleonUltraJS', 'Debug'], Debug)
1✔
33

34
const ERROR_KEYS = [
1✔
35
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Error
36
  'columnNumber',
1✔
37
  'filename',
1✔
38
  'lineNumber',
1✔
39
  'message',
1✔
40
  'name',
1✔
41
  'stack',
1✔
42

43
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError
44
  'errors',
1✔
45

46
  // https://nodejs.org/api/errors.html
47
  'address',
1✔
48
  'code',
1✔
49
  'dest',
1✔
50
  'errno',
1✔
51
  'function',
1✔
52
  'info',
1✔
53
  'library',
1✔
54
  'opensslErrorStack',
1✔
55
  'path',
1✔
56
  'port',
1✔
57
  'reason',
1✔
58
  'syscall',
1✔
59

60
  // axios: https://github.com/axios/axios/blob/v1.x/lib/core/AxiosError.js
61
  'config',
1✔
62
  'description',
1✔
63
  'fileName',
1✔
64
  'number',
1✔
65
  'request',
1✔
66
  'response.data',
1✔
67
  'response.headers',
1✔
68
  'response.status',
1✔
69
  'status',
1✔
70

71
  // http-errors: https://github.com/jshttp/http-errors/blob/master/index.js
72
  'statusCode',
1✔
73
  'statusMessage',
1✔
74

75
  // GraphQLError: https://www.graphql-js.org/api-v16/error/
76
  'args',
1✔
77
  'originalError',
1✔
78
  'positions',
1✔
79
  'source',
1✔
80
  'locations',
1✔
81
  'line',
1✔
82
  'column',
1✔
83

84
  // custom
85
  'data',
1✔
86
] as const
1✔
87

88
/**
89
 * @group Internal
90
 * @internal
91
 */
92
export function errToJson<T extends Error & { cause?: any, stack?: any }> (err: T): Partial<T> {
1✔
93
  const tmp: any = {
3✔
94
    ..._.pick(err, ERROR_KEYS),
3✔
95
    ...(_.isNil(err.cause) ? {} : { cause: errToJson(err.cause) }),
3✔
96
  }
3✔
97
  return tmp
3✔
98
}
3✔
99

100
/**
101
 * @group Internal
102
 * @internal
103
 */
104
export function stringifyClone (obj: any): any {
1✔
105
  const preventCircular = new Set()
1✔
106
  return _.cloneDeepWith(obj, val1 => {
1✔
107
    if (_.isObject(val1) && !_.isEmpty(val1)) {
15✔
108
      if (preventCircular.has(val1)) return '[Circular]'
6✔
109
      preventCircular.add(val1)
5✔
110
    }
5✔
111
    if (Buffer1?.isBuffer(val1)) return { type: 'Buffer', hex: val1.toString('hex') }
15✔
112
    if (typeof val1 === 'bigint') return val1.toString()
15✔
113
    if (val1 instanceof Error) return errToJson(val1)
15✔
114
    if (val1 instanceof Map) return _.fromPairs([...val1.entries()])
15✔
115
    if (val1 instanceof Set) return [...val1.values()]
15✔
116
    if (val1 instanceof Date) return val1.toISOString()
15✔
117
  })
1✔
118
}
1✔
119

120
/**
121
 * @group Internal
122
 * @internal
123
 */
124
export function stringifyReplacer (this: any, key: any, val: any): any {
1✔
125
  if (key.length > 1 && key[0] === '_') return undefined
20✔
126
  const censored = this?._censored ?? []
20✔
127
  for (const key1 of censored) {
20✔
128
    if (!_.hasIn(this, key1)) continue
2✔
129
    _.set(this, key1, '[Censored]')
1✔
130
  }
1✔
131
  delete this?._censored
19✔
132
  return this[key]
20✔
133
}
20✔
134

135
/**
136
 * @group Internal
137
 * @internal
138
 */
139
export function jsonStringify (obj: object, space?: number): string {
1✔
140
  return JSON.stringify(stringifyClone(obj), stringifyReplacer, space)
1✔
141
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc