• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / storage / 24447693422

15 Apr 2026 09:45AM UTC coverage: 82.475% (-0.001%) from 82.476%
24447693422

Pull #1020

github

web-flow
Merge 4dc4b685d into c86312671
Pull Request #1020: fix: cap expires in and return bad request

3685 of 7463 branches covered (49.38%)

Branch coverage included in aggregate %.

15 of 32 new or added lines in 3 files covered. (46.88%)

2791 existing lines in 97 files now uncovered.

30504 of 33991 relevant lines covered (89.74%)

348.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.59
/src/http/plugins/xml.ts
1
import accepts from '@fastify/accepts'
1✔
2
import { FastifyInstance } from 'fastify'
1✔
3
import fastifyPlugin from 'fastify-plugin'
1✔
4
import xml from 'xml2js'
1✔
5

1✔
6
type XmlParserOptions = { disableContentParser?: boolean; parseAsArray?: string[] }
1✔
7
type RequestError = Error & { statusCode?: number }
1✔
8

1✔
9
function forcePathAsArray(node: unknown, pathSegments: string[]): void {
26✔
10
  if (pathSegments.length === 0 || node === null || node === undefined) {
28!
11
    return
×
12
  }
13

26✔
14
  if (Array.isArray(node)) {
28!
15
    node.forEach((item) => forcePathAsArray(item, pathSegments))
×
16
    return
×
17
  }
18

26✔
19
  if (typeof node !== 'object') {
28!
20
    return
×
21
  }
22

26✔
23
  const [current, ...rest] = pathSegments
28✔
24
  const currentRecord = node as Record<string, unknown>
28✔
25

26✔
26
  if (!(current in currentRecord)) {
28!
27
    return
×
28
  }
29

26✔
30
  if (rest.length === 0) {
28✔
31
    const value = currentRecord[current]
14✔
32
    if (value !== undefined && !Array.isArray(value)) {
14!
33
      currentRecord[current] = [value]
7✔
34
    }
6✔
35
    return
14✔
36
  }
13✔
37

13✔
38
  forcePathAsArray(currentRecord[current], rest)
14✔
39
}
13✔
40

1✔
41
export const xmlParser = fastifyPlugin(
2✔
42
  async function (fastify: FastifyInstance, opts: XmlParserOptions) {
1✔
43
    fastify.register(accepts)
2,863✔
44

2,860✔
45
    if (!opts.disableContentParser) {
2,863!
46
      fastify.addContentTypeParser(
2,603✔
47
        ['text/xml', 'application/xml'],
2,600✔
48
        { parseAs: 'string' },
2,600✔
49
        (_request, body, done) => {
2,600✔
50
          if (!body) {
89!
UNCOV
51
            done(null, null)
78✔
UNCOV
52
            return
78✔
53
          }
78✔
54

9✔
55
          xml.parseString(
11✔
56
            body,
9✔
57
            {
9✔
58
              explicitArray: false,
9✔
59
              trim: true,
9✔
60
              valueProcessors: [xml.processors.parseNumbers, xml.processors.parseBooleans],
9✔
61
            },
9✔
62
            (err: Error | null, parsed: unknown) => {
9✔
63
              if (err) {
11✔
64
                const parseError: RequestError = new Error(`Invalid XML payload: ${err.message}`)
2✔
65
                parseError.statusCode = 400
2✔
66
                done(parseError)
2✔
67
                return
2✔
68
              }
1✔
69

8✔
70
              if (parsed && opts.parseAsArray?.length) {
10!
71
                opts.parseAsArray.forEach((path) => {
9✔
72
                  if (!path) {
14!
73
                    return
×
74
                  }
75
                  forcePathAsArray(parsed, path.split('.'))
14✔
76
                })
8✔
77
              }
8✔
78

8✔
79
              done(null, parsed)
9✔
80
            }
8✔
81
          )
9✔
82
        }
9✔
83
      )
2,600✔
84
    }
2,600✔
85

2,860✔
86
    fastify.addHook('preSerialization', async (req, res, payload) => {
2,863✔
87
      const accept = req.accepts()
119✔
88

117✔
89
      const acceptedTypes = ['application/xml', 'text/html']
119✔
90

117✔
91
      if (acceptedTypes.some((allowed) => accept.types(acceptedTypes) === allowed)) {
120✔
92
        res.serializer((payload) => payload)
118✔
93

117✔
94
        const xmlBuilder = new xml.Builder({
118✔
95
          renderOpts: {
117✔
96
            pretty: false,
117✔
97
          },
117✔
98
        })
117✔
99
        const xmlPayload = xmlBuilder.buildObject(payload)
118✔
100
        res.type('application/xml')
118✔
101
        res.header('content-type', 'application/xml; charset=utf-8')
118✔
102
        return xmlPayload
118✔
103
      }
117✔
104

×
105
      return payload
1✔
106
    })
2,860✔
107
  },
2,860✔
108
  { name: 'xml-parser' }
1✔
109
)
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc