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

supabase / storage / 27760253447

18 Jun 2026 12:43PM UTC coverage: 60.005% (-18.2%) from 78.232%
27760253447

push

github

web-flow
fix: limit for delete objects and sign urls (#1160)

Signed-off-by: ferhat elmas <elmas.ferhat@gmail.com>

3351 of 6375 branches covered (52.56%)

Branch coverage included in aggregate %.

25 of 31 new or added lines in 4 files covered. (80.65%)

2041 existing lines in 86 files now uncovered.

7151 of 11127 relevant lines covered (64.27%)

354.89 hits per line

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

56.25
/src/http/plugins/vector.ts
1
import {
2
  attachPgPoolErrorHandler,
3
  getTenantConfig,
4
  multitenantPgExecutor,
5
  PgPoolExecutor,
6
} from '@internal/database'
7
import { deriveVectorDatabaseUrl } from '@internal/database/vector-store-url'
8
import { ERRORS } from '@internal/errors'
9
import {
10
  BucketScopedSingleShard,
11
  PgShardStoreFactory,
12
  ShardCatalog,
13
  Sharder,
14
  SingleShard,
15
} from '@internal/sharding'
16
import {
17
  createS3VectorClient,
18
  createVectorTransactionPgResolver,
19
  PgVectorMetadataDB,
20
  PgVectorStore,
21
  S3Vector,
22
  VectorStore,
23
  VectorStoreManager,
24
} from '@storage/protocols/vector'
25
import { FastifyInstance } from 'fastify'
26
import fastifyPlugin from 'fastify-plugin'
27
import { Pool as PgPool } from 'pg'
28
import { getConfig } from '../../config'
29

30
declare module 'fastify' {
31
  interface FastifyRequest {
32
    s3Vector: VectorStoreManager
33
  }
34
}
35

36
export const s3vector = fastifyPlugin(async function (fastify: FastifyInstance) {
28✔
37
  const config = getConfig()
285✔
38
  const {
39
    vectorBucketProvider,
40
    vectorDatabaseCreate,
41
    vectorDatabaseURL,
42
    vectorS3Buckets,
43
    isMultitenant,
44
    databaseApplicationName,
45
  } = config
285✔
46

47
  let s3Adapter: S3Vector | undefined
48
  if (vectorBucketProvider === 's3' && vectorS3Buckets.length > 0) {
285✔
49
    s3Adapter = new S3Vector(createS3VectorClient())
284✔
50
  }
51

52
  // pgvector + single-tenant: VECTOR_DATABASE_URL is the maintenance URL the
53
  // migration runner used to CREATE DATABASE; the runtime pool targets the
54
  // derived `storage_vectors` database on the same server. When
55
  // VECTOR_DATABASE_CREATE=false, the runtime pool targets VECTOR_DATABASE_URL
56
  // directly.
57
  let stPgVectorAdapter: PgVectorStore | undefined
58
  let stPgVectorPool: PgPool | undefined
59
  if (vectorBucketProvider === 'pgvector' && !isMultitenant && vectorDatabaseURL) {
285!
UNCOV
60
    const connectionString = vectorDatabaseCreate
×
61
      ? deriveVectorDatabaseUrl(vectorDatabaseURL)
62
      : vectorDatabaseURL
UNCOV
63
    stPgVectorPool = attachPgPoolErrorHandler(
×
64
      new PgPool({
65
        connectionString,
66
        application_name: databaseApplicationName,
67
        min: 0,
68
        max: 10,
69
      }),
70
      {
71
        message: '[Vector] Idle pgvector client error',
72
      }
73
    )
UNCOV
74
    stPgVectorAdapter = new PgVectorStore(new PgPoolExecutor(stPgVectorPool))
×
UNCOV
75
    fastify.addHook('onClose', async () => {
×
UNCOV
76
      await stPgVectorPool?.end()
×
77
    })
78
  }
79

80
  const featureEnabled =
81
    (vectorBucketProvider === 's3' && Boolean(s3Adapter)) ||
285!
82
    (vectorBucketProvider === 'pgvector' && (isMultitenant || Boolean(stPgVectorAdapter)))
83

84
  fastify.addHook('preHandler', async (req) => {
285✔
85
    if (!featureEnabled) {
151✔
86
      throw ERRORS.FeatureNotEnabled('vector', 'Vector service not configured')
1✔
87
    }
88

89
    const { vectorMaxBucketsCount, vectorMaxIndexesCount } = config
150✔
90

91
    let maxBucketCount = vectorMaxBucketsCount
150✔
92
    let maxIndexCount = vectorMaxIndexesCount
150✔
93

94
    if (isMultitenant) {
150!
95
      const { features } = await getTenantConfig(req.tenantId)
×
96
      maxBucketCount = features?.vectorBuckets?.maxBuckets || vectorMaxBucketsCount
×
97
      maxIndexCount = features?.vectorBuckets?.maxIndexes || vectorMaxIndexesCount
×
98
    }
99

100
    const store = new PgVectorMetadataDB(req.db)
150✔
101

102
    let adapter: VectorStore
103
    if (vectorBucketProvider === 'pgvector') {
150!
104
      adapter = isMultitenant
×
105
        ? new PgVectorStore(createVectorTransactionPgResolver(req.db))
106
        : stPgVectorAdapter!
107
    } else {
108
      adapter = s3Adapter!
150✔
109
    }
110

111
    let shard: Sharder
112
    if (vectorBucketProvider === 'pgvector') {
150!
113
      shard = new BucketScopedSingleShard({
×
114
        keyPrefix: 'pgvector__',
115
        capacity: Number.MAX_SAFE_INTEGER,
116
      })
117
    } else if (isMultitenant) {
150!
118
      shard = new ShardCatalog(new PgShardStoreFactory(multitenantPgExecutor))
×
119
    } else {
120
      shard = new SingleShard({
150✔
121
        shardKey: vectorS3Buckets[0],
122
        capacity: 10000,
123
      })
124
    }
125

126
    req.s3Vector = new VectorStoreManager(adapter, store, shard, {
150✔
127
      tenantId: req.tenantId,
128
      maxBucketCount,
129
      maxIndexCount,
130
    })
131
  })
132
})
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