• 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

1.54
/src/http/plugins/vector.ts
1
import { getTenantConfig, multitenantKnex } from '@internal/database'
2
import { deriveVectorDatabaseUrl } from '@internal/database/vector-store-url'
3
import { ERRORS } from '@internal/errors'
4
import {
5
  BucketScopedSingleShard,
6
  KnexShardStoreFactory,
7
  ShardCatalog,
8
  Sharder,
9
  SingleShard,
10
} from '@internal/sharding'
11
import {
12
  createS3VectorClient,
13
  createVectorTransactionKnexResolver,
14
  KnexVectorMetadataDB,
15
  PgVectorStore,
16
  S3Vector,
17
  VectorStore,
18
  VectorStoreManager,
19
} from '@storage/protocols/vector'
20
import { FastifyInstance } from 'fastify'
21
import fastifyPlugin from 'fastify-plugin'
22
import Knex from 'knex'
23
import { getConfig } from '../../config'
24

25
declare module 'fastify' {
26
  interface FastifyRequest {
27
    s3Vector: VectorStoreManager
28
  }
29
}
30

31
export const s3vector = fastifyPlugin(async function (fastify: FastifyInstance) {
3✔
UNCOV
32
  const config = getConfig()
×
33
  const {
34
    vectorBucketProvider,
35
    vectorDatabaseCreate,
36
    vectorDatabaseURL,
37
    vectorS3Buckets,
38
    isMultitenant,
39
    databaseApplicationName,
UNCOV
40
  } = config
×
41

42
  // S3 mode: build a singleton client+adapter at boot.
43
  let s3Adapter: S3Vector | undefined
UNCOV
44
  if (vectorBucketProvider === 's3' && vectorS3Buckets.length > 0) {
×
UNCOV
45
    s3Adapter = new S3Vector(createS3VectorClient())
×
46
  }
47

48
  // pgvector + single-tenant: VECTOR_DATABASE_URL is the maintenance URL the
49
  // migration runner used to CREATE DATABASE; the runtime pool targets the
50
  // derived `storage_vectors` database on the same server. When
51
  // VECTOR_DATABASE_CREATE=false, the runtime pool targets VECTOR_DATABASE_URL
52
  // directly.
53
  let stPgVectorAdapter: PgVectorStore | undefined
UNCOV
54
  if (vectorBucketProvider === 'pgvector' && !isMultitenant && vectorDatabaseURL) {
×
55
    const connectionString = vectorDatabaseCreate
×
56
      ? deriveVectorDatabaseUrl(vectorDatabaseURL)
57
      : vectorDatabaseURL
58
    const vectorKnex = Knex({
×
59
      client: 'pg',
60
      connection: {
61
        connectionString,
62
        application_name: databaseApplicationName,
63
      },
64
      pool: { min: 0, max: 10 },
65
    })
66
    stPgVectorAdapter = new PgVectorStore(vectorKnex)
×
67
    fastify.addHook('onClose', async () => {
×
68
      await vectorKnex.destroy()
×
69
    })
70
  }
71

72
  const featureEnabled =
UNCOV
73
    (vectorBucketProvider === 's3' && Boolean(s3Adapter)) ||
×
74
    (vectorBucketProvider === 'pgvector' && (isMultitenant || Boolean(stPgVectorAdapter)))
75

UNCOV
76
  fastify.addHook('preHandler', async (req) => {
×
UNCOV
77
    if (!featureEnabled) {
×
UNCOV
78
      throw ERRORS.FeatureNotEnabled('vector', 'Vector service not configured')
×
79
    }
80

UNCOV
81
    const { vectorMaxBucketsCount, vectorMaxIndexesCount } = config
×
82

UNCOV
83
    let maxBucketCount = vectorMaxBucketsCount
×
UNCOV
84
    let maxIndexCount = vectorMaxIndexesCount
×
85

UNCOV
86
    if (isMultitenant) {
×
87
      const { features } = await getTenantConfig(req.tenantId)
×
88
      maxBucketCount = features?.vectorBuckets?.maxBuckets || vectorMaxBucketsCount
×
89
      maxIndexCount = features?.vectorBuckets?.maxIndexes || vectorMaxIndexesCount
×
90
    }
91

UNCOV
92
    const db = req.db.pool.acquire()
×
UNCOV
93
    const store = new KnexVectorMetadataDB(db)
×
94

95
    // Pick the adapter. In multi-tenant pgvector mode the adapter binds to the
96
    // request's own tenant pool (vectors live in the tenant DB); ST pgvector
97
    // uses the singleton; s3 uses the singleton S3 client.
98
    let adapter: VectorStore
UNCOV
99
    if (vectorBucketProvider === 'pgvector') {
×
100
      adapter = isMultitenant
×
101
        ? new PgVectorStore(createVectorTransactionKnexResolver(db))
102
        : stPgVectorAdapter!
103
    } else {
UNCOV
104
      adapter = s3Adapter!
×
105
    }
106

107
    let shard: Sharder
UNCOV
108
    if (vectorBucketProvider === 'pgvector') {
×
109
      shard = new BucketScopedSingleShard({
×
110
        keyPrefix: 'pgvector__',
111
        capacity: Number.MAX_SAFE_INTEGER,
112
      })
UNCOV
113
    } else if (isMultitenant) {
×
114
      shard = new ShardCatalog(new KnexShardStoreFactory(multitenantKnex))
×
115
    } else {
UNCOV
116
      shard = new SingleShard({
×
117
        shardKey: vectorS3Buckets[0],
118
        capacity: 10000,
119
      })
120
    }
121

UNCOV
122
    req.s3Vector = new VectorStoreManager(adapter, store, shard, {
×
123
      tenantId: req.tenantId,
124
      maxBucketCount,
125
      maxIndexCount,
126
    })
127
  })
128
})
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