First commit

This commit is contained in:
2026-01-12 13:12:46 +01:00
parent b2d9501f6d
commit a1fbd8acf5
4413 changed files with 1245183 additions and 0 deletions

43
node_modules/pino/test/transport/big.test.js generated vendored Normal file
View File

@@ -0,0 +1,43 @@
'use strict'
const { test } = require('tap')
const { join } = require('node:path')
const { createReadStream } = require('node:fs')
const { promisify } = require('node:util')
const execa = require('execa')
const split = require('split2')
const stream = require('node:stream')
const { file } = require('../helper')
const pipeline = promisify(stream.pipeline)
const { Writable } = stream
const sleep = promisify(setTimeout)
const skip = process.env.CI || process.env.CITGM
test('eight million lines', { skip }, async ({ equal, comment }) => {
const destination = file()
await execa(process.argv[0], [join(__dirname, '..', 'fixtures', 'transport-many-lines.js'), destination])
if (process.platform !== 'win32') {
try {
await execa('sync') // Wait for the file to be written to disk
} catch {
// Just a fallback, this should be unreachable
}
}
await sleep(1000) // It seems that sync is not enough (even in POSIX systems)
const toWrite = 8 * 1000000
let count = 0
await pipeline(createReadStream(destination), split(), new Writable({
write (chunk, enc, cb) {
if (count % (toWrite / 10) === 0) {
comment(`read ${count}`)
}
count++
cb()
}
}))
equal(count, toWrite)
})

View File

@@ -0,0 +1,97 @@
'use strict'
const os = require('node:os')
const { join } = require('node:path')
const { readFile } = require('node:fs').promises
const { watchFileCreated, file } = require('../helper')
const { test } = require('tap')
const pino = require('../../pino')
const { pid } = process
const hostname = os.hostname()
test('pino.transport with destination overridden by bundler', async ({ same, teardown }) => {
globalThis.__bundlerPathsOverrides = {
foobar: join(__dirname, '..', 'fixtures', 'to-file-transport.js')
}
const destination = file()
const transport = pino.transport({
target: 'foobar',
options: { destination }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
globalThis.__bundlerPathsOverrides = undefined
})
test('pino.transport with worker destination overridden by bundler', async ({ same, teardown }) => {
globalThis.__bundlerPathsOverrides = {
'pino-worker': join(__dirname, '..', '..', 'lib/worker.js')
}
const destination = file()
const transport = pino.transport({
targets: [
{
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination }
}
]
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
globalThis.__bundlerPathsOverrides = undefined
})
test('pino.transport with worker destination overridden by bundler and mjs transport', async ({ same, teardown }) => {
globalThis.__bundlerPathsOverrides = {
'pino-worker': join(__dirname, '..', '..', 'lib/worker.js')
}
const destination = file()
const transport = pino.transport({
targets: [
{
target: join(__dirname, '..', 'fixtures', 'ts', 'to-file-transport.es2017.cjs'),
options: { destination }
}
]
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
globalThis.__bundlerPathsOverrides = undefined
})

23
node_modules/pino/test/transport/caller.test.js generated vendored Normal file
View File

@@ -0,0 +1,23 @@
'use strict'
const { join } = require('node:path')
const { test } = require('tap')
const execa = require('execa')
test('when using a custom transport outside node_modules, the first file outside node_modules should be used', async function (t) {
const evalApp = join(__dirname, '../', '/fixtures/eval/index.js')
const { stdout } = await execa(process.argv[0], [evalApp])
t.match(stdout, /done!/)
})
test('when using a custom transport where some files in stacktrace are in the node_modules, the first file outside node_modules should be used', async function (t) {
const evalApp = join(__dirname, '../', '/fixtures/eval/node_modules/2-files.js')
const { stdout } = await execa(process.argv[0], [evalApp])
t.match(stdout, /done!/)
})
test('when using a custom transport where all files in stacktrace are in the node_modules, the first file inside node_modules should be used', async function (t) {
const evalApp = join(__dirname, '../', '/fixtures/eval/node_modules/14-files.js')
const { stdout } = await execa(process.argv[0], [evalApp])
t.match(stdout, /done!/)
})

643
node_modules/pino/test/transport/core.test.js generated vendored Normal file
View File

@@ -0,0 +1,643 @@
'use strict'
const os = require('node:os')
const { join } = require('node:path')
const { once } = require('node:events')
const { setImmediate: immediate } = require('node:timers/promises')
const { readFile, writeFile } = require('node:fs').promises
const { watchFileCreated, watchForWrite, file } = require('../helper')
const { test } = require('tap')
const pino = require('../../')
const url = require('url')
const strip = require('strip-ansi')
const execa = require('execa')
const writer = require('flush-write-stream')
const rimraf = require('rimraf')
const { tmpdir } = os
const pid = process.pid
const hostname = os.hostname()
test('pino.transport with file', async ({ same, teardown }) => {
const destination = file()
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('pino.transport with file (no options + error handling)', async ({ equal }) => {
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js')
})
const [err] = await once(transport, 'error')
equal(err.message, 'kaboom')
})
test('pino.transport with file URL', async ({ same, teardown }) => {
const destination = file()
const transport = pino.transport({
target: url.pathToFileURL(join(__dirname, '..', 'fixtures', 'to-file-transport.js')).href,
options: { destination }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('pino.transport errors if file does not exists', ({ plan, pass }) => {
plan(1)
const instance = pino.transport({
target: join(__dirname, '..', 'fixtures', 'non-existent-file'),
worker: {
stdin: true,
stdout: true,
stderr: true
}
})
instance.on('error', function () {
pass('error received')
})
})
test('pino.transport errors if transport worker module does not export a function', ({ plan, equal }) => {
// TODO: add case for non-pipelined single target (needs changes in thread-stream)
plan(2)
const manyTargetsInstance = pino.transport({
targets: [{
level: 'info',
target: join(__dirname, '..', 'fixtures', 'transport-wrong-export-type.js')
}, {
level: 'info',
target: join(__dirname, '..', 'fixtures', 'transport-wrong-export-type.js')
}]
})
manyTargetsInstance.on('error', function (e) {
equal(e.message, 'exported worker is not a function')
})
const pipelinedInstance = pino.transport({
pipeline: [{
target: join(__dirname, '..', 'fixtures', 'transport-wrong-export-type.js')
}]
})
pipelinedInstance.on('error', function (e) {
equal(e.message, 'exported worker is not a function')
})
})
test('pino.transport with esm', async ({ same, teardown }) => {
const destination = file()
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'to-file-transport.mjs'),
options: { destination }
})
const instance = pino(transport)
teardown(transport.end.bind(transport))
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('pino.transport with two files', async ({ same, teardown }) => {
const dest1 = file()
const dest2 = file()
const transport = pino.transport({
targets: [{
level: 'info',
target: 'file://' + join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: dest1 }
}, {
level: 'info',
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: dest2 }
}]
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await Promise.all([watchFileCreated(dest1), watchFileCreated(dest2)])
const result1 = JSON.parse(await readFile(dest1))
delete result1.time
same(result1, {
pid,
hostname,
level: 30,
msg: 'hello'
})
const result2 = JSON.parse(await readFile(dest2))
delete result2.time
same(result2, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('pino.transport with two files and custom levels', async ({ same, teardown }) => {
const dest1 = file()
const dest2 = file()
const transport = pino.transport({
targets: [{
level: 'info',
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: dest1 }
}, {
level: 'foo',
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: dest2 }
}],
levels: { trace: 10, debug: 20, info: 30, warn: 40, error: 50, fatal: 60, foo: 25 }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await Promise.all([watchFileCreated(dest1), watchFileCreated(dest2)])
const result1 = JSON.parse(await readFile(dest1))
delete result1.time
same(result1, {
pid,
hostname,
level: 30,
msg: 'hello'
})
const result2 = JSON.parse(await readFile(dest2))
delete result2.time
same(result2, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('pino.transport without specifying default levels', async ({ same, teardown }) => {
const dest = file()
const transport = pino.transport({
targets: [{
level: 'foo',
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: dest }
}],
levels: { foo: 25 }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await Promise.all([watchFileCreated(dest)])
const result1 = JSON.parse(await readFile(dest))
delete result1.time
same(result1, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('pino.transport with two files and dedupe', async ({ same, teardown }) => {
const dest1 = file()
const dest2 = file()
const transport = pino.transport({
dedupe: true,
targets: [{
level: 'info',
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: dest1 }
}, {
level: 'error',
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: dest2 }
}]
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
instance.error('world')
await Promise.all([watchFileCreated(dest1), watchFileCreated(dest2)])
const result1 = JSON.parse(await readFile(dest1))
delete result1.time
same(result1, {
pid,
hostname,
level: 30,
msg: 'hello'
})
const result2 = JSON.parse(await readFile(dest2))
delete result2.time
same(result2, {
pid,
hostname,
level: 50,
msg: 'world'
})
})
test('pino.transport with an array including a pino-pretty destination', async ({ same, match, teardown }) => {
const dest1 = file()
const dest2 = file()
const transport = pino.transport({
targets: [{
level: 'info',
target: 'pino/file',
options: {
destination: dest1
}
}, {
level: 'info',
target: 'pino-pretty',
options: {
destination: dest2
}
}]
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await Promise.all([watchFileCreated(dest1), watchFileCreated(dest2)])
const result1 = JSON.parse(await readFile(dest1))
delete result1.time
same(result1, {
pid,
hostname,
level: 30,
msg: 'hello'
})
const actual = (await readFile(dest2)).toString()
match(strip(actual), /\[.*\] INFO.*hello/)
})
test('no transport.end()', async ({ same, teardown }) => {
const destination = file()
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination }
})
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('autoEnd = false', async ({ equal, same, teardown }) => {
const destination = file()
const count = process.listenerCount('exit')
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination },
worker: { autoEnd: false }
})
teardown(transport.end.bind(transport))
await once(transport, 'ready')
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
equal(count, process.listenerCount('exit'))
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('pino.transport with target and targets', async ({ fail, equal }) => {
try {
pino.transport({
target: '/a/file',
targets: [{
target: '/a/file'
}]
})
fail('must throw')
} catch (err) {
equal(err.message, 'only one of target or targets can be specified')
}
})
test('pino.transport with target pino/file', async ({ same, teardown }) => {
const destination = file()
const transport = pino.transport({
target: 'pino/file',
options: { destination }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('pino.transport with target pino/file and mkdir option', async ({ same, teardown }) => {
const folder = join(tmpdir(), `pino-${process.pid}-mkdir-transport-file`)
const destination = join(folder, 'log.txt')
teardown(() => {
try {
rimraf.sync(folder)
} catch (err) {
// ignore
}
})
const transport = pino.transport({
target: 'pino/file',
options: { destination, mkdir: true }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('pino.transport with target pino/file and append option', async ({ same, teardown }) => {
const destination = file()
await writeFile(destination, JSON.stringify({ pid, hostname, time: Date.now(), level: 30, msg: 'hello' }))
const transport = pino.transport({
target: 'pino/file',
options: { destination, append: false }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('goodbye')
await watchForWrite(destination, '"goodbye"')
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'goodbye'
})
})
test('pino.transport should error with unknown target', async ({ fail, equal }) => {
try {
pino.transport({
target: 'origin',
caller: 'unknown-file.js'
})
fail('must throw')
} catch (err) {
equal(err.message, 'unable to determine transport target for "origin"')
}
})
test('pino.transport with target pino-pretty', async ({ match, teardown }) => {
const destination = file()
const transport = pino.transport({
target: 'pino-pretty',
options: { destination }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const actual = await readFile(destination, 'utf8')
match(strip(actual), /\[.*\] INFO.*hello/)
})
test('sets worker data informing the transport that pino will send its config', ({ match, plan, teardown }) => {
plan(1)
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'transport-worker-data.js')
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
transport.once('workerData', (workerData) => {
match(workerData.workerData, { pinoWillSendConfig: true })
})
instance.info('hello')
})
test('sets worker data informing the transport that pino will send its config (frozen file)', ({ match, plan, teardown }) => {
plan(1)
const config = {
transport: {
target: join(__dirname, '..', 'fixtures', 'transport-worker-data.js'),
options: {}
}
}
Object.freeze(config)
Object.freeze(config.transport)
Object.freeze(config.transport.options)
const instance = pino(config)
const transport = instance[pino.symbols.streamSym]
teardown(transport.end.bind(transport))
transport.once('workerData', (workerData) => {
match(workerData.workerData, { pinoWillSendConfig: true })
})
instance.info('hello')
})
test('stdout in worker', async ({ not }) => {
let actual = ''
const child = execa(process.argv[0], [join(__dirname, '..', 'fixtures', 'transport-main.js')])
for await (const chunk of child.stdout) {
actual += chunk
}
not(strip(actual).match(/Hello/), null)
})
test('log and exit on ready', async ({ not }) => {
let actual = ''
const child = execa(process.argv[0], [join(__dirname, '..', 'fixtures', 'transport-exit-on-ready.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
await immediate()
not(strip(actual).match(/Hello/), null)
})
test('log and exit before ready', async ({ not }) => {
let actual = ''
const child = execa(process.argv[0], [join(__dirname, '..', 'fixtures', 'transport-exit-immediately.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
await immediate()
not(strip(actual).match(/Hello/), null)
})
test('log and exit before ready with async dest', async ({ not }) => {
const destination = file()
const child = execa(process.argv[0], [join(__dirname, '..', 'fixtures', 'transport-exit-immediately-with-async-dest.js'), destination])
await once(child, 'exit')
const actual = await readFile(destination, 'utf8')
not(strip(actual).match(/HELLO/), null)
not(strip(actual).match(/WORLD/), null)
})
test('string integer destination', async ({ not }) => {
let actual = ''
const child = execa(process.argv[0], [join(__dirname, '..', 'fixtures', 'transport-string-stdout.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
await immediate()
not(strip(actual).match(/Hello/), null)
})
test('pino transport options with target', async ({ teardown, same }) => {
const destination = file()
const instance = pino({
transport: {
target: 'pino/file',
options: { destination }
}
})
const transportStream = instance[pino.symbols.streamSym]
teardown(transportStream.end.bind(transportStream))
instance.info('transport option test')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'transport option test'
})
})
test('pino transport options with targets', async ({ teardown, same }) => {
const dest1 = file()
const dest2 = file()
const instance = pino({
transport: {
targets: [
{ target: 'pino/file', options: { destination: dest1 } },
{ target: 'pino/file', options: { destination: dest2 } }
]
}
})
const transportStream = instance[pino.symbols.streamSym]
teardown(transportStream.end.bind(transportStream))
instance.info('transport option test')
await Promise.all([watchFileCreated(dest1), watchFileCreated(dest2)])
const result1 = JSON.parse(await readFile(dest1))
delete result1.time
same(result1, {
pid,
hostname,
level: 30,
msg: 'transport option test'
})
const result2 = JSON.parse(await readFile(dest2))
delete result2.time
same(result2, {
pid,
hostname,
level: 30,
msg: 'transport option test'
})
})
test('transport options with target and targets', async ({ fail, equal }) => {
try {
pino({
transport: {
target: {},
targets: {}
}
})
fail('must throw')
} catch (err) {
equal(err.message, 'only one of target or targets can be specified')
}
})
test('transport options with target and stream', async ({ fail, equal }) => {
try {
pino({
transport: {
target: {}
}
}, '/log/null')
fail('must throw')
} catch (err) {
equal(err.message, 'only one of option.transport or stream can be specified')
}
})
test('transport options with stream', async ({ fail, equal, teardown }) => {
try {
const dest1 = file()
const transportStream = pino.transport({ target: 'pino/file', options: { destination: dest1 } })
teardown(transportStream.end.bind(transportStream))
pino({
transport: transportStream
})
fail('must throw')
} catch (err) {
equal(err.message, 'option.transport do not allow stream, please pass to option directly. e.g. pino(transport)')
}
})

236
node_modules/pino/test/transport/core.test.ts generated vendored Normal file
View File

@@ -0,0 +1,236 @@
import * as os from 'node:os'
import { join } from 'node:path'
import { once } from 'node:events'
import fs from 'node:fs'
import { watchFileCreated } from '../helper'
import { test } from 'tap'
import pino from '../../'
import * as url from 'node:url'
import { default as strip } from 'strip-ansi'
import execa from 'execa'
import writer from 'flush-write-stream'
if (process.platform === 'win32') {
// TODO: Implement .ts files loading support for Windows
process.exit()
}
const readFile = fs.promises.readFile
const { pid } = process
const hostname = os.hostname()
test('pino.transport with file', async ({ same, teardown }) => {
const destination = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'ts', 'to-file-transport.ts'),
options: { destination }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination, { encoding: 'utf8' }))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('pino.transport with file (no options + error handling)', async ({ equal }) => {
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'ts', 'to-file-transport.ts')
})
const [err] = await once(transport, 'error')
equal(err.message, 'kaboom')
})
test('pino.transport with file URL', async ({ same, teardown }) => {
const destination = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const transport = pino.transport({
target: url.pathToFileURL(join(__dirname, '..', 'fixtures', 'ts', 'to-file-transport.ts')).href,
options: { destination }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination, { encoding: 'utf8' }))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('pino.transport with two files', async ({ same, teardown }) => {
const dest1 = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const dest2 = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const transport = pino.transport({
targets: [{
level: 'info',
target: join(__dirname, '..', 'fixtures', 'ts', 'to-file-transport.ts'),
options: { destination: dest1 }
}, {
level: 'info',
target: join(__dirname, '..', 'fixtures', 'ts', 'to-file-transport.ts'),
options: { destination: dest2 }
}]
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await Promise.all([watchFileCreated(dest1), watchFileCreated(dest2)])
const result1 = JSON.parse(await readFile(dest1, { encoding: 'utf8' }))
delete result1.time
same(result1, {
pid,
hostname,
level: 30,
msg: 'hello'
})
const result2 = JSON.parse(await readFile(dest2, { encoding: 'utf8' }))
delete result2.time
same(result2, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('no transport.end()', async ({ same, teardown }) => {
const destination = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'ts', 'to-file-transport.ts'),
options: { destination }
})
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination, { encoding: 'utf8' }))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('autoEnd = false', async ({ equal, same, teardown }) => {
const destination = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const count = process.listenerCount('exit')
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'ts', 'to-file-transport.ts'),
options: { destination },
worker: { autoEnd: false }
})
teardown(transport.end.bind(transport))
await once(transport, 'ready')
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
equal(count, process.listenerCount('exit'))
const result = JSON.parse(await readFile(destination, { encoding: 'utf8' }))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('stdout in worker', async ({ not }) => {
let actual = ''
const child = execa(process.argv[0], ['-r', 'ts-node/register', join(__dirname, '..', 'fixtures', 'ts', 'transport-main.ts')])
child.stdout?.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
not(strip(actual).match(/Hello/), null)
})
test('log and exit on ready', async ({ not }) => {
let actual = ''
const child = execa(process.argv[0], ['-r', 'ts-node/register', join(__dirname, '..', 'fixtures', 'ts', 'transport-exit-on-ready.ts')])
child.stdout?.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
not(strip(actual).match(/Hello/), null)
})
test('log and exit before ready', async ({ not }) => {
let actual = ''
const child = execa(process.argv[0], ['-r', 'ts-node/register', join(__dirname, '..', 'fixtures', 'ts', 'transport-exit-immediately.ts')])
child.stdout?.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
not(strip(actual).match(/Hello/), null)
})
test('log and exit before ready with async dest', async ({ not }) => {
const destination = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const child = execa(process.argv[0], ['-r', 'ts-node/register', join(__dirname, '..', 'fixtures', 'ts', 'transport-exit-immediately-with-async-dest.ts'), destination])
await once(child, 'exit')
const actual = await readFile(destination, { encoding: 'utf8' })
not(strip(actual).match(/HELLO/), null)
not(strip(actual).match(/WORLD/), null)
})
test('string integer destination', async ({ not }) => {
let actual = ''
const child = execa(process.argv[0], ['-r', 'ts-node/register', join(__dirname, '..', 'fixtures', 'ts', 'transport-string-stdout.ts')])
child.stdout?.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
not(strip(actual).match(/Hello/), null)
})

View File

@@ -0,0 +1,112 @@
import * as os from 'node:os'
import { join } from 'node:path'
import fs from 'node:fs'
import { watchFileCreated } from '../helper'
import { test } from 'tap'
import pino from '../../'
import * as url from 'node:url'
const readFile = fs.promises.readFile
const { pid } = process
const hostname = os.hostname()
// A subset of the test from core.test.js, we don't need all of them to check for compatibility
function runTests(esVersion: string): void {
test(`(ts -> ${esVersion}) pino.transport with file`, async ({ same, teardown }) => {
const destination = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'ts', `to-file-transport.${esVersion}.cjs`),
options: { destination }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination, { encoding: 'utf8' }))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test(`(ts -> ${esVersion}) pino.transport with file URL`, async ({ same, teardown }) => {
const destination = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const transport = pino.transport({
target: url.pathToFileURL(join(__dirname, '..', 'fixtures', 'ts', `to-file-transport.${esVersion}.cjs`)).href,
options: { destination }
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination, { encoding: 'utf8' }))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test(`(ts -> ${esVersion}) pino.transport with two files`, async ({ same, teardown }) => {
const dest1 = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const dest2 = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const transport = pino.transport({
targets: [{
level: 'info',
target: join(__dirname, '..', 'fixtures', 'ts', `to-file-transport.${esVersion}.cjs`),
options: { destination: dest1 }
}, {
level: 'info',
target: join(__dirname, '..', 'fixtures', 'ts', `to-file-transport.${esVersion}.cjs`),
options: { destination: dest2 }
}]
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await Promise.all([watchFileCreated(dest1), watchFileCreated(dest2)])
const result1 = JSON.parse(await readFile(dest1, { encoding: 'utf8' }))
delete result1.time
same(result1, {
pid,
hostname,
level: 30,
msg: 'hello'
})
const result2 = JSON.parse(await readFile(dest2, { encoding: 'utf8' }))
delete result2.time
same(result2, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
}
runTests('es5')
runTests('es6')
runTests('es2017')
runTests('esnext')

34
node_modules/pino/test/transport/crash.test.js generated vendored Normal file
View File

@@ -0,0 +1,34 @@
'use strict'
const { join } = require('node:path')
const { once } = require('node:events')
const { setImmediate: immediate } = require('node:timers/promises')
const { test } = require('tap')
const pino = require('../../')
test('pino.transport emits error if the worker exits with 0 unexpectably', async ({ same, teardown, equal }) => {
// This test will take 10s, because flushSync waits for 10s
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'crashing-transport.js'),
sync: true
})
teardown(transport.end.bind(transport))
await once(transport, 'ready')
let maybeError
transport.on('error', (err) => {
maybeError = err
})
const logger = pino(transport)
for (let i = 0; i < 100000; i++) {
logger.info('hello')
}
await once(transport.worker, 'exit')
await immediate()
same(maybeError.message, 'the worker has exited')
})

239
node_modules/pino/test/transport/module-link.test.js generated vendored Normal file
View File

@@ -0,0 +1,239 @@
'use strict'
const os = require('node:os')
const { join } = require('node:path')
const { readFile, symlink, unlink, mkdir, writeFile } = require('node:fs').promises
const { test } = require('tap')
const { isWin, isYarnPnp, watchFileCreated, file } = require('../helper')
const { once } = require('node:events')
const execa = require('execa')
const pino = require('../../')
const rimraf = require('rimraf')
const { pid } = process
const hostname = os.hostname()
async function installTransportModule (target) {
if (isYarnPnp) {
return
}
try {
await uninstallTransportModule()
} catch {}
if (!target) {
target = join(__dirname, '..', '..')
}
await symlink(
join(__dirname, '..', 'fixtures', 'transport'),
join(target, 'node_modules', 'transport')
)
}
async function uninstallTransportModule () {
if (isYarnPnp) {
return
}
await unlink(join(__dirname, '..', '..', 'node_modules', 'transport'))
}
// TODO make this test pass on Windows
test('pino.transport with package', { skip: isWin }, async ({ same, teardown }) => {
const destination = file()
await installTransportModule()
const transport = pino.transport({
target: 'transport',
options: { destination }
})
teardown(async () => {
await uninstallTransportModule()
transport.end()
})
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
// TODO make this test pass on Windows
test('pino.transport with package as a target', { skip: isWin }, async ({ same, teardown }) => {
const destination = file()
await installTransportModule()
const transport = pino.transport({
targets: [{
target: 'transport',
options: { destination }
}]
})
teardown(async () => {
await uninstallTransportModule()
transport.end()
})
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
// TODO make this test pass on Windows
test('pino({ transport })', { skip: isWin || isYarnPnp }, async ({ same, teardown }) => {
const folder = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
teardown(() => {
rimraf.sync(folder)
})
const destination = join(folder, 'output')
await mkdir(join(folder, 'node_modules'), { recursive: true })
// Link pino
await symlink(
join(__dirname, '..', '..'),
join(folder, 'node_modules', 'pino')
)
await installTransportModule(folder)
const toRun = join(folder, 'index.js')
const toRunContent = `
const pino = require('pino')
const logger = pino({
transport: {
target: 'transport',
options: { destination: '${destination}' }
}
})
logger.info('hello')
`
await writeFile(toRun, toRunContent)
const child = execa(process.argv[0], [toRun])
await once(child, 'close')
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid: child.pid,
hostname,
level: 30,
msg: 'hello'
})
})
// TODO make this test pass on Windows
test('pino({ transport }) from a wrapped dependency', { skip: isWin || isYarnPnp }, async ({ same, teardown }) => {
const folder = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const wrappedFolder = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const destination = join(folder, 'output')
await mkdir(join(folder, 'node_modules'), { recursive: true })
await mkdir(join(wrappedFolder, 'node_modules'), { recursive: true })
teardown(() => {
rimraf.sync(wrappedFolder)
rimraf.sync(folder)
})
// Link pino
await symlink(
join(__dirname, '..', '..'),
join(wrappedFolder, 'node_modules', 'pino')
)
// Link get-caller-file
await symlink(
join(__dirname, '..', '..', 'node_modules', 'get-caller-file'),
join(wrappedFolder, 'node_modules', 'get-caller-file')
)
// Link wrapped
await symlink(
wrappedFolder,
join(folder, 'node_modules', 'wrapped')
)
await installTransportModule(folder)
const pkgjsonContent = {
name: 'pino'
}
await writeFile(join(wrappedFolder, 'package.json'), JSON.stringify(pkgjsonContent))
const wrapped = join(wrappedFolder, 'index.js')
const wrappedContent = `
const pino = require('pino')
const getCaller = require('get-caller-file')
module.exports = function build () {
const logger = pino({
transport: {
caller: getCaller(),
target: 'transport',
options: { destination: '${destination}' }
}
})
return logger
}
`
await writeFile(wrapped, wrappedContent)
const toRun = join(folder, 'index.js')
const toRunContent = `
const logger = require('wrapped')()
logger.info('hello')
`
await writeFile(toRun, toRunContent)
const child = execa(process.argv[0], [toRun])
await once(child, 'close')
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid: child.pid,
hostname,
level: 30,
msg: 'hello'
})
})

135
node_modules/pino/test/transport/pipeline.test.js generated vendored Normal file
View File

@@ -0,0 +1,135 @@
'use strict'
const os = require('node:os')
const { join } = require('node:path')
const { readFile } = require('node:fs').promises
const { watchFileCreated, file } = require('../helper')
const { test } = require('tap')
const pino = require('../../')
const { DEFAULT_LEVELS } = require('../../lib/constants')
const { pid } = process
const hostname = os.hostname()
test('pino.transport with a pipeline', async ({ same, teardown }) => {
const destination = file()
const transport = pino.transport({
pipeline: [{
target: join(__dirname, '..', 'fixtures', 'transport-transform.js')
}, {
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination }
}]
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: DEFAULT_LEVELS.info,
msg: 'hello',
service: 'pino' // this property was added by the transform
})
})
test('pino.transport with targets containing pipelines', async ({ same, teardown }) => {
const destinationA = file()
const destinationB = file()
const transport = pino.transport({
targets: [
{
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: destinationA }
},
{
pipeline: [
{
target: join(__dirname, '..', 'fixtures', 'transport-transform.js')
},
{
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: destinationB }
}
]
}
]
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello')
await watchFileCreated(destinationA)
await watchFileCreated(destinationB)
const resultA = JSON.parse(await readFile(destinationA))
const resultB = JSON.parse(await readFile(destinationB))
delete resultA.time
delete resultB.time
same(resultA, {
pid,
hostname,
level: DEFAULT_LEVELS.info,
msg: 'hello'
})
same(resultB, {
pid,
hostname,
level: DEFAULT_LEVELS.info,
msg: 'hello',
service: 'pino' // this property was added by the transform
})
})
test('pino.transport with targets containing pipelines with levels defined and dedupe', async ({ same, teardown }) => {
const destinationA = file()
const destinationB = file()
const transport = pino.transport({
targets: [
{
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: destinationA },
level: DEFAULT_LEVELS.info
},
{
pipeline: [
{
target: join(__dirname, '..', 'fixtures', 'transport-transform.js')
},
{
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: destinationB }
}
],
level: DEFAULT_LEVELS.error
}
],
dedupe: true
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
instance.info('hello info')
instance.error('hello error')
await watchFileCreated(destinationA)
await watchFileCreated(destinationB)
const resultA = JSON.parse(await readFile(destinationA))
const resultB = JSON.parse(await readFile(destinationB))
delete resultA.time
delete resultB.time
same(resultA, {
pid,
hostname,
level: DEFAULT_LEVELS.info,
msg: 'hello info'
})
same(resultB, {
pid,
hostname,
level: DEFAULT_LEVELS.error,
msg: 'hello error',
service: 'pino' // this property was added by the transform
})
})

14
node_modules/pino/test/transport/repl.test.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
'use strict'
const { doesNotThrow, test } = require('tap')
const proxyquire = require('proxyquire')
test('pino.transport resolves targets in REPL', async ({ same }) => {
// Arrange
const transport = proxyquire('../../lib/transport', {
'./caller': () => ['node:repl']
})
// Act / Assert
doesNotThrow(() => transport({ target: 'pino-pretty' }))
})

55
node_modules/pino/test/transport/syncTrue.test.js generated vendored Normal file
View File

@@ -0,0 +1,55 @@
'use strict'
const pino = require('../..')
const { join } = require('node:path')
const { readFileSync } = require('node:fs')
const { test } = require('tap')
const { file } = require('../helper')
test('thread-stream sync true should log synchronously', async (t) => {
const outputPath = file()
function getOutputLogLines () {
return (readFileSync(outputPath)).toString().trim().split('\n').map(JSON.parse)
}
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: outputPath, flush: true },
sync: true
})
const instance = pino(transport)
var value = { message: 'sync' }
instance.info(value)
instance.info(value)
instance.info(value)
instance.info(value)
instance.info(value)
instance.info(value)
let interrupt = false
let flushData
let loopCounter = 0
// Start a synchronous loop
while (!interrupt && loopCounter < (process.env.MAX_TEST_LOOP_ITERATION || 20000)) {
try {
loopCounter++
const data = getOutputLogLines()
flushData = data
if (data) {
interrupt = true
break
}
} catch (error) {
// File may not exist yet
// Wait till MAX_TEST_LOOP_ITERATION iterations
}
}
if (!interrupt) {
throw new Error('Sync loop did not get interrupt')
}
t.equal(flushData.length, 6)
})

68
node_modules/pino/test/transport/syncfalse.test.js generated vendored Normal file
View File

@@ -0,0 +1,68 @@
'use strict'
const os = require('node:os')
const pino = require('../..')
const { join } = require('node:path')
const { test } = require('tap')
const { readFile } = require('node:fs').promises
const { watchFileCreated, file } = require('../helper')
const { promisify } = require('node:util')
const { pid } = process
const hostname = os.hostname()
test('thread-stream async flush', async ({ equal, same }) => {
const destination = file()
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination }
})
const instance = pino(transport)
instance.info('hello')
equal(instance.flush(), undefined)
await watchFileCreated(destination)
const result = JSON.parse(await readFile(destination))
delete result.time
same(result, {
pid,
hostname,
level: 30,
msg: 'hello'
})
})
test('thread-stream async flush should call the passed callback', async (t) => {
const outputPath = file()
async function getOutputLogLines () {
return (await readFile(outputPath)).toString().trim().split('\n').map(JSON.parse)
}
const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: outputPath }
})
const instance = pino(transport)
const flushPromise = promisify(instance.flush).bind(instance)
instance.info('hello')
await flushPromise()
await watchFileCreated(outputPath)
const [firstFlushData] = await getOutputLogLines()
t.equal(firstFlushData.msg, 'hello')
// should not flush this as no data accumulated that's bigger than min length
instance.info('world')
// Making sure data is not flushed yet
const afterLogData = await getOutputLogLines()
t.equal(afterLogData.length, 1)
await flushPromise()
// Making sure data is not flushed yet
const afterSecondFlush = (await getOutputLogLines())[1]
t.equal(afterSecondFlush.msg, 'world')
})

44
node_modules/pino/test/transport/targets.test.js generated vendored Normal file
View File

@@ -0,0 +1,44 @@
'use strict'
const { test } = require('tap')
const { join } = require('node:path')
const proxyquire = require('proxyquire')
const Writable = require('node:stream').Writable
const pino = require('../../pino')
test('file-target mocked', async function ({ equal, same, plan, pass }) {
plan(1)
let ret
const fileTarget = proxyquire('../../file', {
'./pino': {
destination (opts) {
same(opts, { dest: 1, sync: false })
ret = new Writable()
ret.fd = opts.dest
process.nextTick(() => {
ret.emit('ready')
})
return ret
}
}
})
await fileTarget()
})
test('pino.transport with syntax error', ({ same, teardown, plan }) => {
plan(1)
const transport = pino.transport({
targets: [{
target: join(__dirname, '..', 'fixtures', 'syntax-error-esm.mjs')
}]
})
teardown(transport.end.bind(transport))
transport.on('error', (err) => {
same(err, new SyntaxError('Unexpected end of input'))
})
})

View File

@@ -0,0 +1,167 @@
'use strict'
const os = require('node:os')
const { join } = require('node:path')
const { readFile } = require('node:fs').promises
const writeStream = require('flush-write-stream')
const { watchFileCreated, file } = require('../helper')
const { test } = require('tap')
const pino = require('../../')
const { pid } = process
const hostname = os.hostname()
function serializeError (error) {
return {
type: error.name,
message: error.message,
stack: error.stack
}
}
function parseLogs (buffer) {
return JSON.parse(`[${buffer.toString().replace(/}{/g, '},{')}]`)
}
test('transport uses pino config', async ({ same, teardown, plan }) => {
plan(1)
const destination = file()
const transport = pino.transport({
pipeline: [{
target: join(__dirname, '..', 'fixtures', 'transport-uses-pino-config.js')
}, {
target: 'pino/file',
options: { destination }
}]
})
teardown(transport.end.bind(transport))
const instance = pino({
messageKey: 'customMessageKey',
errorKey: 'customErrorKey',
customLevels: { custom: 35 }
}, transport)
const error = new Error('bar')
instance.custom('foo')
instance.error(error)
await watchFileCreated(destination)
const result = parseLogs(await readFile(destination))
same(result, [{
severityText: 'custom',
body: 'foo',
attributes: {
pid,
hostname
}
}, {
severityText: 'error',
body: 'bar',
attributes: {
pid,
hostname
},
error: serializeError(error)
}])
})
test('transport uses pino config without customizations', async ({ same, teardown, plan }) => {
plan(1)
const destination = file()
const transport = pino.transport({
pipeline: [{
target: join(__dirname, '..', 'fixtures', 'transport-uses-pino-config.js')
}, {
target: 'pino/file',
options: { destination }
}]
})
teardown(transport.end.bind(transport))
const instance = pino(transport)
const error = new Error('qux')
instance.info('baz')
instance.error(error)
await watchFileCreated(destination)
const result = parseLogs(await readFile(destination))
same(result, [{
severityText: 'info',
body: 'baz',
attributes: {
pid,
hostname
}
}, {
severityText: 'error',
body: 'qux',
attributes: {
pid,
hostname
},
error: serializeError(error)
}])
})
test('transport uses pino config with multistream', async ({ same, teardown, plan }) => {
plan(2)
const destination = file()
const messages = []
const stream = writeStream(function (data, enc, cb) {
const message = JSON.parse(data)
delete message.time
messages.push(message)
cb()
})
const transport = pino.transport({
pipeline: [{
target: join(__dirname, '..', 'fixtures', 'transport-uses-pino-config.js')
}, {
target: 'pino/file',
options: { destination }
}]
})
teardown(transport.end.bind(transport))
const instance = pino({
messageKey: 'customMessageKey',
errorKey: 'customErrorKey',
customLevels: { custom: 35 }
}, pino.multistream([transport, { stream }]))
const error = new Error('buzz')
const serializedError = serializeError(error)
instance.custom('fizz')
instance.error(error)
await watchFileCreated(destination)
const result = parseLogs(await readFile(destination))
same(result, [{
severityText: 'custom',
body: 'fizz',
attributes: {
pid,
hostname
}
}, {
severityText: 'error',
body: 'buzz',
attributes: {
pid,
hostname
},
error: serializedError
}])
same(messages, [{
level: 35,
pid,
hostname,
customMessageKey: 'fizz'
}, {
level: 50,
pid,
hostname,
customErrorKey: serializedError,
customMessageKey: 'buzz'
}])
})