fastify 5.7.0 → 5.7.2

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.
Files changed (32) hide show
  1. package/.idea/fastify.iml +12 -0
  2. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  3. package/.idea/jsLibraryMappings.xml +6 -0
  4. package/.idea/jsLinters/eslint.xml +6 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/vcs.xml +6 -0
  7. package/LICENSE +1 -4
  8. package/SPONSORS.md +2 -2
  9. package/docs/Guides/Ecosystem.md +2 -1
  10. package/docs/Guides/Plugins-Guide.md +8 -8
  11. package/docs/Reference/Server.md +6 -2
  12. package/docs/Reference/Validation-and-Serialization.md +15 -6
  13. package/fastify.js +1 -1
  14. package/lib/content-type-parser.js +40 -30
  15. package/lib/content-type.js +152 -0
  16. package/lib/error-serializer.js +24 -10
  17. package/lib/handle-request.js +12 -4
  18. package/package.json +2 -2
  19. package/test/content-parser.test.js +21 -39
  20. package/test/content-type.test.js +102 -1
  21. package/test/custom-parser.0.test.js +3 -3
  22. package/test/custom-parser.1.test.js +0 -35
  23. package/test/custom-parser.3.test.js +1 -1
  24. package/test/schema-validation.test.js +66 -33
  25. package/.claude/settings.local.json +0 -11
  26. package/docs/fastify-fastify-pr-6425-run-20528050272-Lint_Docs.log +0 -180
  27. package/docs/fastify-fastify-pr-6425-run-20528054188-PR_#6425.log +0 -4006
  28. package/docs/fastify-fastify-pr-6425-run-20528054403-Pull_Request_Labeler.log +0 -42
  29. package/docs/fastify-fastify-pr-6425-run-20528054421-Lint_Docs.log +0 -196
  30. package/docs/fastify-fastify-pr-6425-run-20528054423-Internal_Links_Check.log +0 -1864
  31. package/docs/fastify-fastify-pr-6425-run-20528054430-Test_compare.log +0 -5
  32. package/docs/fastify-fastify-pr-6425-run-20528054438-pull_request_title_check.log +0 -41
@@ -55,6 +55,7 @@ test('getParser', async t => {
55
55
  fastify.addContentTypeParser(/^image\/.*/, first)
56
56
  fastify.addContentTypeParser(/^application\/.+\+xml/, second)
57
57
  fastify.addContentTypeParser('text/html', third)
58
+ fastify.addContentTypeParser('text/html; charset=utf-8', third)
58
59
 
59
60
  t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('application/t+xml').fn, second)
60
61
  t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('image/png').fn, first)
@@ -66,14 +67,15 @@ test('getParser', async t => {
66
67
  })
67
68
 
68
69
  await t.test('should return matching parser with caching /1', t => {
69
- t.plan(6)
70
+ t.plan(7)
70
71
 
71
72
  const fastify = Fastify()
72
73
 
73
74
  fastify.addContentTypeParser('text/html', first)
74
75
 
75
- t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html').fn, first)
76
76
  t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 0)
77
+ t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html').fn, first)
78
+ t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 1)
77
79
  t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html ').fn, first)
78
80
  t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 1)
79
81
  t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html ').fn, first)
@@ -81,20 +83,21 @@ test('getParser', async t => {
81
83
  })
82
84
 
83
85
  await t.test('should return matching parser with caching /2', t => {
84
- t.plan(8)
86
+ t.plan(9)
85
87
 
86
88
  const fastify = Fastify()
87
89
 
88
90
  fastify.addContentTypeParser('text/html', first)
89
91
 
90
- t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html').fn, first)
91
92
  t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 0)
93
+ t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html').fn, first)
94
+ t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 1)
92
95
  t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/HTML').fn, first)
93
96
  t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 1)
94
97
  t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('TEXT/html').fn, first)
95
- t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 2)
98
+ t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 1)
96
99
  t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('TEXT/html').fn, first)
97
- t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 2)
100
+ t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 1)
98
101
  })
99
102
 
100
103
  await t.test('should return matching parser with caching /3', t => {
@@ -125,7 +128,7 @@ test('getParser', async t => {
125
128
  })
126
129
 
127
130
  await t.test('should return parser that catches all if no other is set', t => {
128
- t.plan(3)
131
+ t.plan(2)
129
132
 
130
133
  const fastify = Fastify()
131
134
 
@@ -134,7 +137,6 @@ test('getParser', async t => {
134
137
 
135
138
  t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('image/gif').fn, first)
136
139
  t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html').fn, second)
137
- t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text').fn, first)
138
140
  })
139
141
 
140
142
  await t.test('should return undefined if no matching parser exist', t => {
@@ -208,7 +210,7 @@ test('add', async t => {
208
210
  const fastify = Fastify()
209
211
  const contentTypeParser = fastify[keys.kContentTypeParser]
210
212
 
211
- t.assert.ifError(contentTypeParser.add('test', {}, first))
213
+ t.assert.ifError(contentTypeParser.add('test/type', {}, first))
212
214
  t.assert.ifError(contentTypeParser.add(/test/, {}, first))
213
215
  t.assert.throws(
214
216
  () => contentTypeParser.add({}, {}, first),
@@ -557,7 +559,7 @@ test('content-type match parameters - regexp', async t => {
557
559
 
558
560
  const fastify = Fastify()
559
561
  fastify.removeAllContentTypeParsers()
560
- fastify.addContentTypeParser(/application\/json; charset=utf8/, function (request, body, done) {
562
+ fastify.addContentTypeParser(/application\/json; charset="utf8"/, function (request, body, done) {
561
563
  t.assert.ok('should be called')
562
564
  done(null, body)
563
565
  })
@@ -697,37 +699,17 @@ test('content-type regexp list should be cloned when plugin override', async t =
697
699
  }
698
700
  })
699
701
 
700
- test('edge case content-type - ;', async t => {
702
+ test('content-type fail when not a valid type', async t => {
701
703
  t.plan(1)
702
704
 
703
705
  const fastify = Fastify()
704
706
  fastify.removeAllContentTypeParsers()
705
- fastify.addContentTypeParser(';', function (request, body, done) {
706
- t.assert.fail('should not be called')
707
- done(null, body)
708
- })
709
-
710
- fastify.post('/', async () => {
711
- return 'ok'
712
- })
713
-
714
- await fastify.inject({
715
- method: 'POST',
716
- path: '/',
717
- headers: {
718
- 'content-type': 'application/json; foo=bar; charset=utf8'
719
- },
720
- body: ''
721
- })
722
-
723
- await fastify.inject({
724
- method: 'POST',
725
- path: '/',
726
- headers: {
727
- 'content-type': 'image/jpeg'
728
- },
729
- body: ''
730
- })
731
-
732
- t.assert.ok('end')
707
+ try {
708
+ fastify.addContentTypeParser('type-only', function (request, body, done) {
709
+ t.assert.fail('shouldn\'t be called')
710
+ done(null, body)
711
+ })
712
+ } catch (error) {
713
+ t.assert.equal(error.message, 'The content type should be a string or a RegExp')
714
+ }
733
715
  })
@@ -1,6 +1,7 @@
1
1
  'use strict'
2
2
 
3
- const { test } = require('node:test')
3
+ const { describe, test } = require('node:test')
4
+ const ContentType = require('../lib/content-type')
4
5
  const Fastify = require('..')
5
6
 
6
7
  test('should remove content-type for setErrorHandler', async t => {
@@ -40,3 +41,103 @@ test('should remove content-type for setErrorHandler', async t => {
40
41
  t.assert.strictEqual(statusCode, 400)
41
42
  t.assert.strictEqual(body, JSON.stringify({ foo: 'bar' }))
42
43
  })
44
+
45
+ describe('ContentType class', () => {
46
+ test('returns empty instance for empty value', (t) => {
47
+ let found = new ContentType('')
48
+ t.assert.equal(found.isEmpty, true)
49
+
50
+ found = new ContentType('undefined')
51
+ t.assert.equal(found.isEmpty, true)
52
+
53
+ found = new ContentType()
54
+ t.assert.equal(found.isEmpty, true)
55
+ })
56
+
57
+ test('indicates media type is not correct format', (t) => {
58
+ let found = new ContentType('foo')
59
+ t.assert.equal(found.isEmpty, true)
60
+ t.assert.equal(found.isValid, false)
61
+
62
+ found = new ContentType('foo /bar')
63
+ t.assert.equal(found.isEmpty, true)
64
+ t.assert.equal(found.isValid, false)
65
+
66
+ found = new ContentType('foo/ bar')
67
+ t.assert.equal(found.isEmpty, true)
68
+ t.assert.equal(found.isValid, false)
69
+
70
+ found = new ContentType('foo; param=1')
71
+ t.assert.equal(found.isEmpty, true)
72
+ t.assert.equal(found.isValid, false)
73
+
74
+ found = new ContentType('foo/π; param=1')
75
+ t.assert.equal(found.isEmpty, true)
76
+ t.assert.equal(found.isValid, false)
77
+ })
78
+
79
+ test('returns a plain media type instance', (t) => {
80
+ const found = new ContentType('Application/JSON')
81
+ t.assert.equal(found.mediaType, 'application/json')
82
+ t.assert.equal(found.type, 'application')
83
+ t.assert.equal(found.subtype, 'json')
84
+ t.assert.equal(found.parameters.size, 0)
85
+ })
86
+
87
+ test('handles empty parameters list', (t) => {
88
+ const found = new ContentType('Application/JSON ;')
89
+ t.assert.equal(found.isEmpty, false)
90
+ t.assert.equal(found.mediaType, 'application/json')
91
+ t.assert.equal(found.type, 'application')
92
+ t.assert.equal(found.subtype, 'json')
93
+ t.assert.equal(found.parameters.size, 0)
94
+ })
95
+
96
+ test('returns a media type instance with parameters', (t) => {
97
+ const found = new ContentType('Application/JSON ; charset=utf-8; foo=BaR;baz=" 42"')
98
+ t.assert.equal(found.isEmpty, false)
99
+ t.assert.equal(found.mediaType, 'application/json')
100
+ t.assert.equal(found.type, 'application')
101
+ t.assert.equal(found.subtype, 'json')
102
+ t.assert.equal(found.parameters.size, 3)
103
+
104
+ const expected = [
105
+ ['charset', 'utf-8'],
106
+ ['foo', 'BaR'],
107
+ ['baz', ' 42']
108
+ ]
109
+ t.assert.deepStrictEqual(
110
+ Array.from(found.parameters.entries()),
111
+ expected
112
+ )
113
+
114
+ t.assert.equal(
115
+ found.toString(),
116
+ 'application/json; charset="utf-8"; foo="BaR"; baz=" 42"'
117
+ )
118
+ })
119
+
120
+ test('skips invalid quoted string parameters', (t) => {
121
+ const found = new ContentType('Application/JSON ; charset=utf-8; foo=BaR;baz=" 42')
122
+ t.assert.equal(found.isEmpty, false)
123
+ t.assert.equal(found.mediaType, 'application/json')
124
+ t.assert.equal(found.type, 'application')
125
+ t.assert.equal(found.subtype, 'json')
126
+ t.assert.equal(found.parameters.size, 3)
127
+
128
+ const expected = [
129
+ ['charset', 'utf-8'],
130
+ ['foo', 'BaR'],
131
+ ['baz', 'invalid quoted string']
132
+ ]
133
+ t.assert.deepStrictEqual(
134
+ Array.from(found.parameters.entries()),
135
+ expected
136
+ )
137
+
138
+ t.assert.equal(
139
+ found.toString(),
140
+ 'application/json; charset="utf-8"; foo="BaR"; baz="invalid quoted string"'
141
+ )
142
+ })
143
+ })
@@ -354,7 +354,7 @@ test('catch all content type parser', async (t) => {
354
354
  method: 'POST',
355
355
  body: 'hello',
356
356
  headers: {
357
- 'Content-Type': 'very-weird-content-type'
357
+ 'Content-Type': 'very-weird-content-type/foo'
358
358
  }
359
359
  })
360
360
 
@@ -363,7 +363,7 @@ test('catch all content type parser', async (t) => {
363
363
  t.assert.strictEqual(await result2.text(), 'hello')
364
364
  })
365
365
 
366
- test('catch all content type parser should not interfere with other conte type parsers', async (t) => {
366
+ test('catch all content type parser should not interfere with other content type parsers', async (t) => {
367
367
  t.plan(6)
368
368
  const fastify = Fastify()
369
369
 
@@ -404,7 +404,7 @@ test('catch all content type parser should not interfere with other conte type p
404
404
  method: 'POST',
405
405
  body: 'hello',
406
406
  headers: {
407
- 'Content-Type': 'very-weird-content-type'
407
+ 'Content-Type': 'very-weird-content-type/foo'
408
408
  }
409
409
  })
410
410
 
@@ -89,41 +89,6 @@ test('Should get the body as string /1', async (t) => {
89
89
  t.assert.strictEqual(await result.text(), 'hello world')
90
90
  })
91
91
 
92
- test('Should get the body as string /2', async (t) => {
93
- t.plan(4)
94
- const fastify = Fastify()
95
-
96
- fastify.post('/', (req, reply) => {
97
- reply.send(req.body)
98
- })
99
-
100
- fastify.addContentTypeParser('text/plain/test', { parseAs: 'string' }, function (req, body, done) {
101
- t.assert.ok('called')
102
- t.assert.ok(typeof body === 'string')
103
- try {
104
- const plainText = body
105
- done(null, plainText)
106
- } catch (err) {
107
- err.statusCode = 400
108
- done(err, undefined)
109
- }
110
- })
111
-
112
- const fastifyServer = await fastify.listen({ port: 0 })
113
- t.after(() => fastify.close())
114
-
115
- const result = await fetch(fastifyServer, {
116
- method: 'POST',
117
- body: 'hello world',
118
- headers: {
119
- 'Content-Type': ' text/plain/test '
120
- }
121
- })
122
-
123
- t.assert.strictEqual(result.status, 200)
124
- t.assert.strictEqual(await result.text(), 'hello world')
125
- })
126
-
127
92
  test('Should get the body as buffer', async (t) => {
128
93
  t.plan(4)
129
94
  const fastify = Fastify()
@@ -189,7 +189,7 @@ test('catch all content type parser should not interfere with content type parse
189
189
 
190
190
  const assertions = [
191
191
  { body: '{"myKey":"myValue"}', contentType: 'application/json', expected: JSON.stringify({ myKey: 'myValue' }) },
192
- { body: 'body', contentType: 'very-weird-content-type', expected: 'body' },
192
+ { body: 'body', contentType: 'very-weird-content-type/foo', expected: 'body' },
193
193
  { body: 'my text', contentType: 'text/html', expected: 'my texthtml' }
194
194
  ]
195
195
 
@@ -1416,7 +1416,7 @@ test('Schema validation will not be bypass by different content type', async t =
1416
1416
  t.after(() => fastify.close())
1417
1417
  const address = fastify.listeningOrigin
1418
1418
 
1419
- const correct1 = await fetch(address, {
1419
+ let found = await fetch(address, {
1420
1420
  method: 'POST',
1421
1421
  url: '/',
1422
1422
  headers: {
@@ -1424,10 +1424,10 @@ test('Schema validation will not be bypass by different content type', async t =
1424
1424
  },
1425
1425
  body: JSON.stringify({ foo: 'string' })
1426
1426
  })
1427
- t.assert.strictEqual(correct1.status, 200)
1428
- await correct1.bytes()
1427
+ t.assert.strictEqual(found.status, 200)
1428
+ await found.bytes()
1429
1429
 
1430
- const correct2 = await fetch(address, {
1430
+ found = await fetch(address, {
1431
1431
  method: 'POST',
1432
1432
  url: '/',
1433
1433
  headers: {
@@ -1435,10 +1435,10 @@ test('Schema validation will not be bypass by different content type', async t =
1435
1435
  },
1436
1436
  body: JSON.stringify({ foo: 'string' })
1437
1437
  })
1438
- t.assert.strictEqual(correct2.status, 200)
1439
- await correct2.bytes()
1438
+ t.assert.strictEqual(found.status, 200)
1439
+ await found.bytes()
1440
1440
 
1441
- const correct3 = await fetch(address, {
1441
+ found = await fetch(address, {
1442
1442
  method: 'POST',
1443
1443
  url: '/',
1444
1444
  headers: {
@@ -1446,10 +1446,10 @@ test('Schema validation will not be bypass by different content type', async t =
1446
1446
  },
1447
1447
  body: JSON.stringify({ foo: 'string' })
1448
1448
  })
1449
- t.assert.strictEqual(correct2.status, 200)
1450
- await correct3.bytes()
1449
+ t.assert.strictEqual(found.status, 200)
1450
+ await found.bytes()
1451
1451
 
1452
- const invalid1 = await fetch(address, {
1452
+ found = await fetch(address, {
1453
1453
  method: 'POST',
1454
1454
  url: '/',
1455
1455
  headers: {
@@ -1457,10 +1457,10 @@ test('Schema validation will not be bypass by different content type', async t =
1457
1457
  },
1458
1458
  body: JSON.stringify({ invalid: 'string' })
1459
1459
  })
1460
- t.assert.strictEqual(invalid1.status, 400)
1461
- t.assert.strictEqual((await invalid1.json()).code, 'FST_ERR_VALIDATION')
1460
+ t.assert.strictEqual(found.status, 400)
1461
+ t.assert.strictEqual((await found.json()).code, 'FST_ERR_VALIDATION')
1462
1462
 
1463
- const invalid2 = await fetch(address, {
1463
+ found = await fetch(address, {
1464
1464
  method: 'POST',
1465
1465
  url: '/',
1466
1466
  headers: {
@@ -1468,10 +1468,10 @@ test('Schema validation will not be bypass by different content type', async t =
1468
1468
  },
1469
1469
  body: JSON.stringify({ invalid: 'string' })
1470
1470
  })
1471
- t.assert.strictEqual(invalid2.status, 400)
1472
- t.assert.strictEqual((await invalid2.json()).code, 'FST_ERR_VALIDATION')
1471
+ t.assert.strictEqual(found.status, 400)
1472
+ t.assert.strictEqual((await found.json()).code, 'FST_ERR_VALIDATION')
1473
1473
 
1474
- const invalid3 = await fetch(address, {
1474
+ found = await fetch(address, {
1475
1475
  method: 'POST',
1476
1476
  url: '/',
1477
1477
  headers: {
@@ -1479,10 +1479,10 @@ test('Schema validation will not be bypass by different content type', async t =
1479
1479
  },
1480
1480
  body: JSON.stringify({ invalid: 'string' })
1481
1481
  })
1482
- t.assert.strictEqual(invalid3.status, 400)
1483
- t.assert.strictEqual((await invalid3.json()).code, 'FST_ERR_VALIDATION')
1482
+ t.assert.strictEqual(found.status, 400)
1483
+ t.assert.strictEqual((await found.json()).code, 'FST_ERR_VALIDATION')
1484
1484
 
1485
- const invalid4 = await fetch(address, {
1485
+ found = await fetch(address, {
1486
1486
  method: 'POST',
1487
1487
  url: '/',
1488
1488
  headers: {
@@ -1490,10 +1490,10 @@ test('Schema validation will not be bypass by different content type', async t =
1490
1490
  },
1491
1491
  body: JSON.stringify({ invalid: 'string' })
1492
1492
  })
1493
- t.assert.strictEqual(invalid4.status, 400)
1494
- t.assert.strictEqual((await invalid4.json()).code, 'FST_ERR_VALIDATION')
1493
+ t.assert.strictEqual(found.status, 415)
1494
+ t.assert.strictEqual((await found.json()).code, 'FST_ERR_CTP_INVALID_MEDIA_TYPE')
1495
1495
 
1496
- const invalid5 = await fetch(address, {
1496
+ found = await fetch(address, {
1497
1497
  method: 'POST',
1498
1498
  url: '/',
1499
1499
  headers: {
@@ -1501,10 +1501,10 @@ test('Schema validation will not be bypass by different content type', async t =
1501
1501
  },
1502
1502
  body: JSON.stringify({ invalid: 'string' })
1503
1503
  })
1504
- t.assert.strictEqual(invalid5.status, 400)
1505
- t.assert.strictEqual((await invalid5.json()).code, 'FST_ERR_VALIDATION')
1504
+ t.assert.strictEqual(found.status, 415)
1505
+ t.assert.strictEqual((await found.json()).code, 'FST_ERR_CTP_INVALID_MEDIA_TYPE')
1506
1506
 
1507
- const invalid6 = await fetch(address, {
1507
+ found = await fetch(address, {
1508
1508
  method: 'POST',
1509
1509
  url: '/',
1510
1510
  headers: {
@@ -1512,10 +1512,10 @@ test('Schema validation will not be bypass by different content type', async t =
1512
1512
  },
1513
1513
  body: JSON.stringify({ invalid: 'string' })
1514
1514
  })
1515
- t.assert.strictEqual(invalid6.status, 400)
1516
- t.assert.strictEqual((await invalid6.json()).code, 'FST_ERR_VALIDATION')
1515
+ t.assert.strictEqual(found.status, 415)
1516
+ t.assert.strictEqual((await found.json()).code, 'FST_ERR_CTP_INVALID_MEDIA_TYPE')
1517
1517
 
1518
- const invalid7 = await fetch(address, {
1518
+ found = await fetch(address, {
1519
1519
  method: 'POST',
1520
1520
  url: '/',
1521
1521
  headers: {
@@ -1523,10 +1523,10 @@ test('Schema validation will not be bypass by different content type', async t =
1523
1523
  },
1524
1524
  body: JSON.stringify({ invalid: 'string' })
1525
1525
  })
1526
- t.assert.strictEqual(invalid7.status, 400)
1527
- t.assert.strictEqual((await invalid7.json()).code, 'FST_ERR_VALIDATION')
1526
+ t.assert.strictEqual(found.status, 400)
1527
+ t.assert.strictEqual((await found.json()).code, 'FST_ERR_VALIDATION')
1528
1528
 
1529
- const invalid8 = await fetch(address, {
1529
+ found = await fetch(address, {
1530
1530
  method: 'POST',
1531
1531
  url: '/',
1532
1532
  headers: {
@@ -1534,6 +1534,39 @@ test('Schema validation will not be bypass by different content type', async t =
1534
1534
  },
1535
1535
  body: JSON.stringify({ invalid: 'string' })
1536
1536
  })
1537
- t.assert.strictEqual(invalid8.status, 400)
1538
- t.assert.strictEqual((await invalid8.json()).code, 'FST_ERR_VALIDATION')
1537
+ t.assert.strictEqual(found.status, 400)
1538
+ t.assert.strictEqual((await found.json()).code, 'FST_ERR_VALIDATION')
1539
+
1540
+ found = await fetch(address, {
1541
+ method: 'POST',
1542
+ url: '/',
1543
+ headers: {
1544
+ 'content-type': 'ApPlIcAtIoN/JsOn\ta'
1545
+ },
1546
+ body: JSON.stringify({ invalid: 'string' })
1547
+ })
1548
+ t.assert.strictEqual(found.status, 415)
1549
+ t.assert.strictEqual((await found.json()).code, 'FST_ERR_CTP_INVALID_MEDIA_TYPE')
1550
+
1551
+ found = await fetch(address, {
1552
+ method: 'POST',
1553
+ url: '/',
1554
+ headers: {
1555
+ 'content-type': 'ApPlIcAtIoN/JsOn\ta; charset=utf-8'
1556
+ },
1557
+ body: JSON.stringify({ invalid: 'string' })
1558
+ })
1559
+ t.assert.strictEqual(found.status, 415)
1560
+ t.assert.strictEqual((await found.json()).code, 'FST_ERR_CTP_INVALID_MEDIA_TYPE')
1561
+
1562
+ found = await fetch(address, {
1563
+ method: 'POST',
1564
+ url: '/',
1565
+ headers: {
1566
+ 'content-type': 'application/ json'
1567
+ },
1568
+ body: JSON.stringify({ invalid: 'string' })
1569
+ })
1570
+ t.assert.strictEqual(found.status, 415)
1571
+ t.assert.strictEqual((await found.json()).code, 'FST_ERR_CTP_INVALID_MEDIA_TYPE')
1539
1572
  })
@@ -1,11 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "WebFetch(domain:github.com)",
5
- "Bash(curl -sI https://github.com/nucleode/arecibo)",
6
- "Bash(curl:*)"
7
- ],
8
- "deny": [],
9
- "ask": []
10
- }
11
- }