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

supabase / storage / 27131902167

08 Jun 2026 10:35AM UTC coverage: 42.746% (-33.7%) from 76.41%
27131902167

Pull #1139

github

web-flow
Merge 4f7c37c69 into 74a0f6472
Pull Request #1139: feat: use @smithy/undici-http-handler for S3 client

2498 of 6435 branches covered (38.82%)

Branch coverage included in aggregate %.

10 of 24 new or added lines in 5 files covered. (41.67%)

3801 existing lines in 169 files now uncovered.

4895 of 10860 relevant lines covered (45.07%)

34.32 hits per line

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

15.0
/src/http/routes/render/renderSignedImage.ts
1
import { SIGNED_URL_SCOPE_DOWNLOAD } from '@internal/auth'
2
import { getTenantConfig } from '@internal/database'
3
import { ImageRenderer } from '@storage/renderer'
4
import { FastifyInstance } from 'fastify'
5
import { FromSchema } from 'json-schema-to-ts'
6
import { getConfig } from '../../../config'
7
import { ROUTE_OPERATIONS } from '../operations'
8

9
const { storageS3Bucket, isMultitenant } = getConfig()
2✔
10

11
const renderAuthenticatedImageParamsSchema = {
2✔
12
  type: 'object',
13
  properties: {
14
    bucketName: { type: 'string', examples: ['avatars'] },
15
    '*': { type: 'string', examples: ['folder/cat.png'] },
16
  },
17
  required: ['bucketName', '*'],
18
} as const
19

20
const renderImageQuerySchema = {
2✔
21
  type: 'object',
22
  properties: {
23
    token: {
24
      type: 'string',
25
      examples: [
26
        'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1cmwiOiJidWNrZXQyL3B1YmxpYy9zYWRjYXQtdXBsb2FkMjMucG5nIiwiaWF0IjoxNjE3NzI2MjczLCJleHAiOjE2MTc3MjcyNzN9.uBQcXzuvXxfw-9WgzWMBfE_nR3VOgpvfZe032sfLSSk',
27
      ],
28
    },
29
    download: { type: 'string', examples: ['filename.png'] },
30
  },
31
  required: ['token'],
32
} as const
33

34
interface renderImageRequestInterface {
35
  Params: FromSchema<typeof renderAuthenticatedImageParamsSchema>
36
  Querystring: FromSchema<typeof renderImageQuerySchema>
37
}
38

39
export default async function routes(fastify: FastifyInstance) {
UNCOV
40
  const summary = 'Render an authenticated image with the given transformations'
×
UNCOV
41
  fastify.get<renderImageRequestInterface>(
×
42
    '/sign/:bucketName/*',
43
    {
44
      schema: {
45
        params: renderAuthenticatedImageParamsSchema,
46
        querystring: renderImageQuerySchema,
47
        summary,
48
        response: { '4xx': { $ref: 'errorSchema#', description: 'Error response' } },
49
        tags: ['transformation'],
50
      },
51
      config: {
52
        operation: { type: ROUTE_OPERATIONS.RENDER_SIGNED_IMAGE },
53
      },
54
    },
55
    async (request, response) => {
UNCOV
56
      const { token } = request.query
×
UNCOV
57
      const { download } = request.query
×
58

UNCOV
59
      const { url, transformations, exp } = await request.storage
×
60
        .from(request.params.bucketName)
61
        .verifyObjectSignature(token, request.params['*'], SIGNED_URL_SCOPE_DOWNLOAD)
62

UNCOV
63
      const s3Key = `${request.tenantId}/${url}`
×
64

UNCOV
65
      const [bucketName, ...objParts] = url.split('/')
×
UNCOV
66
      const obj = await request.storage
×
67
        .asSuperUser()
68
        .from(bucketName)
69
        .findObject(objParts.join('/'), 'id,version,metadata')
70

UNCOV
71
      const renderer = request.storage.renderer('image') as ImageRenderer
×
72

UNCOV
73
      if (isMultitenant) {
×
74
        const tenantConfig = await getTenantConfig(request.tenantId)
×
75
        renderer.setLimits({
×
76
          maxResolution: tenantConfig.features.imageTransformation.maxResolution,
77
        })
78
      }
79

UNCOV
80
      return renderer
×
81
        .setTransformationsFromString(transformations || '')
×
82
        .render(request, response, {
83
          bucket: storageS3Bucket,
84
          key: s3Key,
85
          version: obj.version,
86
          download,
87
          expires: new Date(exp * 1000).toUTCString(),
88
          xRobotsTag: obj.metadata?.['xRobotsTag'] as string | undefined,
89
          signal: request.signals.disconnect.signal,
90
        })
91
    }
92
  )
93
}
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