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

supabase / storage / 30390837140

28 Jul 2026 07:11PM UTC coverage: 80.327% (-0.08%) from 80.41%
30390837140

Pull #1276

github

web-flow
Merge 45a3adfa7 into 20927735c
Pull Request #1276: fix(docs): normalize nullable JSON Schema idioms for OpenAPI 3.0 docs

5644 of 7567 branches covered (74.59%)

Branch coverage included in aggregate %.

30 of 32 new or added lines in 1 file covered. (93.75%)

20 existing lines in 3 files now uncovered.

10758 of 12852 relevant lines covered (83.71%)

412.59 hits per line

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

89.55
/src/http/openapi-nullable.ts
1
import type { SwaggerTransform } from '@fastify/swagger'
2
import { finiteSwaggerTransform } from './finite'
3

4
// Route schemas are authored as plain JSON Schema, e.g. `type: ['integer', 'null']`
5
// or `{ anyOf: [<schema>, { type: 'null' }] }` for `$ref`-based unions — both of
6
// which AJV validates natively. OpenAPI 3.0's Schema Object can't represent
7
// either idiom: it only allows a single `type` string plus a separate
8
// `nullable: true` boolean. Rewrite both into that OpenAPI 3.0 shape for the
9
// generated docs; the schemas used for runtime validation are untouched (same
10
// clone-before-mutate approach as `stripFiniteKeyword`).
11
function isNullOnlySchema(value: unknown): value is { type: 'null' } {
12
  return (
49✔
13
    !!value &&
184✔
14
    typeof value === 'object' &&
15
    Object.keys(value).length === 1 &&
16
    (value as { type?: unknown }).type === 'null'
17
  )
18
}
19

20
export function normalizeNullableSchema<T>(value: T): T {
21
  if (Array.isArray(value)) {
3,527✔
22
    return value.map(normalizeNullableSchema) as T
629✔
23
  }
24

25
  if (!value || typeof value !== 'object') {
2,898✔
26
    return value
1,715✔
27
  }
28

29
  const prototype = Object.getPrototypeOf(value)
1,183✔
30
  if (prototype !== Object.prototype && prototype !== null) {
1,183!
NEW
31
    return value
×
32
  }
33

34
  const object = value as Record<string, unknown>
1,183✔
35

36
  const anyOf = object.anyOf
1,183✔
37
  if (Array.isArray(anyOf) && anyOf.length === 2) {
1,183✔
38
    const nullIndex = anyOf.findIndex(isNullOnlySchema)
25✔
39
    const other = nullIndex === -1 ? undefined : anyOf[1 - nullIndex]
25✔
40
    if (other && typeof other === 'object') {
25✔
41
      const merged: Record<string, unknown> = {
22✔
42
        ...(normalizeNullableSchema(other) as Record<string, unknown>),
43
        nullable: true,
44
      }
45
      for (const [key, nestedValue] of Object.entries(object)) {
22✔
46
        if (key !== 'anyOf' && !(key in merged)) {
22!
NEW
47
          merged[key] = normalizeNullableSchema(nestedValue)
×
48
        }
49
      }
50
      return merged as T
22✔
51
    }
52
  }
53

54
  const result: Record<string, unknown> = {}
1,161✔
55
  for (const [key, nestedValue] of Object.entries(object)) {
1,161✔
56
    if (key === 'type' && Array.isArray(nestedValue) && nestedValue.length === 2) {
2,668✔
57
      const nullIndex = nestedValue.indexOf('null')
21✔
58
      if (nullIndex !== -1) {
21!
59
        result.type = nestedValue[1 - nullIndex]
21✔
60
        result.nullable = true
21✔
61
        continue
21✔
62
      }
63
    }
64
    result[key] = normalizeNullableSchema(nestedValue)
2,647✔
65
  }
66

67
  return result as T
1,161✔
68
}
69

70
// Composes with `finiteSwaggerTransform`: strip the internal `finite` keyword
71
// first, then normalize nullable idioms, so the generated docs schema is both
72
// free of internal-only keywords and OpenAPI 3.0-valid.
73
export const docsSwaggerTransform: SwaggerTransform = (params) => {
38✔
74
  const { schema } = finiteSwaggerTransform(params)
150✔
75
  return { schema: normalizeNullableSchema(schema), url: params.url }
150✔
76
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc