fastify 5.11.2 → 5.12.0
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/README.md +7 -7
- package/SPONSORS.md +1 -0
- package/docs/Guides/Serverless.md +34 -2
- package/docs/Reference/Encapsulation.md +31 -2
- package/docs/Reference/Errors.md +76 -3
- package/docs/Reference/Reply.md +14 -0
- package/docs/Reference/Request.md +18 -6
- package/docs/Reference/Routes.md +13 -0
- package/fastify.js +1 -1
- package/lib/content-type-parser.js +4 -0
- package/lib/content-type.js +4 -1
- package/lib/decorate.js +1 -1
- package/lib/log-controller.js +1 -1
- package/lib/reply.js +18 -4
- package/package.json +2 -3
- package/test/content-parser.test.js +48 -18
- package/test/content-type.test.js +4 -0
- package/test/decorator-instance-properties.test.js +49 -0
- package/test/helper.js +73 -1
- package/test/hooks-async.test.js +1 -2
- package/test/hooks.test.js +1 -2
- package/test/internals/reply.test.js +76 -1
- package/test/listen.1.test.js +17 -52
- package/test/listen.5.test.js +6 -9
- package/test/logger/instantiation.test.js +1 -1
- package/test/logger/logging.test.js +1 -1
- package/test/logger/request.test.js +1 -1
- package/test/logger/response.test.js +1 -1
- package/test/plugin.4.test.js +5 -4
- package/test/reply-media-type.test.js +131 -0
- package/test/reply-trailers.test.js +92 -4
- package/test/route-prefix.test.js +1 -1
- package/test/route.6.test.js +4 -11
- package/test/schema-feature.test.js +36 -65
- package/test/schema-serialization.test.js +1 -1
- package/test/schema-special-usage.test.js +1 -1
- package/test/schema-validation.test.js +1 -1
- package/test/stream.2.test.js +1 -1
- package/types/logger.d.ts +1 -1
- package/.pi/bash-confirm-whitelist.json +0 -180
- package/test/toolkit.js +0 -63
|
@@ -142,6 +142,37 @@ test('send trailers when payload is stream', (t, testDone) => {
|
|
|
142
142
|
})
|
|
143
143
|
})
|
|
144
144
|
|
|
145
|
+
test('remove trailer while stream is being consumed', (t, testDone) => {
|
|
146
|
+
t.plan(5)
|
|
147
|
+
|
|
148
|
+
const fastify = Fastify()
|
|
149
|
+
|
|
150
|
+
fastify.get('/', function (request, reply) {
|
|
151
|
+
const stream = Readable.from((function * () {
|
|
152
|
+
reply.removeTrailer('ETag')
|
|
153
|
+
yield 'hello'
|
|
154
|
+
})())
|
|
155
|
+
|
|
156
|
+
reply.trailer('ETag', function () {
|
|
157
|
+
t.assert.fail('removed trailer should not be called')
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
reply.send(stream)
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
fastify.inject({
|
|
164
|
+
method: 'GET',
|
|
165
|
+
url: '/'
|
|
166
|
+
}, (error, res) => {
|
|
167
|
+
t.assert.ifError(error)
|
|
168
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
169
|
+
t.assert.strictEqual(res.payload, 'hello')
|
|
170
|
+
t.assert.strictEqual(res.headers.trailer, 'etag')
|
|
171
|
+
t.assert.strictEqual(res.trailers.etag, undefined)
|
|
172
|
+
testDone()
|
|
173
|
+
})
|
|
174
|
+
})
|
|
175
|
+
|
|
145
176
|
test('send trailers when using async-await', (t, testDone) => {
|
|
146
177
|
t.plan(5)
|
|
147
178
|
|
|
@@ -395,10 +426,67 @@ test('remove all trailers', (t, testDone) => {
|
|
|
395
426
|
}, (error, res) => {
|
|
396
427
|
t.assert.ifError(error)
|
|
397
428
|
t.assert.strictEqual(res.statusCode, 200)
|
|
398
|
-
t.assert.
|
|
399
|
-
t.assert.
|
|
400
|
-
t.assert.
|
|
401
|
-
t.assert.
|
|
429
|
+
t.assert.strictEqual(res.headers.trailer, undefined)
|
|
430
|
+
t.assert.strictEqual(res.trailers.etag, undefined)
|
|
431
|
+
t.assert.strictEqual(res.trailers['should-not-call'], undefined)
|
|
432
|
+
t.assert.strictEqual(res.headers['content-length'], '0')
|
|
433
|
+
testDone()
|
|
434
|
+
})
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
test('remove some trailers should keep trailer mode for the remaining ones', (t, testDone) => {
|
|
438
|
+
t.plan(6)
|
|
439
|
+
|
|
440
|
+
const fastify = Fastify()
|
|
441
|
+
|
|
442
|
+
fastify.get('/', function (request, reply) {
|
|
443
|
+
reply.trailer('ETag', function () {
|
|
444
|
+
t.assert.fail('removed trailer should not be called')
|
|
445
|
+
})
|
|
446
|
+
reply.removeTrailer('ETag')
|
|
447
|
+
reply.trailer('Content-MD5', function (reply, payload, done) {
|
|
448
|
+
done(null, 'custom-md5')
|
|
449
|
+
})
|
|
450
|
+
reply.send('hello')
|
|
451
|
+
})
|
|
452
|
+
|
|
453
|
+
fastify.inject({
|
|
454
|
+
method: 'GET',
|
|
455
|
+
url: '/'
|
|
456
|
+
}, (error, res) => {
|
|
457
|
+
t.assert.ifError(error)
|
|
458
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
459
|
+
t.assert.strictEqual(res.headers.trailer, 'content-md5')
|
|
460
|
+
t.assert.strictEqual(res.headers['transfer-encoding'], 'chunked')
|
|
461
|
+
t.assert.strictEqual(res.headers['content-length'], undefined)
|
|
462
|
+
t.assert.strictEqual(res.trailers['content-md5'], 'custom-md5')
|
|
463
|
+
testDone()
|
|
464
|
+
})
|
|
465
|
+
})
|
|
466
|
+
|
|
467
|
+
test('remove all trailers should behave like no trailers were registered', (t, testDone) => {
|
|
468
|
+
t.plan(6)
|
|
469
|
+
|
|
470
|
+
const fastify = Fastify()
|
|
471
|
+
|
|
472
|
+
fastify.get('/', function (request, reply) {
|
|
473
|
+
reply.trailer('ETag', function () {
|
|
474
|
+
t.assert.fail('removed trailer should not be called')
|
|
475
|
+
})
|
|
476
|
+
reply.removeTrailer('ETag')
|
|
477
|
+
reply.send('hello')
|
|
478
|
+
})
|
|
479
|
+
|
|
480
|
+
fastify.inject({
|
|
481
|
+
method: 'GET',
|
|
482
|
+
url: '/'
|
|
483
|
+
}, (error, res) => {
|
|
484
|
+
t.assert.ifError(error)
|
|
485
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
486
|
+
t.assert.strictEqual(res.headers.trailer, undefined)
|
|
487
|
+
t.assert.strictEqual(res.headers['transfer-encoding'], undefined)
|
|
488
|
+
t.assert.strictEqual(res.headers['content-length'], '5')
|
|
489
|
+
t.assert.strictEqual(res.trailers.etag, undefined)
|
|
402
490
|
testDone()
|
|
403
491
|
})
|
|
404
492
|
})
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
4
|
const Fastify = require('..')
|
|
5
|
-
const { waitForCb } = require('./
|
|
5
|
+
const { waitForCb } = require('./helper')
|
|
6
6
|
|
|
7
7
|
test('Prefix options should add a prefix for all the routes inside a register / 1', (t, testDone) => {
|
|
8
8
|
t.plan(6)
|
package/test/route.6.test.js
CHANGED
|
@@ -4,6 +4,7 @@ const stream = require('node:stream')
|
|
|
4
4
|
const { ReadableStream } = require('node:stream/web')
|
|
5
5
|
const { test } = require('node:test')
|
|
6
6
|
const Fastify = require('..')
|
|
7
|
+
const { assertNoWarning } = require('./helper')
|
|
7
8
|
|
|
8
9
|
test('Creates a HEAD route for a GET one with prefixTrailingSlash', async (t) => {
|
|
9
10
|
t.plan(1)
|
|
@@ -281,6 +282,8 @@ test('route onSend can be function or array of functions', async t => {
|
|
|
281
282
|
})
|
|
282
283
|
|
|
283
284
|
test('no warning for exposeHeadRoute', async t => {
|
|
285
|
+
assertNoWarning(t)
|
|
286
|
+
|
|
284
287
|
const fastify = Fastify()
|
|
285
288
|
|
|
286
289
|
fastify.route({
|
|
@@ -292,15 +295,5 @@ test('no warning for exposeHeadRoute', async t => {
|
|
|
292
295
|
}
|
|
293
296
|
})
|
|
294
297
|
|
|
295
|
-
|
|
296
|
-
t.assert.fail('no warning')
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
process.on('warning', listener)
|
|
300
|
-
|
|
301
|
-
await fastify.listen({ port: 0 })
|
|
302
|
-
|
|
303
|
-
process.removeListener('warning', listener)
|
|
304
|
-
|
|
305
|
-
await fastify.close()
|
|
298
|
+
await fastify.ready()
|
|
306
299
|
})
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
|
-
const Fastify = require('..')
|
|
5
4
|
const fp = require('fastify-plugin')
|
|
5
|
+
const { spyWarning } = require('process-warning')
|
|
6
|
+
const Fastify = require('..')
|
|
6
7
|
const deepClone = require('rfdc')({ circles: true, proto: false })
|
|
7
8
|
const Ajv = require('ajv')
|
|
8
9
|
const { kSchemaController } = require('../lib/symbols.js')
|
|
9
10
|
const { FSTWRN001 } = require('../lib/warnings')
|
|
10
|
-
const { waitForCb } = require('./
|
|
11
|
+
const { waitForCb } = require('./helper')
|
|
11
12
|
|
|
12
13
|
const echoParams = (req, reply) => { reply.send(req.params) }
|
|
13
14
|
const echoBody = (req, reply) => { reply.send(req.body) }
|
|
@@ -320,18 +321,10 @@ test('Should not change the input schemas', (t, testDone) => {
|
|
|
320
321
|
|
|
321
322
|
test('Should emit warning if the schema headers is undefined', (t, testDone) => {
|
|
322
323
|
t.plan(4)
|
|
323
|
-
const
|
|
324
|
+
const spyData = spyWarning(FSTWRN001)
|
|
325
|
+
t.after(spyData.restore)
|
|
324
326
|
|
|
325
|
-
|
|
326
|
-
function onWarning (warning) {
|
|
327
|
-
t.assert.strictEqual(warning.name, 'FastifyWarning')
|
|
328
|
-
t.assert.strictEqual(warning.code, FSTWRN001.code)
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
t.after(() => {
|
|
332
|
-
process.removeListener('warning', onWarning)
|
|
333
|
-
FSTWRN001.emitted = false
|
|
334
|
-
})
|
|
327
|
+
const fastify = Fastify()
|
|
335
328
|
|
|
336
329
|
fastify.post('/:id', {
|
|
337
330
|
handler: echoParams,
|
|
@@ -346,24 +339,18 @@ test('Should emit warning if the schema headers is undefined', (t, testDone) =>
|
|
|
346
339
|
}, (error, res) => {
|
|
347
340
|
t.assert.ifError(error)
|
|
348
341
|
t.assert.strictEqual(res.statusCode, 200)
|
|
342
|
+
t.assert.deepStrictEqual(spyData.calls, [{ arguments: ['headers', 'POST', '/:id'], result: true }])
|
|
343
|
+
t.assert.strictEqual(spyData.callCount(), 1)
|
|
349
344
|
testDone()
|
|
350
345
|
})
|
|
351
346
|
})
|
|
352
347
|
|
|
353
348
|
test('Should emit warning if the schema body is undefined', (t, testDone) => {
|
|
354
349
|
t.plan(4)
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
process.on('warning', onWarning)
|
|
358
|
-
function onWarning (warning) {
|
|
359
|
-
t.assert.strictEqual(warning.name, 'FastifyWarning')
|
|
360
|
-
t.assert.strictEqual(warning.code, FSTWRN001.code)
|
|
361
|
-
}
|
|
350
|
+
const spyData = spyWarning(FSTWRN001)
|
|
351
|
+
t.after(spyData.restore)
|
|
362
352
|
|
|
363
|
-
|
|
364
|
-
process.removeListener('warning', onWarning)
|
|
365
|
-
FSTWRN001.emitted = false
|
|
366
|
-
})
|
|
353
|
+
const fastify = Fastify()
|
|
367
354
|
|
|
368
355
|
fastify.post('/:id', {
|
|
369
356
|
handler: echoParams,
|
|
@@ -378,24 +365,18 @@ test('Should emit warning if the schema body is undefined', (t, testDone) => {
|
|
|
378
365
|
}, (error, res) => {
|
|
379
366
|
t.assert.ifError(error)
|
|
380
367
|
t.assert.strictEqual(res.statusCode, 200)
|
|
368
|
+
t.assert.deepStrictEqual(spyData.calls, [{ arguments: ['body', 'POST', '/:id'], result: true }])
|
|
369
|
+
t.assert.strictEqual(spyData.callCount(), 1)
|
|
381
370
|
testDone()
|
|
382
371
|
})
|
|
383
372
|
})
|
|
384
373
|
|
|
385
374
|
test('Should emit warning if the schema query is undefined', (t, testDone) => {
|
|
386
375
|
t.plan(4)
|
|
387
|
-
const
|
|
376
|
+
const spyData = spyWarning(FSTWRN001)
|
|
377
|
+
t.after(spyData.restore)
|
|
388
378
|
|
|
389
|
-
|
|
390
|
-
function onWarning (warning) {
|
|
391
|
-
t.assert.strictEqual(warning.name, 'FastifyWarning')
|
|
392
|
-
t.assert.strictEqual(warning.code, FSTWRN001.code)
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
t.after(() => {
|
|
396
|
-
process.removeListener('warning', onWarning)
|
|
397
|
-
FSTWRN001.emitted = false
|
|
398
|
-
})
|
|
379
|
+
const fastify = Fastify()
|
|
399
380
|
|
|
400
381
|
fastify.post('/:id', {
|
|
401
382
|
handler: echoParams,
|
|
@@ -410,24 +391,18 @@ test('Should emit warning if the schema query is undefined', (t, testDone) => {
|
|
|
410
391
|
}, (error, res) => {
|
|
411
392
|
t.assert.ifError(error)
|
|
412
393
|
t.assert.strictEqual(res.statusCode, 200)
|
|
394
|
+
t.assert.deepStrictEqual(spyData.calls, [{ arguments: ['querystring', 'POST', '/:id'], result: true }])
|
|
395
|
+
t.assert.strictEqual(spyData.callCount(), 1)
|
|
413
396
|
testDone()
|
|
414
397
|
})
|
|
415
398
|
})
|
|
416
399
|
|
|
417
400
|
test('Should emit warning if the schema params is undefined', (t, testDone) => {
|
|
418
401
|
t.plan(4)
|
|
419
|
-
const
|
|
402
|
+
const spyData = spyWarning(FSTWRN001)
|
|
403
|
+
t.after(spyData.restore)
|
|
420
404
|
|
|
421
|
-
|
|
422
|
-
function onWarning (warning) {
|
|
423
|
-
t.assert.strictEqual(warning.name, 'FastifyWarning')
|
|
424
|
-
t.assert.strictEqual(warning.code, FSTWRN001.code)
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
t.after(() => {
|
|
428
|
-
process.removeListener('warning', onWarning)
|
|
429
|
-
FSTWRN001.emitted = false
|
|
430
|
-
})
|
|
405
|
+
const fastify = Fastify()
|
|
431
406
|
|
|
432
407
|
fastify.post('/:id', {
|
|
433
408
|
handler: echoParams,
|
|
@@ -442,31 +417,18 @@ test('Should emit warning if the schema params is undefined', (t, testDone) => {
|
|
|
442
417
|
}, (error, res) => {
|
|
443
418
|
t.assert.ifError(error)
|
|
444
419
|
t.assert.strictEqual(res.statusCode, 200)
|
|
420
|
+
t.assert.deepStrictEqual(spyData.calls, [{ arguments: ['params', 'POST', '/:id'], result: true }])
|
|
421
|
+
t.assert.strictEqual(spyData.callCount(), 1)
|
|
445
422
|
testDone()
|
|
446
423
|
})
|
|
447
424
|
})
|
|
448
425
|
|
|
449
426
|
test('Should emit a warning for every route with undefined schema', (t, testDone) => {
|
|
450
|
-
t.plan(
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
let runs = 0
|
|
454
|
-
const expectedWarningEmitted = [0, 1, 2, 3]
|
|
455
|
-
// It emits 4 warnings:
|
|
456
|
-
// - 2 - GET and HEAD for /undefinedParams/:id
|
|
457
|
-
// - 2 - GET and HEAD for /undefinedBody/:id
|
|
458
|
-
// => 3 x 4 assertions = 12 assertions
|
|
459
|
-
function onWarning (warning) {
|
|
460
|
-
t.assert.strictEqual(warning.name, 'FastifyWarning')
|
|
461
|
-
t.assert.strictEqual(warning.code, FSTWRN001.code)
|
|
462
|
-
t.assert.strictEqual(runs++, expectedWarningEmitted.shift())
|
|
463
|
-
}
|
|
427
|
+
t.plan(9)
|
|
428
|
+
const spyData = spyWarning(FSTWRN001)
|
|
429
|
+
t.after(spyData.restore)
|
|
464
430
|
|
|
465
|
-
|
|
466
|
-
t.after(() => {
|
|
467
|
-
process.removeListener('warning', onWarning)
|
|
468
|
-
FSTWRN001.emitted = false
|
|
469
|
-
})
|
|
431
|
+
const fastify = Fastify()
|
|
470
432
|
|
|
471
433
|
fastify.get('/undefinedParams/:id', {
|
|
472
434
|
handler: echoParams,
|
|
@@ -496,6 +458,15 @@ test('Should emit a warning for every route with undefined schema', (t, testDone
|
|
|
496
458
|
}, (error, res) => {
|
|
497
459
|
t.assert.ifError(error)
|
|
498
460
|
t.assert.strictEqual(res.statusCode, 200)
|
|
461
|
+
// fastify.inject run in series
|
|
462
|
+
// last callback recieve all warnings at once
|
|
463
|
+
// GET /undefinedParams/123
|
|
464
|
+
t.assert.deepStrictEqual(spyData.calls[0], { arguments: ['params', 'GET', '/undefinedParams/:id'], result: true })
|
|
465
|
+
t.assert.deepStrictEqual(spyData.calls[1], { arguments: ['params', 'HEAD', '/undefinedParams/:id'], result: true })
|
|
466
|
+
// GET /undefinedBody/123
|
|
467
|
+
t.assert.deepStrictEqual(spyData.calls[2], { arguments: ['body', 'GET', '/undefinedBody/:id'], result: true })
|
|
468
|
+
t.assert.deepStrictEqual(spyData.calls[3], { arguments: ['body', 'HEAD', '/undefinedBody/:id'], result: true })
|
|
469
|
+
t.assert.strictEqual(spyData.callCount(), 4)
|
|
499
470
|
testDone()
|
|
500
471
|
})
|
|
501
472
|
})
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
4
|
const Fastify = require('..')
|
|
5
5
|
const ContentType = require('../lib/content-type')
|
|
6
|
-
const { waitForCb } = require('./
|
|
6
|
+
const { waitForCb } = require('./helper')
|
|
7
7
|
|
|
8
8
|
const echoBody = (req, reply) => { reply.send(req.body) }
|
|
9
9
|
|
|
@@ -9,7 +9,7 @@ const Fastify = require('..')
|
|
|
9
9
|
const ajvMergePatch = require('ajv-merge-patch')
|
|
10
10
|
const ajvErrors = require('ajv-errors')
|
|
11
11
|
const proxyquire = require('proxyquire')
|
|
12
|
-
const { waitForCb } = require('./
|
|
12
|
+
const { waitForCb } = require('./helper')
|
|
13
13
|
|
|
14
14
|
test('Ajv plugins array parameter', (t, testDone) => {
|
|
15
15
|
t.plan(3)
|
|
@@ -5,7 +5,7 @@ const Fastify = require('..')
|
|
|
5
5
|
|
|
6
6
|
const AJV = require('ajv')
|
|
7
7
|
const Schema = require('fluent-json-schema')
|
|
8
|
-
const { waitForCb } = require('./
|
|
8
|
+
const { waitForCb } = require('./helper')
|
|
9
9
|
const { kRequestContentType } = require('../lib/symbols')
|
|
10
10
|
|
|
11
11
|
const customSchemaCompilers = {
|
package/test/stream.2.test.js
CHANGED
|
@@ -7,7 +7,7 @@ const resolve = require('node:path').resolve
|
|
|
7
7
|
const zlib = require('node:zlib')
|
|
8
8
|
const pipeline = require('node:stream').pipeline
|
|
9
9
|
const Fastify = require('..')
|
|
10
|
-
const { waitForCb } = require('./
|
|
10
|
+
const { waitForCb } = require('./helper')
|
|
11
11
|
|
|
12
12
|
test('onSend hook stream', t => {
|
|
13
13
|
t.plan(4)
|
package/types/logger.d.ts
CHANGED
|
@@ -124,7 +124,7 @@ export declare class LogController {
|
|
|
124
124
|
isLogDisabled (request: FastifyRequest): boolean
|
|
125
125
|
incomingRequest (request: FastifyRequest, reply: FastifyReply, metadata?: Record<string, unknown>): void
|
|
126
126
|
requestCompleted (
|
|
127
|
-
error: Error | null,
|
|
127
|
+
error: Error | null | undefined,
|
|
128
128
|
request: FastifyRequest,
|
|
129
129
|
reply: FastifyReply,
|
|
130
130
|
metadata?: Record<string, unknown>
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"entries": [
|
|
3
|
-
{
|
|
4
|
-
"type": "exact",
|
|
5
|
-
"value": "git fetch --all --prune --quiet && echo FETCH_OK || echo FETCH_FAILED",
|
|
6
|
-
"addedAt": "2026-02-07T10:03:03.909Z",
|
|
7
|
-
"note": "Always accept",
|
|
8
|
-
"source": "user"
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
"type": "exact",
|
|
12
|
-
"value": "npm install --ignore-scripts",
|
|
13
|
-
"addedAt": "2026-02-07T10:21:13.104Z",
|
|
14
|
-
"note": "Always accept",
|
|
15
|
-
"source": "user"
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
"type": "exact",
|
|
19
|
-
"value": "npm run coverage:ci-check-coverage",
|
|
20
|
-
"addedAt": "2026-02-07T15:10:08.412Z",
|
|
21
|
-
"note": "Always accept",
|
|
22
|
-
"source": "user"
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"type": "exact",
|
|
26
|
-
"value": "node --test test/web-api.test.js",
|
|
27
|
-
"addedAt": "2026-02-07T15:24:46.872Z",
|
|
28
|
-
"note": "Always accept",
|
|
29
|
-
"source": "user"
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
"type": "exact",
|
|
33
|
-
"value": "gpg --list-secret-keys --keyid-format=long || true && git config --get user.signingkey && git config --get commit.gpgsign",
|
|
34
|
-
"addedAt": "2026-02-11T04:42:44.716Z",
|
|
35
|
-
"note": "Always accept",
|
|
36
|
-
"source": "user"
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"type": "exact",
|
|
40
|
-
"value": "cd /home/matteo/repositories/fastify && npm run test:typescript",
|
|
41
|
-
"addedAt": "2026-02-19T20:22:59.298Z",
|
|
42
|
-
"note": "Always accept",
|
|
43
|
-
"source": "user"
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"type": "exact",
|
|
47
|
-
"value": "cd /home/matteo/repositories/fastify && git checkout -- types/route.d.ts",
|
|
48
|
-
"addedAt": "2026-02-19T20:23:45.912Z",
|
|
49
|
-
"note": "Always accept",
|
|
50
|
-
"source": "user"
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"type": "exact",
|
|
54
|
-
"value": "cd /home/matteo/repositories/fastify && git status --short && git diff -- types/route.d.ts test/types/route.test-d.ts | sed -n '1,220p'",
|
|
55
|
-
"addedAt": "2026-02-19T20:25:10.175Z",
|
|
56
|
-
"note": "Always accept",
|
|
57
|
-
"source": "user"
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
"type": "exact",
|
|
61
|
-
"value": "cd /home/matteo/repositories/fastify && git checkout -- types/route.d.ts test/types/route.test-d.ts && npm run test:typescript",
|
|
62
|
-
"addedAt": "2026-02-19T20:25:56.421Z",
|
|
63
|
-
"note": "Always accept",
|
|
64
|
-
"source": "user"
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"type": "exact",
|
|
68
|
-
"value": "cd /home/matteo/repositories/fastify && npm run lint:eslint -- types/route.d.ts test/types/route.test-d.ts",
|
|
69
|
-
"addedAt": "2026-02-19T20:27:12.547Z",
|
|
70
|
-
"note": "Always accept",
|
|
71
|
-
"source": "user"
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
"type": "exact",
|
|
75
|
-
"value": "cd /home/matteo/repositories/fastify && git checkout -b fix/6513-route-hook-meta-return",
|
|
76
|
-
"addedAt": "2026-02-19T20:27:31.569Z",
|
|
77
|
-
"note": "Always accept",
|
|
78
|
-
"source": "user"
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
"type": "exact",
|
|
82
|
-
"value": "cd /home/matteo/repositories/fastify && git add types/route.d.ts test/types/route.test-d.ts && git commit -m \"fix(types): allow async route hooks in shorthand options\"",
|
|
83
|
-
"addedAt": "2026-02-19T20:27:35.261Z",
|
|
84
|
-
"note": "Always accept",
|
|
85
|
-
"source": "user"
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
"type": "exact",
|
|
89
|
-
"value": "cd /home/matteo/repositories/fastify && npx tsc /tmp/ctx-test2.ts --noEmit --strict",
|
|
90
|
-
"addedAt": "2026-02-19T20:44:45.451Z",
|
|
91
|
-
"note": "Always accept",
|
|
92
|
-
"source": "user"
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
"type": "exact",
|
|
96
|
-
"value": "cd /home/matteo/repositories/fastify && npx tsd --files test/types/hooks.test-d.ts",
|
|
97
|
-
"addedAt": "2026-02-19T20:47:16.815Z",
|
|
98
|
-
"note": "Always accept",
|
|
99
|
-
"source": "user"
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
"type": "exact",
|
|
103
|
-
"value": "cd /home/matteo/repositories/fastify && npx tsd --files test/types/route.test-d.ts",
|
|
104
|
-
"addedAt": "2026-02-19T20:47:37.607Z",
|
|
105
|
-
"note": "Always accept",
|
|
106
|
-
"source": "user"
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
"type": "exact",
|
|
110
|
-
"value": "cd /home/matteo/repositories/fastify && npx tsd",
|
|
111
|
-
"addedAt": "2026-02-19T20:48:17.812Z",
|
|
112
|
-
"note": "Always accept",
|
|
113
|
-
"source": "user"
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
"type": "exact",
|
|
117
|
-
"value": "cd /home/matteo/repositories/fastify && npm run lint:eslint -- types/route.d.ts && npx tsd --files test/types/hooks.test-d.ts && npx tsd --files test/types/route.test-d.ts",
|
|
118
|
-
"addedAt": "2026-02-19T20:51:05.173Z",
|
|
119
|
-
"note": "Always accept",
|
|
120
|
-
"source": "user"
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
"type": "exact",
|
|
124
|
-
"value": "which gh && gh --version && gh auth status",
|
|
125
|
-
"addedAt": "2026-02-20T07:03:43.023Z",
|
|
126
|
-
"note": "Always accept",
|
|
127
|
-
"source": "user"
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
"type": "exact",
|
|
131
|
-
"value": "gh api repos/fastify/fastify/rulesets",
|
|
132
|
-
"addedAt": "2026-02-22T22:29:22.020Z",
|
|
133
|
-
"note": "Always accept",
|
|
134
|
-
"source": "user"
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
"type": "exact",
|
|
138
|
-
"value": "node --test test/fastify-instance.test.js",
|
|
139
|
-
"addedAt": "2026-02-23T07:23:34.147Z",
|
|
140
|
-
"note": "Always accept",
|
|
141
|
-
"source": "user"
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
"type": "exact",
|
|
145
|
-
"value": "nl -ba scripts/validate-ecosystem-links.js | sed -n '1,220p'",
|
|
146
|
-
"addedAt": "2026-02-23T07:23:55.927Z",
|
|
147
|
-
"note": "Always accept",
|
|
148
|
-
"source": "user"
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
"type": "pattern",
|
|
152
|
-
"value": "^npx\\s+eslint\\s+[\\w./~-]+\\s+[\\w./~-]+\\s+[\\w./~-]+\\s+[\\w./~-]+$",
|
|
153
|
-
"addedAt": "2026-03-09T12:41:11.065Z",
|
|
154
|
-
"note": "Always accept generic",
|
|
155
|
-
"source": "ai"
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
"type": "pattern",
|
|
159
|
-
"value": "^node\\s+--test\\s+[\\w./~-]+\\s+[\\w./~-]+$",
|
|
160
|
-
"addedAt": "2026-03-09T12:41:58.425Z",
|
|
161
|
-
"note": "Always accept generic",
|
|
162
|
-
"source": "ai"
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
"type": "pattern",
|
|
166
|
-
"value": "^npm\\s+run\\s+test:typescript$",
|
|
167
|
-
"addedAt": "2026-03-09T12:42:48.283Z",
|
|
168
|
-
"note": "Always accept generic",
|
|
169
|
-
"source": "ai"
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
"type": "exact",
|
|
173
|
-
"value": "gh search code \"request.host org:fastify\" --limit 20 --json repository,path,url",
|
|
174
|
-
"addedAt": "2026-03-09T21:03:22.953Z",
|
|
175
|
-
"note": "Always accept exact",
|
|
176
|
-
"source": "user"
|
|
177
|
-
}
|
|
178
|
-
],
|
|
179
|
-
"version": 2
|
|
180
|
-
}
|
package/test/toolkit.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
exports.waitForCb = function (options) {
|
|
4
|
-
let count = null
|
|
5
|
-
let done = false
|
|
6
|
-
let iResolve
|
|
7
|
-
let iReject
|
|
8
|
-
|
|
9
|
-
function stepIn () {
|
|
10
|
-
if (done) {
|
|
11
|
-
iReject(new Error('Unexpected done call'))
|
|
12
|
-
return
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (--count) {
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
done = true
|
|
20
|
-
iResolve()
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const patience = new Promise((resolve, reject) => {
|
|
24
|
-
iResolve = resolve
|
|
25
|
-
iReject = reject
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
count = options.steps || 1
|
|
29
|
-
done = false
|
|
30
|
-
|
|
31
|
-
return { stepIn, patience }
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
exports.partialDeepStrictEqual = function partialDeepStrictEqual (actual, expected) {
|
|
35
|
-
if (typeof expected !== 'object' || expected === null) {
|
|
36
|
-
return actual === expected
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (typeof actual !== 'object' || actual === null) {
|
|
40
|
-
return false
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (Array.isArray(expected)) {
|
|
44
|
-
if (!Array.isArray(actual)) return false
|
|
45
|
-
if (expected.length > actual.length) return false
|
|
46
|
-
|
|
47
|
-
for (let i = 0; i < expected.length; i++) {
|
|
48
|
-
if (!partialDeepStrictEqual(actual[i], expected[i])) {
|
|
49
|
-
return false
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return true
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
for (const key of Object.keys(expected)) {
|
|
56
|
-
if (!(key in actual)) return false
|
|
57
|
-
if (!partialDeepStrictEqual(actual[key], expected[key])) {
|
|
58
|
-
return false
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return true
|
|
63
|
-
}
|