react-hook-eslint 1.0.1
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/CONTRIBUTING.md +30 -0
- package/LICENSE +21 -0
- package/README.md +85 -0
- package/SECURITY.md +68 -0
- package/docs/api.md +1487 -0
- package/docs/asynchronous.md +40 -0
- package/docs/benchmarks.md +55 -0
- package/docs/browser.md +227 -0
- package/docs/bundling.md +40 -0
- package/docs/child-loggers.md +95 -0
- package/docs/ecosystem.md +84 -0
- package/docs/help.md +345 -0
- package/docs/lts.md +64 -0
- package/docs/pretty.md +35 -0
- package/docs/redaction.md +135 -0
- package/docs/transports.md +1238 -0
- package/docs/web.md +269 -0
- package/docsify/sidebar.md +26 -0
- package/favicon-16x16.png +0 -0
- package/favicon-32x32.png +0 -0
- package/favicon.ico +0 -0
- package/file.js +12 -0
- package/index.html +55 -0
- package/lib/caller.js +30 -0
- package/lib/constants.js +28 -0
- package/lib/deprecations.js +8 -0
- package/lib/levels.js +241 -0
- package/lib/meta.js +3 -0
- package/lib/multistream.js +188 -0
- package/lib/proto.js +234 -0
- package/lib/redaction.js +118 -0
- package/lib/symbols.js +74 -0
- package/lib/time.js +11 -0
- package/lib/tools.js +394 -0
- package/lib/transport-stream.js +56 -0
- package/lib/transport.js +167 -0
- package/lib/worker.js +194 -0
- package/lib/writer.js +44 -0
- package/package.json +38 -0
- package/pino-banner.png +0 -0
- package/pino-logo-hire.png +0 -0
- package/pino-tree.png +0 -0
- package/pino.d.ts +889 -0
- package/pino.js +38 -0
- package/pretty-demo.png +0 -0
- package/tsconfig.json +14 -0
@@ -0,0 +1,188 @@
|
|
1
|
+
'use strict'
|
2
|
+
|
3
|
+
const metadata = Symbol.for('pino.metadata')
|
4
|
+
const { DEFAULT_LEVELS } = require('./constants')
|
5
|
+
|
6
|
+
const DEFAULT_INFO_LEVEL = DEFAULT_LEVELS.info
|
7
|
+
|
8
|
+
function multistream (streamsArray, opts) {
|
9
|
+
let counter = 0
|
10
|
+
streamsArray = streamsArray || []
|
11
|
+
opts = opts || { dedupe: false }
|
12
|
+
|
13
|
+
const streamLevels = Object.create(DEFAULT_LEVELS)
|
14
|
+
streamLevels.silent = Infinity
|
15
|
+
if (opts.levels && typeof opts.levels === 'object') {
|
16
|
+
Object.keys(opts.levels).forEach(i => {
|
17
|
+
streamLevels[i] = opts.levels[i]
|
18
|
+
})
|
19
|
+
}
|
20
|
+
|
21
|
+
const res = {
|
22
|
+
write,
|
23
|
+
add,
|
24
|
+
emit,
|
25
|
+
flushSync,
|
26
|
+
end,
|
27
|
+
minLevel: 0,
|
28
|
+
streams: [],
|
29
|
+
clone,
|
30
|
+
[metadata]: true,
|
31
|
+
streamLevels
|
32
|
+
}
|
33
|
+
|
34
|
+
if (Array.isArray(streamsArray)) {
|
35
|
+
streamsArray.forEach(add, res)
|
36
|
+
} else {
|
37
|
+
add.call(res, streamsArray)
|
38
|
+
}
|
39
|
+
|
40
|
+
// clean this object up
|
41
|
+
// or it will stay allocated forever
|
42
|
+
// as it is closed on the following closures
|
43
|
+
streamsArray = null
|
44
|
+
|
45
|
+
return res
|
46
|
+
|
47
|
+
// we can exit early because the streams are ordered by level
|
48
|
+
function write (data) {
|
49
|
+
let dest
|
50
|
+
const level = this.lastLevel
|
51
|
+
const { streams } = this
|
52
|
+
// for handling situation when several streams has the same level
|
53
|
+
let recordedLevel = 0
|
54
|
+
let stream
|
55
|
+
|
56
|
+
// if dedupe set to true we send logs to the stream with the highest level
|
57
|
+
// therefore, we have to change sorting order
|
58
|
+
for (let i = initLoopVar(streams.length, opts.dedupe); checkLoopVar(i, streams.length, opts.dedupe); i = adjustLoopVar(i, opts.dedupe)) {
|
59
|
+
dest = streams[i]
|
60
|
+
if (dest.level <= level) {
|
61
|
+
if (recordedLevel !== 0 && recordedLevel !== dest.level) {
|
62
|
+
break
|
63
|
+
}
|
64
|
+
stream = dest.stream
|
65
|
+
if (stream[metadata]) {
|
66
|
+
const { lastTime, lastMsg, lastObj, lastLogger } = this
|
67
|
+
stream.lastLevel = level
|
68
|
+
stream.lastTime = lastTime
|
69
|
+
stream.lastMsg = lastMsg
|
70
|
+
stream.lastObj = lastObj
|
71
|
+
stream.lastLogger = lastLogger
|
72
|
+
}
|
73
|
+
stream.write(data)
|
74
|
+
if (opts.dedupe) {
|
75
|
+
recordedLevel = dest.level
|
76
|
+
}
|
77
|
+
} else if (!opts.dedupe) {
|
78
|
+
break
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
function emit (...args) {
|
84
|
+
for (const { stream } of this.streams) {
|
85
|
+
if (typeof stream.emit === 'function') {
|
86
|
+
stream.emit(...args)
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
function flushSync () {
|
92
|
+
for (const { stream } of this.streams) {
|
93
|
+
if (typeof stream.flushSync === 'function') {
|
94
|
+
stream.flushSync()
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
function add (dest) {
|
100
|
+
if (!dest) {
|
101
|
+
return res
|
102
|
+
}
|
103
|
+
|
104
|
+
// Check that dest implements either StreamEntry or DestinationStream
|
105
|
+
const isStream = typeof dest.write === 'function' || dest.stream
|
106
|
+
const stream_ = dest.write ? dest : dest.stream
|
107
|
+
// This is necessary to provide a meaningful error message, otherwise it throws somewhere inside write()
|
108
|
+
if (!isStream) {
|
109
|
+
throw Error('stream object needs to implement either StreamEntry or DestinationStream interface')
|
110
|
+
}
|
111
|
+
|
112
|
+
const { streams, streamLevels } = this
|
113
|
+
|
114
|
+
let level
|
115
|
+
if (typeof dest.levelVal === 'number') {
|
116
|
+
level = dest.levelVal
|
117
|
+
} else if (typeof dest.level === 'string') {
|
118
|
+
level = streamLevels[dest.level]
|
119
|
+
} else if (typeof dest.level === 'number') {
|
120
|
+
level = dest.level
|
121
|
+
} else {
|
122
|
+
level = DEFAULT_INFO_LEVEL
|
123
|
+
}
|
124
|
+
|
125
|
+
const dest_ = {
|
126
|
+
stream: stream_,
|
127
|
+
level,
|
128
|
+
levelVal: undefined,
|
129
|
+
id: counter++
|
130
|
+
}
|
131
|
+
|
132
|
+
streams.unshift(dest_)
|
133
|
+
streams.sort(compareByLevel)
|
134
|
+
|
135
|
+
this.minLevel = streams[0].level
|
136
|
+
|
137
|
+
return res
|
138
|
+
}
|
139
|
+
|
140
|
+
function end () {
|
141
|
+
for (const { stream } of this.streams) {
|
142
|
+
if (typeof stream.flushSync === 'function') {
|
143
|
+
stream.flushSync()
|
144
|
+
}
|
145
|
+
stream.end()
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
function clone (level) {
|
150
|
+
const streams = new Array(this.streams.length)
|
151
|
+
|
152
|
+
for (let i = 0; i < streams.length; i++) {
|
153
|
+
streams[i] = {
|
154
|
+
level,
|
155
|
+
stream: this.streams[i].stream
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
return {
|
160
|
+
write,
|
161
|
+
add,
|
162
|
+
minLevel: level,
|
163
|
+
streams,
|
164
|
+
clone,
|
165
|
+
emit,
|
166
|
+
flushSync,
|
167
|
+
[metadata]: true
|
168
|
+
}
|
169
|
+
}
|
170
|
+
}
|
171
|
+
|
172
|
+
function compareByLevel (a, b) {
|
173
|
+
return a.level - b.level
|
174
|
+
}
|
175
|
+
|
176
|
+
function initLoopVar (length, dedupe) {
|
177
|
+
return dedupe ? length - 1 : 0
|
178
|
+
}
|
179
|
+
|
180
|
+
function adjustLoopVar (i, dedupe) {
|
181
|
+
return dedupe ? i - 1 : i + 1
|
182
|
+
}
|
183
|
+
|
184
|
+
function checkLoopVar (i, length, dedupe) {
|
185
|
+
return dedupe ? i >= 0 : i < length
|
186
|
+
}
|
187
|
+
|
188
|
+
module.exports = multistream
|
package/lib/proto.js
ADDED
@@ -0,0 +1,234 @@
|
|
1
|
+
'use strict'
|
2
|
+
|
3
|
+
/* eslint no-prototype-builtins: 0 */
|
4
|
+
|
5
|
+
const { EventEmitter } = require('node:events')
|
6
|
+
const {
|
7
|
+
lsCacheSym,
|
8
|
+
levelValSym,
|
9
|
+
setLevelSym,
|
10
|
+
getLevelSym,
|
11
|
+
chindingsSym,
|
12
|
+
parsedChindingsSym,
|
13
|
+
mixinSym,
|
14
|
+
asJsonSym,
|
15
|
+
writeSym,
|
16
|
+
mixinMergeStrategySym,
|
17
|
+
timeSym,
|
18
|
+
timeSliceIndexSym,
|
19
|
+
streamSym,
|
20
|
+
serializersSym,
|
21
|
+
formattersSym,
|
22
|
+
errorKeySym,
|
23
|
+
messageKeySym,
|
24
|
+
useOnlyCustomLevelsSym,
|
25
|
+
needsMetadataGsym,
|
26
|
+
redactFmtSym,
|
27
|
+
stringifySym,
|
28
|
+
formatOptsSym,
|
29
|
+
stringifiersSym,
|
30
|
+
msgPrefixSym,
|
31
|
+
hooksSym
|
32
|
+
} = require('./symbols')
|
33
|
+
const {
|
34
|
+
getLevel,
|
35
|
+
setLevel,
|
36
|
+
isLevelEnabled,
|
37
|
+
mappings,
|
38
|
+
initialLsCache,
|
39
|
+
genLsCache,
|
40
|
+
assertNoLevelCollisions
|
41
|
+
} = require('./levels')
|
42
|
+
const {
|
43
|
+
asChindings,
|
44
|
+
asJson,
|
45
|
+
buildFormatters,
|
46
|
+
stringify
|
47
|
+
} = require('./tools')
|
48
|
+
const {
|
49
|
+
version
|
50
|
+
} = require('./meta')
|
51
|
+
const redaction = require('./redaction')
|
52
|
+
|
53
|
+
// note: use of class is satirical
|
54
|
+
// https://github.com/pinojs/pino/pull/433#pullrequestreview-127703127
|
55
|
+
const constructor = class Pino {}
|
56
|
+
const prototype = {
|
57
|
+
constructor,
|
58
|
+
child,
|
59
|
+
bindings,
|
60
|
+
setBindings,
|
61
|
+
flush,
|
62
|
+
isLevelEnabled,
|
63
|
+
version,
|
64
|
+
get level () { return this[getLevelSym]() },
|
65
|
+
set level (lvl) { this[setLevelSym](lvl) },
|
66
|
+
get levelVal () { return this[levelValSym] },
|
67
|
+
set levelVal (n) { throw Error('levelVal is read-only') },
|
68
|
+
[lsCacheSym]: initialLsCache,
|
69
|
+
[writeSym]: write,
|
70
|
+
[asJsonSym]: asJson,
|
71
|
+
[getLevelSym]: getLevel,
|
72
|
+
[setLevelSym]: setLevel
|
73
|
+
}
|
74
|
+
|
75
|
+
Object.setPrototypeOf(prototype, EventEmitter.prototype)
|
76
|
+
|
77
|
+
// exporting and consuming the prototype object using factory pattern fixes scoping issues with getters when serializing
|
78
|
+
module.exports = function () {
|
79
|
+
return Object.create(prototype)
|
80
|
+
}
|
81
|
+
|
82
|
+
const resetChildingsFormatter = bindings => bindings
|
83
|
+
function child (bindings, options) {
|
84
|
+
if (!bindings) {
|
85
|
+
throw Error('missing bindings for child Pino')
|
86
|
+
}
|
87
|
+
options = options || {} // default options to empty object
|
88
|
+
const serializers = this[serializersSym]
|
89
|
+
const formatters = this[formattersSym]
|
90
|
+
const instance = Object.create(this)
|
91
|
+
|
92
|
+
if (options.hasOwnProperty('serializers') === true) {
|
93
|
+
instance[serializersSym] = Object.create(null)
|
94
|
+
|
95
|
+
for (const k in serializers) {
|
96
|
+
instance[serializersSym][k] = serializers[k]
|
97
|
+
}
|
98
|
+
const parentSymbols = Object.getOwnPropertySymbols(serializers)
|
99
|
+
/* eslint no-var: off */
|
100
|
+
for (var i = 0; i < parentSymbols.length; i++) {
|
101
|
+
const ks = parentSymbols[i]
|
102
|
+
instance[serializersSym][ks] = serializers[ks]
|
103
|
+
}
|
104
|
+
|
105
|
+
for (const bk in options.serializers) {
|
106
|
+
instance[serializersSym][bk] = options.serializers[bk]
|
107
|
+
}
|
108
|
+
const bindingsSymbols = Object.getOwnPropertySymbols(options.serializers)
|
109
|
+
for (var bi = 0; bi < bindingsSymbols.length; bi++) {
|
110
|
+
const bks = bindingsSymbols[bi]
|
111
|
+
instance[serializersSym][bks] = options.serializers[bks]
|
112
|
+
}
|
113
|
+
} else instance[serializersSym] = serializers
|
114
|
+
if (options.hasOwnProperty('formatters')) {
|
115
|
+
const { level, bindings: chindings, log } = options.formatters
|
116
|
+
instance[formattersSym] = buildFormatters(
|
117
|
+
level || formatters.level,
|
118
|
+
chindings || resetChildingsFormatter,
|
119
|
+
log || formatters.log
|
120
|
+
)
|
121
|
+
} else {
|
122
|
+
instance[formattersSym] = buildFormatters(
|
123
|
+
formatters.level,
|
124
|
+
resetChildingsFormatter,
|
125
|
+
formatters.log
|
126
|
+
)
|
127
|
+
}
|
128
|
+
if (options.hasOwnProperty('customLevels') === true) {
|
129
|
+
assertNoLevelCollisions(this.levels, options.customLevels)
|
130
|
+
instance.levels = mappings(options.customLevels, instance[useOnlyCustomLevelsSym])
|
131
|
+
genLsCache(instance)
|
132
|
+
}
|
133
|
+
|
134
|
+
// redact must place before asChindings and only replace if exist
|
135
|
+
if ((typeof options.redact === 'object' && options.redact !== null) || Array.isArray(options.redact)) {
|
136
|
+
instance.redact = options.redact // replace redact directly
|
137
|
+
const stringifiers = redaction(instance.redact, stringify)
|
138
|
+
const formatOpts = { stringify: stringifiers[redactFmtSym] }
|
139
|
+
instance[stringifySym] = stringify
|
140
|
+
instance[stringifiersSym] = stringifiers
|
141
|
+
instance[formatOptsSym] = formatOpts
|
142
|
+
}
|
143
|
+
|
144
|
+
if (typeof options.msgPrefix === 'string') {
|
145
|
+
instance[msgPrefixSym] = (this[msgPrefixSym] || '') + options.msgPrefix
|
146
|
+
}
|
147
|
+
|
148
|
+
instance[chindingsSym] = asChindings(instance, bindings)
|
149
|
+
const childLevel = options.level || this.level
|
150
|
+
instance[setLevelSym](childLevel)
|
151
|
+
this.onChild(instance)
|
152
|
+
return instance
|
153
|
+
}
|
154
|
+
|
155
|
+
function bindings () {
|
156
|
+
const chindings = this[chindingsSym]
|
157
|
+
const chindingsJson = `{${chindings.substr(1)}}` // at least contains ,"pid":7068,"hostname":"myMac"
|
158
|
+
const bindingsFromJson = JSON.parse(chindingsJson)
|
159
|
+
delete bindingsFromJson.pid
|
160
|
+
delete bindingsFromJson.hostname
|
161
|
+
return bindingsFromJson
|
162
|
+
}
|
163
|
+
|
164
|
+
function setBindings (newBindings) {
|
165
|
+
const chindings = asChindings(this, newBindings)
|
166
|
+
this[chindingsSym] = chindings
|
167
|
+
delete this[parsedChindingsSym]
|
168
|
+
}
|
169
|
+
|
170
|
+
/**
|
171
|
+
* Default strategy for creating `mergeObject` from arguments and the result from `mixin()`.
|
172
|
+
* Fields from `mergeObject` have higher priority in this strategy.
|
173
|
+
*
|
174
|
+
* @param {Object} mergeObject The object a user has supplied to the logging function.
|
175
|
+
* @param {Object} mixinObject The result of the `mixin` method.
|
176
|
+
* @return {Object}
|
177
|
+
*/
|
178
|
+
function defaultMixinMergeStrategy (mergeObject, mixinObject) {
|
179
|
+
return Object.assign(mixinObject, mergeObject)
|
180
|
+
}
|
181
|
+
|
182
|
+
function write (_obj, msg, num) {
|
183
|
+
const t = this[timeSym]()
|
184
|
+
const mixin = this[mixinSym]
|
185
|
+
const errorKey = this[errorKeySym]
|
186
|
+
const messageKey = this[messageKeySym]
|
187
|
+
const mixinMergeStrategy = this[mixinMergeStrategySym] || defaultMixinMergeStrategy
|
188
|
+
let obj
|
189
|
+
const streamWriteHook = this[hooksSym].streamWrite
|
190
|
+
|
191
|
+
if (_obj === undefined || _obj === null) {
|
192
|
+
obj = {}
|
193
|
+
} else if (_obj instanceof Error) {
|
194
|
+
obj = { [errorKey]: _obj }
|
195
|
+
if (msg === undefined) {
|
196
|
+
msg = _obj.message
|
197
|
+
}
|
198
|
+
} else {
|
199
|
+
obj = _obj
|
200
|
+
if (msg === undefined && _obj[messageKey] === undefined && _obj[errorKey]) {
|
201
|
+
msg = _obj[errorKey].message
|
202
|
+
}
|
203
|
+
}
|
204
|
+
|
205
|
+
if (mixin) {
|
206
|
+
obj = mixinMergeStrategy(obj, mixin(obj, num, this))
|
207
|
+
}
|
208
|
+
|
209
|
+
const s = this[asJsonSym](obj, msg, num, t)
|
210
|
+
|
211
|
+
const stream = this[streamSym]
|
212
|
+
if (stream[needsMetadataGsym] === true) {
|
213
|
+
stream.lastLevel = num
|
214
|
+
stream.lastObj = obj
|
215
|
+
stream.lastMsg = msg
|
216
|
+
stream.lastTime = t.slice(this[timeSliceIndexSym])
|
217
|
+
stream.lastLogger = this // for child loggers
|
218
|
+
}
|
219
|
+
stream.write(streamWriteHook ? streamWriteHook(s) : s)
|
220
|
+
}
|
221
|
+
|
222
|
+
function noop () {}
|
223
|
+
|
224
|
+
function flush (cb) {
|
225
|
+
if (cb != null && typeof cb !== 'function') {
|
226
|
+
throw Error('callback must be a function')
|
227
|
+
}
|
228
|
+
|
229
|
+
const stream = this[streamSym]
|
230
|
+
|
231
|
+
if (typeof stream.flush === 'function') {
|
232
|
+
stream.flush(cb || noop)
|
233
|
+
} else if (cb) cb()
|
234
|
+
}
|
package/lib/redaction.js
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
'use strict'
|
2
|
+
|
3
|
+
const fastRedact = require('fast-redact')
|
4
|
+
const { redactFmtSym, wildcardFirstSym } = require('./symbols')
|
5
|
+
const { rx, validator } = fastRedact
|
6
|
+
|
7
|
+
const validate = validator({
|
8
|
+
ERR_PATHS_MUST_BE_STRINGS: () => 'pino – redacted paths must be strings',
|
9
|
+
ERR_INVALID_PATH: (s) => `pino – redact paths array contains an invalid path (${s})`
|
10
|
+
})
|
11
|
+
|
12
|
+
const CENSOR = '[Redacted]'
|
13
|
+
const strict = false // TODO should this be configurable?
|
14
|
+
|
15
|
+
function redaction (opts, serialize) {
|
16
|
+
const { paths, censor } = handle(opts)
|
17
|
+
|
18
|
+
const shape = paths.reduce((o, str) => {
|
19
|
+
rx.lastIndex = 0
|
20
|
+
const first = rx.exec(str)
|
21
|
+
const next = rx.exec(str)
|
22
|
+
|
23
|
+
// ns is the top-level path segment, brackets + quoting removed.
|
24
|
+
let ns = first[1] !== undefined
|
25
|
+
? first[1].replace(/^(?:"|'|`)(.*)(?:"|'|`)$/, '$1')
|
26
|
+
: first[0]
|
27
|
+
|
28
|
+
if (ns === '*') {
|
29
|
+
ns = wildcardFirstSym
|
30
|
+
}
|
31
|
+
|
32
|
+
// top level key:
|
33
|
+
if (next === null) {
|
34
|
+
o[ns] = null
|
35
|
+
return o
|
36
|
+
}
|
37
|
+
|
38
|
+
// path with at least two segments:
|
39
|
+
// if ns is already redacted at the top level, ignore lower level redactions
|
40
|
+
if (o[ns] === null) {
|
41
|
+
return o
|
42
|
+
}
|
43
|
+
|
44
|
+
const { index } = next
|
45
|
+
const nextPath = `${str.substr(index, str.length - 1)}`
|
46
|
+
|
47
|
+
o[ns] = o[ns] || []
|
48
|
+
|
49
|
+
// shape is a mix of paths beginning with literal values and wildcard
|
50
|
+
// paths [ "a.b.c", "*.b.z" ] should reduce to a shape of
|
51
|
+
// { "a": [ "b.c", "b.z" ], *: [ "b.z" ] }
|
52
|
+
// note: "b.z" is in both "a" and * arrays because "a" matches the wildcard.
|
53
|
+
// (* entry has wildcardFirstSym as key)
|
54
|
+
if (ns !== wildcardFirstSym && o[ns].length === 0) {
|
55
|
+
// first time ns's get all '*' redactions so far
|
56
|
+
o[ns].push(...(o[wildcardFirstSym] || []))
|
57
|
+
}
|
58
|
+
|
59
|
+
if (ns === wildcardFirstSym) {
|
60
|
+
// new * path gets added to all previously registered literal ns's.
|
61
|
+
Object.keys(o).forEach(function (k) {
|
62
|
+
if (o[k]) {
|
63
|
+
o[k].push(nextPath)
|
64
|
+
}
|
65
|
+
})
|
66
|
+
}
|
67
|
+
|
68
|
+
o[ns].push(nextPath)
|
69
|
+
return o
|
70
|
+
}, {})
|
71
|
+
|
72
|
+
// the redactor assigned to the format symbol key
|
73
|
+
// provides top level redaction for instances where
|
74
|
+
// an object is interpolated into the msg string
|
75
|
+
const result = {
|
76
|
+
[redactFmtSym]: fastRedact({ paths, censor, serialize, strict })
|
77
|
+
}
|
78
|
+
|
79
|
+
const topCensor = (...args) => {
|
80
|
+
return typeof censor === 'function' ? serialize(censor(...args)) : serialize(censor)
|
81
|
+
}
|
82
|
+
|
83
|
+
return [...Object.keys(shape), ...Object.getOwnPropertySymbols(shape)].reduce((o, k) => {
|
84
|
+
// top level key:
|
85
|
+
if (shape[k] === null) {
|
86
|
+
o[k] = (value) => topCensor(value, [k])
|
87
|
+
} else {
|
88
|
+
const wrappedCensor = typeof censor === 'function'
|
89
|
+
? (value, path) => {
|
90
|
+
return censor(value, [k, ...path])
|
91
|
+
}
|
92
|
+
: censor
|
93
|
+
o[k] = fastRedact({
|
94
|
+
paths: shape[k],
|
95
|
+
censor: wrappedCensor,
|
96
|
+
serialize,
|
97
|
+
strict
|
98
|
+
})
|
99
|
+
}
|
100
|
+
return o
|
101
|
+
}, result)
|
102
|
+
}
|
103
|
+
|
104
|
+
function handle (opts) {
|
105
|
+
if (Array.isArray(opts)) {
|
106
|
+
opts = { paths: opts, censor: CENSOR }
|
107
|
+
validate(opts)
|
108
|
+
return opts
|
109
|
+
}
|
110
|
+
let { paths, censor = CENSOR, remove } = opts
|
111
|
+
if (Array.isArray(paths) === false) { throw Error('pino – redact must contain an array of strings') }
|
112
|
+
if (remove === true) censor = undefined
|
113
|
+
validate({ paths, censor })
|
114
|
+
|
115
|
+
return { paths, censor }
|
116
|
+
}
|
117
|
+
|
118
|
+
module.exports = redaction
|
package/lib/symbols.js
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
'use strict'
|
2
|
+
|
3
|
+
const setLevelSym = Symbol('pino.setLevel')
|
4
|
+
const getLevelSym = Symbol('pino.getLevel')
|
5
|
+
const levelValSym = Symbol('pino.levelVal')
|
6
|
+
const levelCompSym = Symbol('pino.levelComp')
|
7
|
+
const useLevelLabelsSym = Symbol('pino.useLevelLabels')
|
8
|
+
const useOnlyCustomLevelsSym = Symbol('pino.useOnlyCustomLevels')
|
9
|
+
const mixinSym = Symbol('pino.mixin')
|
10
|
+
|
11
|
+
const lsCacheSym = Symbol('pino.lsCache')
|
12
|
+
const chindingsSym = Symbol('pino.chindings')
|
13
|
+
|
14
|
+
const asJsonSym = Symbol('pino.asJson')
|
15
|
+
const writeSym = Symbol('pino.write')
|
16
|
+
const redactFmtSym = Symbol('pino.redactFmt')
|
17
|
+
|
18
|
+
const timeSym = Symbol('pino.time')
|
19
|
+
const timeSliceIndexSym = Symbol('pino.timeSliceIndex')
|
20
|
+
const streamSym = Symbol('pino.stream')
|
21
|
+
const stringifySym = Symbol('pino.stringify')
|
22
|
+
const stringifySafeSym = Symbol('pino.stringifySafe')
|
23
|
+
const stringifiersSym = Symbol('pino.stringifiers')
|
24
|
+
const endSym = Symbol('pino.end')
|
25
|
+
const formatOptsSym = Symbol('pino.formatOpts')
|
26
|
+
const messageKeySym = Symbol('pino.messageKey')
|
27
|
+
const errorKeySym = Symbol('pino.errorKey')
|
28
|
+
const nestedKeySym = Symbol('pino.nestedKey')
|
29
|
+
const nestedKeyStrSym = Symbol('pino.nestedKeyStr')
|
30
|
+
const mixinMergeStrategySym = Symbol('pino.mixinMergeStrategy')
|
31
|
+
const msgPrefixSym = Symbol('pino.msgPrefix')
|
32
|
+
|
33
|
+
const wildcardFirstSym = Symbol('pino.wildcardFirst')
|
34
|
+
|
35
|
+
// public symbols, no need to use the same pino
|
36
|
+
// version for these
|
37
|
+
const serializersSym = Symbol.for('pino.serializers')
|
38
|
+
const formattersSym = Symbol.for('pino.formatters')
|
39
|
+
const hooksSym = Symbol.for('pino.hooks')
|
40
|
+
const needsMetadataGsym = Symbol.for('pino.metadata')
|
41
|
+
|
42
|
+
module.exports = {
|
43
|
+
setLevelSym,
|
44
|
+
getLevelSym,
|
45
|
+
levelValSym,
|
46
|
+
levelCompSym,
|
47
|
+
useLevelLabelsSym,
|
48
|
+
mixinSym,
|
49
|
+
lsCacheSym,
|
50
|
+
chindingsSym,
|
51
|
+
asJsonSym,
|
52
|
+
writeSym,
|
53
|
+
serializersSym,
|
54
|
+
redactFmtSym,
|
55
|
+
timeSym,
|
56
|
+
timeSliceIndexSym,
|
57
|
+
streamSym,
|
58
|
+
stringifySym,
|
59
|
+
stringifySafeSym,
|
60
|
+
stringifiersSym,
|
61
|
+
endSym,
|
62
|
+
formatOptsSym,
|
63
|
+
messageKeySym,
|
64
|
+
errorKeySym,
|
65
|
+
nestedKeySym,
|
66
|
+
wildcardFirstSym,
|
67
|
+
needsMetadataGsym,
|
68
|
+
useOnlyCustomLevelsSym,
|
69
|
+
formattersSym,
|
70
|
+
hooksSym,
|
71
|
+
nestedKeyStrSym,
|
72
|
+
mixinMergeStrategySym,
|
73
|
+
msgPrefixSym
|
74
|
+
}
|
package/lib/time.js
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
'use strict'
|
2
|
+
|
3
|
+
const nullTime = () => ''
|
4
|
+
|
5
|
+
const epochTime = () => `,"time":${Date.now()}`
|
6
|
+
|
7
|
+
const unixTime = () => `,"time":${Math.round(Date.now() / 1000.0)}`
|
8
|
+
|
9
|
+
const isoTime = () => `,"time":"${new Date(Date.now()).toISOString()}"` // using Date.now() for testability
|
10
|
+
|
11
|
+
module.exports = { nullTime, epochTime, unixTime, isoTime }
|