pino-testkit 10.4.5
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/.nojekyll +0 -0
- package/.prettierignore +1 -0
- package/CNAME +1 -0
- package/CONTRIBUTING.md +30 -0
- package/LICENSE +21 -0
- package/README.md +175 -0
- package/SECURITY.md +87 -0
- package/benchmarks/basic.bench.js +95 -0
- package/benchmarks/child-child.bench.js +52 -0
- package/benchmarks/child-creation.bench.js +73 -0
- package/benchmarks/child.bench.js +62 -0
- package/benchmarks/deep-object.bench.js +88 -0
- package/benchmarks/formatters.bench.js +50 -0
- package/benchmarks/internal/custom-levels.js +67 -0
- package/benchmarks/internal/just-pino-heavy.bench.js +76 -0
- package/benchmarks/internal/just-pino.bench.js +182 -0
- package/benchmarks/internal/parent-vs-child.bench.js +75 -0
- package/benchmarks/internal/redact.bench.js +86 -0
- package/benchmarks/long-string.bench.js +81 -0
- package/benchmarks/multi-arg.bench.js +193 -0
- package/benchmarks/multistream.js +98 -0
- package/benchmarks/object.bench.js +82 -0
- package/benchmarks/utils/generate-benchmark-doc.js +36 -0
- package/benchmarks/utils/runbench.js +138 -0
- package/benchmarks/utils/wrap-log-level.js +55 -0
- package/bin.js +6 -0
- package/browser.js +547 -0
- package/build/sync-version.js +25 -0
- package/docs/api.md +1593 -0
- package/docs/asynchronous.md +40 -0
- package/docs/benchmarks.md +55 -0
- package/docs/browser.md +278 -0
- package/docs/bundling.md +40 -0
- package/docs/child-loggers.md +95 -0
- package/docs/diagnostics.md +16 -0
- package/docs/ecosystem.md +86 -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 +1376 -0
- package/docs/web.md +309 -0
- package/eslint.config.js +28 -0
- package/examples/basic.js +43 -0
- package/examples/transport.js +68 -0
- package/favicon.ico +0 -0
- package/file.js +12 -0
- package/inc-version.sh +42 -0
- package/index.html +55 -0
- package/lib/caller.js +30 -0
- package/lib/constants.js +28 -0
- package/lib/contract.js +8 -0
- package/lib/deprecations.js +8 -0
- package/lib/levels.js +241 -0
- package/lib/meta.js +3 -0
- package/lib/multistream.js +203 -0
- package/lib/proto.js +256 -0
- package/lib/redaction.js +114 -0
- package/lib/symbols.js +74 -0
- package/lib/time.js +39 -0
- package/lib/tools.js +427 -0
- package/lib/transport-stream.js +56 -0
- package/lib/transport.js +289 -0
- package/lib/worker.js +194 -0
- package/package.json +119 -0
- package/pino.d.ts +908 -0
- package/pino.js +240 -0
- package/test/basic.test.js +886 -0
- package/test/broken-pipe.test.js +59 -0
- package/test/browser-child.test.js +132 -0
- package/test/browser-disabled.test.js +87 -0
- package/test/browser-early-console-freeze.test.js +12 -0
- package/test/browser-is-level-enabled.test.js +101 -0
- package/test/browser-levels.test.js +241 -0
- package/test/browser-serializers.test.js +352 -0
- package/test/browser-timestamp.test.js +88 -0
- package/test/browser-transmit.test.js +417 -0
- package/test/browser.test.js +698 -0
- package/test/complex-objects.test.js +36 -0
- package/test/crlf.test.js +34 -0
- package/test/custom-levels.test.js +267 -0
- package/test/diagnostics.test.js +107 -0
- package/test/error-key.test.js +37 -0
- package/test/error.test.js +403 -0
- package/test/escaping.test.js +93 -0
- package/test/esm/esm.mjs +14 -0
- package/test/esm/index.test.js +21 -0
- package/test/esm/named-exports.mjs +29 -0
- package/test/exit.test.js +79 -0
- package/test/fixtures/broken-pipe/basic.js +9 -0
- package/test/fixtures/broken-pipe/destination.js +10 -0
- package/test/fixtures/broken-pipe/syncfalse.js +12 -0
- package/test/fixtures/console-transport.js +13 -0
- package/test/fixtures/crashing-transport.js +13 -0
- package/test/fixtures/default-exit.js +8 -0
- package/test/fixtures/destination-exit.js +8 -0
- package/test/fixtures/eval/index.js +13 -0
- package/test/fixtures/eval/node_modules/14-files.js +3 -0
- package/test/fixtures/eval/node_modules/2-files.js +3 -0
- package/test/fixtures/eval/node_modules/file1.js +5 -0
- package/test/fixtures/eval/node_modules/file10.js +5 -0
- package/test/fixtures/eval/node_modules/file11.js +5 -0
- package/test/fixtures/eval/node_modules/file12.js +5 -0
- package/test/fixtures/eval/node_modules/file13.js +5 -0
- package/test/fixtures/eval/node_modules/file14.js +11 -0
- package/test/fixtures/eval/node_modules/file2.js +5 -0
- package/test/fixtures/eval/node_modules/file3.js +5 -0
- package/test/fixtures/eval/node_modules/file4.js +5 -0
- package/test/fixtures/eval/node_modules/file5.js +5 -0
- package/test/fixtures/eval/node_modules/file6.js +5 -0
- package/test/fixtures/eval/node_modules/file7.js +5 -0
- package/test/fixtures/eval/node_modules/file8.js +5 -0
- package/test/fixtures/eval/node_modules/file9.js +5 -0
- package/test/fixtures/noop-transport.js +10 -0
- package/test/fixtures/pretty/null-prototype.js +8 -0
- package/test/fixtures/stdout-hack-protection.js +11 -0
- package/test/fixtures/syncfalse-child.js +6 -0
- package/test/fixtures/syncfalse-exit.js +9 -0
- package/test/fixtures/syncfalse-flush-exit.js +10 -0
- package/test/fixtures/syncfalse.js +6 -0
- package/test/fixtures/syntax-error-esm.mjs +2 -0
- package/test/fixtures/to-file-transport-with-transform.js +20 -0
- package/test/fixtures/to-file-transport.js +13 -0
- package/test/fixtures/to-file-transport.mjs +8 -0
- package/test/fixtures/transport/index.js +12 -0
- package/test/fixtures/transport/package.json +5 -0
- package/test/fixtures/transport-exit-immediately-with-async-dest.js +16 -0
- package/test/fixtures/transport-exit-immediately.js +11 -0
- package/test/fixtures/transport-exit-on-ready.js +12 -0
- package/test/fixtures/transport-invalid-node-options.js +26 -0
- package/test/fixtures/transport-main.js +9 -0
- package/test/fixtures/transport-many-lines.js +29 -0
- package/test/fixtures/transport-preload-main.mjs +13 -0
- package/test/fixtures/transport-preload.mjs +13 -0
- package/test/fixtures/transport-string-stdout.js +9 -0
- package/test/fixtures/transport-transform.js +21 -0
- package/test/fixtures/transport-uses-pino-config.js +33 -0
- package/test/fixtures/transport-with-on-exit.js +12 -0
- package/test/fixtures/transport-worker-data.js +19 -0
- package/test/fixtures/transport-worker-name.js +24 -0
- package/test/fixtures/transport-worker.js +15 -0
- package/test/fixtures/transport-wrong-export-type.js +3 -0
- package/test/fixtures/ts/to-file-transport-native.mts +15 -0
- package/test/fixtures/ts/to-file-transport-with-transform.ts +18 -0
- package/test/fixtures/ts/to-file-transport.ts +11 -0
- package/test/fixtures/ts/transpile.cjs +36 -0
- package/test/fixtures/ts/transport-exit-immediately-with-async-dest.ts +15 -0
- package/test/fixtures/ts/transport-exit-immediately.ts +10 -0
- package/test/fixtures/ts/transport-exit-on-ready.ts +11 -0
- package/test/fixtures/ts/transport-main.ts +8 -0
- package/test/fixtures/ts/transport-string-stdout.ts +8 -0
- package/test/fixtures/ts/transport-worker.ts +14 -0
- package/test/formatters.test.js +364 -0
- package/test/helper.d.ts +4 -0
- package/test/helper.js +155 -0
- package/test/hooks.test.js +114 -0
- package/test/http.test.js +214 -0
- package/test/internals/version.test.js +17 -0
- package/test/is-level-enabled.test.js +179 -0
- package/test/jest/basic.spec.js +10 -0
- package/test/levels.test.js +810 -0
- package/test/metadata.test.js +120 -0
- package/test/mixin-merge-strategy.test.js +57 -0
- package/test/mixin.test.js +241 -0
- package/test/multistream.test.js +729 -0
- package/test/redact.test.js +893 -0
- package/test/serializers.test.js +257 -0
- package/test/stdout-protection.test.js +41 -0
- package/test/syncfalse.test.js +186 -0
- package/test/timestamp-nano.test.js +37 -0
- package/test/timestamp.test.js +124 -0
- package/test/transport/big.test.js +42 -0
- package/test/transport/bundlers-support.test.js +99 -0
- package/test/transport/caller.test.js +24 -0
- package/test/transport/core.test.js +733 -0
- package/test/transport/core.transpiled.test.ts +114 -0
- package/test/transport/crash.test.js +36 -0
- package/test/transport/module-link.test.js +241 -0
- package/test/transport/native-type-stripping.test.mjs +151 -0
- package/test/transport/node-options.test.js +116 -0
- package/test/transport/pipeline.test.js +137 -0
- package/test/transport/preload.test.js +54 -0
- package/test/transport/repl.test.js +15 -0
- package/test/transport/sync-false.test.js +67 -0
- package/test/transport/sync-true.test.js +57 -0
- package/test/transport/targets.test.js +48 -0
- package/test/transport/uses-pino-config.test.js +166 -0
- package/test/transport-stream.test.js +40 -0
- package/test/types/pino-import.test-d.cts +30 -0
- package/test/types/pino-multistream.test-d.ts +28 -0
- package/test/types/pino-top-export.test-d.ts +34 -0
- package/test/types/pino-transport.test-d.ts +156 -0
- package/test/types/pino-type-only.test-d.ts +75 -0
- package/test/types/pino.test-d.ts +683 -0
- package/test/types/pino.ts +91 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import test from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import * as os from 'node:os'
|
|
4
|
+
import { join } from 'node:path'
|
|
5
|
+
import fs from 'node:fs'
|
|
6
|
+
import * as url from 'node:url'
|
|
7
|
+
|
|
8
|
+
import { watchFileCreated } from '../helper'
|
|
9
|
+
import pino from '../../'
|
|
10
|
+
|
|
11
|
+
const readFile = fs.promises.readFile
|
|
12
|
+
|
|
13
|
+
const { pid } = process
|
|
14
|
+
const hostname = os.hostname()
|
|
15
|
+
|
|
16
|
+
// A subset of the test from core.test.js, we don't need all of them to check for compatibility
|
|
17
|
+
function runTests (esVersion: string): void {
|
|
18
|
+
test(`(ts -> ${esVersion}) pino.transport with file`, async (t) => {
|
|
19
|
+
const destination = join(
|
|
20
|
+
os.tmpdir(),
|
|
21
|
+
'_' + Math.random().toString(36).substr(2, 9)
|
|
22
|
+
)
|
|
23
|
+
const transport = pino.transport({
|
|
24
|
+
target: join(__dirname, '..', 'fixtures', 'ts', `to-file-transport.${esVersion}.cjs`),
|
|
25
|
+
options: { destination }
|
|
26
|
+
})
|
|
27
|
+
t.after(transport.end.bind(transport))
|
|
28
|
+
const instance = pino(transport)
|
|
29
|
+
instance.info('hello')
|
|
30
|
+
await watchFileCreated(destination)
|
|
31
|
+
const result = JSON.parse(await readFile(destination, { encoding: 'utf8' }))
|
|
32
|
+
delete result.time
|
|
33
|
+
assert.deepEqual(result, {
|
|
34
|
+
pid,
|
|
35
|
+
hostname,
|
|
36
|
+
level: 30,
|
|
37
|
+
msg: 'hello'
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test(`(ts -> ${esVersion}) pino.transport with file URL`, async (t) => {
|
|
42
|
+
const destination = join(
|
|
43
|
+
os.tmpdir(),
|
|
44
|
+
'_' + Math.random().toString(36).substr(2, 9)
|
|
45
|
+
)
|
|
46
|
+
const transport = pino.transport({
|
|
47
|
+
target: url.pathToFileURL(join(__dirname, '..', 'fixtures', 'ts', `to-file-transport.${esVersion}.cjs`)).href,
|
|
48
|
+
options: { destination }
|
|
49
|
+
})
|
|
50
|
+
t.after(transport.end.bind(transport))
|
|
51
|
+
const instance = pino(transport)
|
|
52
|
+
instance.info('hello')
|
|
53
|
+
await watchFileCreated(destination)
|
|
54
|
+
const result = JSON.parse(await readFile(destination, { encoding: 'utf8' }))
|
|
55
|
+
delete result.time
|
|
56
|
+
assert.deepEqual(result, {
|
|
57
|
+
pid,
|
|
58
|
+
hostname,
|
|
59
|
+
level: 30,
|
|
60
|
+
msg: 'hello'
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test(`(ts -> ${esVersion}) pino.transport with two files`, async (t) => {
|
|
65
|
+
const dest1 = join(
|
|
66
|
+
os.tmpdir(),
|
|
67
|
+
'_' + Math.random().toString(36).substr(2, 9)
|
|
68
|
+
)
|
|
69
|
+
const dest2 = join(
|
|
70
|
+
os.tmpdir(),
|
|
71
|
+
'_' + Math.random().toString(36).substr(2, 9)
|
|
72
|
+
)
|
|
73
|
+
const transport = pino.transport({
|
|
74
|
+
targets: [{
|
|
75
|
+
level: 'info',
|
|
76
|
+
target: join(__dirname, '..', 'fixtures', 'ts', `to-file-transport.${esVersion}.cjs`),
|
|
77
|
+
options: { destination: dest1 }
|
|
78
|
+
}, {
|
|
79
|
+
level: 'info',
|
|
80
|
+
target: join(__dirname, '..', 'fixtures', 'ts', `to-file-transport.${esVersion}.cjs`),
|
|
81
|
+
options: { destination: dest2 }
|
|
82
|
+
}]
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
t.after(transport.end.bind(transport))
|
|
86
|
+
|
|
87
|
+
const instance = pino(transport)
|
|
88
|
+
instance.info('hello')
|
|
89
|
+
|
|
90
|
+
await Promise.all([watchFileCreated(dest1), watchFileCreated(dest2)])
|
|
91
|
+
|
|
92
|
+
const result1 = JSON.parse(await readFile(dest1, { encoding: 'utf8' }))
|
|
93
|
+
delete result1.time
|
|
94
|
+
assert.deepEqual(result1, {
|
|
95
|
+
pid,
|
|
96
|
+
hostname,
|
|
97
|
+
level: 30,
|
|
98
|
+
msg: 'hello'
|
|
99
|
+
})
|
|
100
|
+
const result2 = JSON.parse(await readFile(dest2, { encoding: 'utf8' }))
|
|
101
|
+
delete result2.time
|
|
102
|
+
assert.deepEqual(result2, {
|
|
103
|
+
pid,
|
|
104
|
+
hostname,
|
|
105
|
+
level: 30,
|
|
106
|
+
msg: 'hello'
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
runTests('es5')
|
|
112
|
+
runTests('es6')
|
|
113
|
+
runTests('es2017')
|
|
114
|
+
runTests('esnext')
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('node:test')
|
|
4
|
+
const assert = require('node:assert')
|
|
5
|
+
const { join } = require('node:path')
|
|
6
|
+
const { once } = require('node:events')
|
|
7
|
+
const { setImmediate: immediate } = require('node:timers/promises')
|
|
8
|
+
|
|
9
|
+
const pino = require('../../')
|
|
10
|
+
|
|
11
|
+
test('pino.transport emits error if the worker exits with 0 unexpectably', async (t) => {
|
|
12
|
+
// This test will take 10s, because flushSync waits for 10s
|
|
13
|
+
const transport = pino.transport({
|
|
14
|
+
target: join(__dirname, '..', 'fixtures', 'crashing-transport.js'),
|
|
15
|
+
sync: true
|
|
16
|
+
})
|
|
17
|
+
t.after(transport.end.bind(transport))
|
|
18
|
+
|
|
19
|
+
await once(transport, 'ready')
|
|
20
|
+
|
|
21
|
+
let maybeError
|
|
22
|
+
transport.on('error', (err) => {
|
|
23
|
+
maybeError = err
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const logger = pino(transport)
|
|
27
|
+
for (let i = 0; i < 100000; i++) {
|
|
28
|
+
logger.info('hello')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
await once(transport.worker, 'exit')
|
|
32
|
+
|
|
33
|
+
await immediate()
|
|
34
|
+
|
|
35
|
+
assert.equal(maybeError.message, 'the worker has exited')
|
|
36
|
+
})
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('node:test')
|
|
4
|
+
const assert = require('node:assert')
|
|
5
|
+
const os = require('node:os')
|
|
6
|
+
const { join } = require('node:path')
|
|
7
|
+
const { readFile, symlink, unlink, mkdir, writeFile } = require('node:fs').promises
|
|
8
|
+
const { once } = require('node:events')
|
|
9
|
+
const execa = require('execa')
|
|
10
|
+
const rimraf = require('rimraf')
|
|
11
|
+
|
|
12
|
+
const { isWin, isYarnPnp, watchFileCreated, file } = require('../helper')
|
|
13
|
+
const pino = require('../../')
|
|
14
|
+
|
|
15
|
+
const { pid } = process
|
|
16
|
+
const hostname = os.hostname()
|
|
17
|
+
|
|
18
|
+
async function installTransportModule (target) {
|
|
19
|
+
if (isYarnPnp) {
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
await uninstallTransportModule()
|
|
24
|
+
} catch {}
|
|
25
|
+
|
|
26
|
+
if (!target) {
|
|
27
|
+
target = join(__dirname, '..', '..')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
await symlink(
|
|
31
|
+
join(__dirname, '..', 'fixtures', 'transport'),
|
|
32
|
+
join(target, 'node_modules', 'transport')
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function uninstallTransportModule () {
|
|
37
|
+
if (isYarnPnp) {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
await unlink(join(__dirname, '..', '..', 'node_modules', 'transport'))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// TODO make this test pass on Windows
|
|
44
|
+
test('pino.transport with package', { skip: isWin }, async (t) => {
|
|
45
|
+
const destination = file()
|
|
46
|
+
|
|
47
|
+
await installTransportModule()
|
|
48
|
+
|
|
49
|
+
const transport = pino.transport({
|
|
50
|
+
target: 'transport',
|
|
51
|
+
options: { destination }
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
t.after(async () => {
|
|
55
|
+
await uninstallTransportModule()
|
|
56
|
+
transport.end()
|
|
57
|
+
})
|
|
58
|
+
const instance = pino(transport)
|
|
59
|
+
instance.info('hello')
|
|
60
|
+
await watchFileCreated(destination)
|
|
61
|
+
const result = JSON.parse(await readFile(destination))
|
|
62
|
+
delete result.time
|
|
63
|
+
assert.deepEqual(result, {
|
|
64
|
+
pid,
|
|
65
|
+
hostname,
|
|
66
|
+
level: 30,
|
|
67
|
+
msg: 'hello'
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
// TODO make this test pass on Windows
|
|
72
|
+
test('pino.transport with package as a target', { skip: isWin }, async (t) => {
|
|
73
|
+
const destination = file()
|
|
74
|
+
|
|
75
|
+
await installTransportModule()
|
|
76
|
+
|
|
77
|
+
const transport = pino.transport({
|
|
78
|
+
targets: [{
|
|
79
|
+
target: 'transport',
|
|
80
|
+
options: { destination }
|
|
81
|
+
}]
|
|
82
|
+
})
|
|
83
|
+
t.after(async () => {
|
|
84
|
+
await uninstallTransportModule()
|
|
85
|
+
transport.end()
|
|
86
|
+
})
|
|
87
|
+
const instance = pino(transport)
|
|
88
|
+
instance.info('hello')
|
|
89
|
+
await watchFileCreated(destination)
|
|
90
|
+
const result = JSON.parse(await readFile(destination))
|
|
91
|
+
delete result.time
|
|
92
|
+
assert.deepEqual(result, {
|
|
93
|
+
pid,
|
|
94
|
+
hostname,
|
|
95
|
+
level: 30,
|
|
96
|
+
msg: 'hello'
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
// TODO make this test pass on Windows
|
|
101
|
+
test('pino({ transport })', { skip: isWin || isYarnPnp }, async (t) => {
|
|
102
|
+
const folder = join(
|
|
103
|
+
os.tmpdir(),
|
|
104
|
+
'_' + Math.random().toString(36).substr(2, 9)
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
t.after(() => {
|
|
108
|
+
rimraf.sync(folder)
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
const destination = join(folder, 'output')
|
|
112
|
+
|
|
113
|
+
await mkdir(join(folder, 'node_modules'), { recursive: true })
|
|
114
|
+
|
|
115
|
+
// Link pino
|
|
116
|
+
await symlink(
|
|
117
|
+
join(__dirname, '..', '..'),
|
|
118
|
+
join(folder, 'node_modules', 'pino')
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
await installTransportModule(folder)
|
|
122
|
+
|
|
123
|
+
const toRun = join(folder, 'index.js')
|
|
124
|
+
|
|
125
|
+
const toRunContent = `
|
|
126
|
+
const pino = require('pino')
|
|
127
|
+
const logger = pino({
|
|
128
|
+
transport: {
|
|
129
|
+
target: 'transport',
|
|
130
|
+
options: { destination: '${destination}' }
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
logger.info('hello')
|
|
134
|
+
`
|
|
135
|
+
|
|
136
|
+
await writeFile(toRun, toRunContent)
|
|
137
|
+
|
|
138
|
+
const child = execa(process.argv[0], [toRun])
|
|
139
|
+
|
|
140
|
+
await once(child, 'close')
|
|
141
|
+
|
|
142
|
+
const result = JSON.parse(await readFile(destination))
|
|
143
|
+
delete result.time
|
|
144
|
+
assert.deepEqual(result, {
|
|
145
|
+
pid: child.pid,
|
|
146
|
+
hostname,
|
|
147
|
+
level: 30,
|
|
148
|
+
msg: 'hello'
|
|
149
|
+
})
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
// TODO make this test pass on Windows
|
|
153
|
+
test('pino({ transport }) from a wrapped dependency', { skip: isWin || isYarnPnp }, async (t) => {
|
|
154
|
+
const folder = join(
|
|
155
|
+
os.tmpdir(),
|
|
156
|
+
'_' + Math.random().toString(36).substr(2, 9)
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
const wrappedFolder = join(
|
|
160
|
+
os.tmpdir(),
|
|
161
|
+
'_' + Math.random().toString(36).substr(2, 9)
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
const destination = join(folder, 'output')
|
|
165
|
+
|
|
166
|
+
await mkdir(join(folder, 'node_modules'), { recursive: true })
|
|
167
|
+
await mkdir(join(wrappedFolder, 'node_modules'), { recursive: true })
|
|
168
|
+
|
|
169
|
+
t.after(() => {
|
|
170
|
+
rimraf.sync(wrappedFolder)
|
|
171
|
+
rimraf.sync(folder)
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
// Link pino
|
|
175
|
+
await symlink(
|
|
176
|
+
join(__dirname, '..', '..'),
|
|
177
|
+
join(wrappedFolder, 'node_modules', 'pino')
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
// Link get-caller-file
|
|
181
|
+
await symlink(
|
|
182
|
+
join(__dirname, '..', '..', 'node_modules', 'get-caller-file'),
|
|
183
|
+
join(wrappedFolder, 'node_modules', 'get-caller-file')
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
// Link wrapped
|
|
187
|
+
await symlink(
|
|
188
|
+
wrappedFolder,
|
|
189
|
+
join(folder, 'node_modules', 'wrapped')
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
await installTransportModule(folder)
|
|
193
|
+
|
|
194
|
+
const pkgjsonContent = {
|
|
195
|
+
name: 'pino'
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
await writeFile(join(wrappedFolder, 'package.json'), JSON.stringify(pkgjsonContent))
|
|
199
|
+
|
|
200
|
+
const wrapped = join(wrappedFolder, 'index.js')
|
|
201
|
+
|
|
202
|
+
const wrappedContent = `
|
|
203
|
+
const pino = require('pino')
|
|
204
|
+
const getCaller = require('get-caller-file')
|
|
205
|
+
|
|
206
|
+
module.exports = function build () {
|
|
207
|
+
const logger = pino({
|
|
208
|
+
transport: {
|
|
209
|
+
caller: getCaller(),
|
|
210
|
+
target: 'transport',
|
|
211
|
+
options: { destination: '${destination}' }
|
|
212
|
+
}
|
|
213
|
+
})
|
|
214
|
+
return logger
|
|
215
|
+
}
|
|
216
|
+
`
|
|
217
|
+
|
|
218
|
+
await writeFile(wrapped, wrappedContent)
|
|
219
|
+
|
|
220
|
+
const toRun = join(folder, 'index.js')
|
|
221
|
+
|
|
222
|
+
const toRunContent = `
|
|
223
|
+
const logger = require('wrapped')()
|
|
224
|
+
logger.info('hello')
|
|
225
|
+
`
|
|
226
|
+
|
|
227
|
+
await writeFile(toRun, toRunContent)
|
|
228
|
+
|
|
229
|
+
const child = execa(process.argv[0], [toRun])
|
|
230
|
+
|
|
231
|
+
await once(child, 'close')
|
|
232
|
+
|
|
233
|
+
const result = JSON.parse(await readFile(destination))
|
|
234
|
+
delete result.time
|
|
235
|
+
assert.deepEqual(result, {
|
|
236
|
+
pid: child.pid,
|
|
237
|
+
hostname,
|
|
238
|
+
level: 30,
|
|
239
|
+
msg: 'hello'
|
|
240
|
+
})
|
|
241
|
+
})
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import test from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import * as os from 'node:os'
|
|
4
|
+
import { join } from 'node:path'
|
|
5
|
+
import fs from 'node:fs'
|
|
6
|
+
import * as url from 'node:url'
|
|
7
|
+
|
|
8
|
+
import { watchFileCreated } from '../helper.js'
|
|
9
|
+
|
|
10
|
+
const readFile = fs.promises.readFile
|
|
11
|
+
|
|
12
|
+
const { pid } = process
|
|
13
|
+
const hostname = os.hostname()
|
|
14
|
+
|
|
15
|
+
// Check if Node.js supports native type stripping (Node.js 22+)
|
|
16
|
+
function supportsTypeStripping () {
|
|
17
|
+
const major = parseInt(process.versions.node.split('.')[0], 10)
|
|
18
|
+
return major >= 22
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Only run these tests on Node.js 22+
|
|
22
|
+
const skipTests = !supportsTypeStripping()
|
|
23
|
+
const skipMessage = 'Native TypeScript type stripping not supported (requires Node.js 22+)'
|
|
24
|
+
|
|
25
|
+
test('pino.transport with native TypeScript file', { skip: skipTests ? skipMessage : false }, async (t) => {
|
|
26
|
+
const destination = join(
|
|
27
|
+
os.tmpdir(),
|
|
28
|
+
'_' + Math.random().toString(36).substr(2, 9)
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
// We need to dynamically import pino to ensure worker thread inherits flags
|
|
32
|
+
const { default: pino } = await import('../../pino.js')
|
|
33
|
+
|
|
34
|
+
const transport = pino.transport({
|
|
35
|
+
target: join(import.meta.dirname || url.fileURLToPath(new URL('.', import.meta.url)), '..', 'fixtures', 'ts', 'to-file-transport-native.mts'),
|
|
36
|
+
options: { destination }
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
t.after(() => {
|
|
40
|
+
transport.end()
|
|
41
|
+
try {
|
|
42
|
+
fs.unlinkSync(destination)
|
|
43
|
+
} catch {}
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const instance = pino(transport)
|
|
47
|
+
instance.info('hello from native TypeScript transport')
|
|
48
|
+
|
|
49
|
+
await watchFileCreated(destination)
|
|
50
|
+
const result = JSON.parse(await readFile(destination, { encoding: 'utf8' }))
|
|
51
|
+
delete result.time
|
|
52
|
+
|
|
53
|
+
assert.deepEqual(result, {
|
|
54
|
+
pid,
|
|
55
|
+
hostname,
|
|
56
|
+
level: 30,
|
|
57
|
+
msg: 'hello from native TypeScript transport'
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
test('pino.transport with native TypeScript file URL', { skip: skipTests ? skipMessage : false }, async (t) => {
|
|
62
|
+
const destination = join(
|
|
63
|
+
os.tmpdir(),
|
|
64
|
+
'_' + Math.random().toString(36).substr(2, 9)
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
const { default: pino } = await import('../../pino.js')
|
|
68
|
+
|
|
69
|
+
const transport = pino.transport({
|
|
70
|
+
target: url.pathToFileURL(join(import.meta.dirname || url.fileURLToPath(new URL('.', import.meta.url)), '..', 'fixtures', 'ts', 'to-file-transport-native.mts')).href,
|
|
71
|
+
options: { destination }
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
t.after(() => {
|
|
75
|
+
transport.end()
|
|
76
|
+
try {
|
|
77
|
+
fs.unlinkSync(destination)
|
|
78
|
+
} catch {}
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
const instance = pino(transport)
|
|
82
|
+
instance.info('hello from file URL transport')
|
|
83
|
+
|
|
84
|
+
await watchFileCreated(destination)
|
|
85
|
+
const result = JSON.parse(await readFile(destination, { encoding: 'utf8' }))
|
|
86
|
+
delete result.time
|
|
87
|
+
|
|
88
|
+
assert.deepEqual(result, {
|
|
89
|
+
pid,
|
|
90
|
+
hostname,
|
|
91
|
+
level: 30,
|
|
92
|
+
msg: 'hello from file URL transport'
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
test('pino.transport with multiple native TypeScript targets', { skip: skipTests ? skipMessage : false }, async (t) => {
|
|
97
|
+
const dest1 = join(
|
|
98
|
+
os.tmpdir(),
|
|
99
|
+
'_' + Math.random().toString(36).substr(2, 9)
|
|
100
|
+
)
|
|
101
|
+
const dest2 = join(
|
|
102
|
+
os.tmpdir(),
|
|
103
|
+
'_' + Math.random().toString(36).substr(2, 9)
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
const { default: pino } = await import('../../pino.js')
|
|
107
|
+
const fixtureDir = join(import.meta.dirname || url.fileURLToPath(new URL('.', import.meta.url)), '..', 'fixtures', 'ts')
|
|
108
|
+
|
|
109
|
+
const transport = pino.transport({
|
|
110
|
+
targets: [{
|
|
111
|
+
level: 'info',
|
|
112
|
+
target: join(fixtureDir, 'to-file-transport-native.mts'),
|
|
113
|
+
options: { destination: dest1 }
|
|
114
|
+
}, {
|
|
115
|
+
level: 'info',
|
|
116
|
+
target: join(fixtureDir, 'to-file-transport-native.mts'),
|
|
117
|
+
options: { destination: dest2 }
|
|
118
|
+
}]
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
t.after(() => {
|
|
122
|
+
transport.end()
|
|
123
|
+
try {
|
|
124
|
+
fs.unlinkSync(dest1)
|
|
125
|
+
fs.unlinkSync(dest2)
|
|
126
|
+
} catch {}
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
const instance = pino(transport)
|
|
130
|
+
instance.info('hello from multiple targets')
|
|
131
|
+
|
|
132
|
+
await Promise.all([watchFileCreated(dest1), watchFileCreated(dest2)])
|
|
133
|
+
|
|
134
|
+
const result1 = JSON.parse(await readFile(dest1, { encoding: 'utf8' }))
|
|
135
|
+
delete result1.time
|
|
136
|
+
assert.deepEqual(result1, {
|
|
137
|
+
pid,
|
|
138
|
+
hostname,
|
|
139
|
+
level: 30,
|
|
140
|
+
msg: 'hello from multiple targets'
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
const result2 = JSON.parse(await readFile(dest2, { encoding: 'utf8' }))
|
|
144
|
+
delete result2.time
|
|
145
|
+
assert.deepEqual(result2, {
|
|
146
|
+
pid,
|
|
147
|
+
hostname,
|
|
148
|
+
level: 30,
|
|
149
|
+
msg: 'hello from multiple targets'
|
|
150
|
+
})
|
|
151
|
+
})
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('node:test')
|
|
4
|
+
const assert = require('node:assert')
|
|
5
|
+
const { EventEmitter } = require('node:events')
|
|
6
|
+
const { join } = require('node:path')
|
|
7
|
+
const { pathToFileURL } = require('node:url')
|
|
8
|
+
const proxyquire = require('proxyquire')
|
|
9
|
+
|
|
10
|
+
function buildTransportWithFakeThreadStream () {
|
|
11
|
+
let lastCtorOpts
|
|
12
|
+
|
|
13
|
+
class FakeThreadStream extends EventEmitter {
|
|
14
|
+
constructor (opts) {
|
|
15
|
+
super()
|
|
16
|
+
this._closed = false
|
|
17
|
+
lastCtorOpts = opts
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
unref () {}
|
|
21
|
+
ref () {}
|
|
22
|
+
flushSync () {}
|
|
23
|
+
end () {
|
|
24
|
+
this._closed = true
|
|
25
|
+
this.emit('close')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get closed () {
|
|
29
|
+
return this._closed
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const transport = proxyquire('../../lib/transport', {
|
|
34
|
+
'thread-stream': FakeThreadStream
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
transport,
|
|
39
|
+
getLastCtorOpts () {
|
|
40
|
+
return lastCtorOpts
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
test('pino.transport sanitizes missing absolute preload in NODE_OPTIONS', () => {
|
|
46
|
+
const previous = process.env.NODE_OPTIONS
|
|
47
|
+
const missing = join(__dirname, '..', 'fixtures', 'missing-preload.js')
|
|
48
|
+
process.env.NODE_OPTIONS = `--require ${missing} --trace-warnings`
|
|
49
|
+
|
|
50
|
+
const { transport, getLastCtorOpts } = buildTransportWithFakeThreadStream()
|
|
51
|
+
transport({ target: join(__dirname, '..', 'fixtures', 'to-file-transport.js') })
|
|
52
|
+
|
|
53
|
+
assert.equal(getLastCtorOpts().workerOpts.env.NODE_OPTIONS, '--trace-warnings')
|
|
54
|
+
|
|
55
|
+
if (previous === undefined) {
|
|
56
|
+
delete process.env.NODE_OPTIONS
|
|
57
|
+
} else {
|
|
58
|
+
process.env.NODE_OPTIONS = previous
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
test('pino.transport sanitizes missing file:// preload in NODE_OPTIONS', () => {
|
|
63
|
+
const previous = process.env.NODE_OPTIONS
|
|
64
|
+
const missingFileUrl = pathToFileURL(join(__dirname, '..', 'fixtures', 'missing-import.mjs')).href
|
|
65
|
+
process.env.NODE_OPTIONS = `--import=${missingFileUrl}`
|
|
66
|
+
|
|
67
|
+
const { transport, getLastCtorOpts } = buildTransportWithFakeThreadStream()
|
|
68
|
+
transport({ target: join(__dirname, '..', 'fixtures', 'to-file-transport.js') })
|
|
69
|
+
|
|
70
|
+
assert.equal(getLastCtorOpts().workerOpts.env.NODE_OPTIONS, '')
|
|
71
|
+
|
|
72
|
+
if (previous === undefined) {
|
|
73
|
+
delete process.env.NODE_OPTIONS
|
|
74
|
+
} else {
|
|
75
|
+
process.env.NODE_OPTIONS = previous
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test('pino.transport keeps relative preload flags in NODE_OPTIONS', () => {
|
|
80
|
+
const previous = process.env.NODE_OPTIONS
|
|
81
|
+
process.env.NODE_OPTIONS = '--require ./relative-preload.js'
|
|
82
|
+
|
|
83
|
+
const { transport, getLastCtorOpts } = buildTransportWithFakeThreadStream()
|
|
84
|
+
transport({ target: join(__dirname, '..', 'fixtures', 'to-file-transport.js') })
|
|
85
|
+
|
|
86
|
+
assert.equal(getLastCtorOpts().workerOpts.env, undefined)
|
|
87
|
+
|
|
88
|
+
if (previous === undefined) {
|
|
89
|
+
delete process.env.NODE_OPTIONS
|
|
90
|
+
} else {
|
|
91
|
+
process.env.NODE_OPTIONS = previous
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test('pino.transport does not override explicit worker.env', () => {
|
|
96
|
+
const previous = process.env.NODE_OPTIONS
|
|
97
|
+
process.env.NODE_OPTIONS = `--require ${join(__dirname, '..', 'fixtures', 'missing-preload.js')}`
|
|
98
|
+
|
|
99
|
+
const explicitEnv = { NODE_OPTIONS: '--trace-warnings' }
|
|
100
|
+
|
|
101
|
+
const { transport, getLastCtorOpts } = buildTransportWithFakeThreadStream()
|
|
102
|
+
transport({
|
|
103
|
+
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
|
|
104
|
+
worker: {
|
|
105
|
+
env: explicitEnv
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
assert.equal(getLastCtorOpts().workerOpts.env, explicitEnv)
|
|
110
|
+
|
|
111
|
+
if (previous === undefined) {
|
|
112
|
+
delete process.env.NODE_OPTIONS
|
|
113
|
+
} else {
|
|
114
|
+
process.env.NODE_OPTIONS = previous
|
|
115
|
+
}
|
|
116
|
+
})
|