MCPcopy
hub / github.com/codedogQBY/ReadAny / S3Backend

Class S3Backend

packages/core/src/sync/s3-backend.ts:157–518  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

155}
156
157export class S3Backend implements ISyncBackend {
158 readonly type = "s3" as const;
159 private client: S3Client;
160 private config: S3Config;
161 private remoteRoot: string;
162
163 constructor(config: S3Config, secretAccessKey: string) {
164 this.remoteRoot =
165 sanitizeS3RemoteRoot(config.remoteRoot ?? DEFAULT_S3_REMOTE_ROOT) || DEFAULT_S3_REMOTE_ROOT;
166 this.config = {
167 ...config,
168 remoteRoot: this.remoteRoot,
169 };
170 let requestHandler: PlatformFetchHttpHandler | undefined;
171 try {
172 const platform = getPlatformService();
173 if (platform.isDesktop) {
174 requestHandler = new PlatformFetchHttpHandler();
175 }
176 } catch {
177 // Platform service may not be initialized in tests that never touch S3.
178 }
179
180 // Auto-detect path-style for non-AWS endpoints. Self-hosted S3-compatible
181 // servers (rclone serve s3, MinIO, IP/localhost endpoints) overwhelmingly
182 // require path-style addressing because their hostname can't carry the
183 // bucket as a subdomain. AWS S3 supports both styles, so leave that alone.
184 // Users can still override via the UI toggle.
185 const pathStyle = config.pathStyle ?? shouldDefaultToPathStyle(config.endpoint);
186
187 const clientConfig = {
188 endpoint: config.endpoint,
189 region: config.region,
190 credentials: {
191 accessKeyId: config.accessKeyId,
192 secretAccessKey,
193 },
194 forcePathStyle: pathStyle,
195 ...(requestHandler ? { requestHandler } : {}),
196 };
197
198 this.client = new S3Client(clientConfig);
199 }
200
201 async testConnection(): Promise<boolean> {
202 try {
203 await this.client.send(
204 new ListObjectsV2Command({
205 Bucket: this.config.bucket,
206 MaxKeys: 1,
207 Prefix: `${this.remoteRoot}/`,
208 }),
209 );
210 return true;
211 } catch (error) {
212 // The SDK's Error subclasses don't serialize their useful fields via
213 // default console.error formatting, so the feedback log capture ends
214 // up with just "Error: ..." and the user can't tell what went wrong.

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected