|
1 | 1 | /** |
2 | 2 | * S3 client factory. |
3 | 3 | * |
4 | | - * Creates a configured S3Client from a StorageConnectionConfig. |
5 | | - * Handles provider-specific settings (path-style for MinIO, etc.). |
| 4 | + * Delegates to @constructive-io/s3-utils for the actual S3Client creation. |
| 5 | + * Re-exports createS3Client so existing consumers of bucket-provisioner |
| 6 | + * continue to work without changes. |
6 | 7 | */ |
7 | 8 |
|
8 | | -import { S3Client } from '@aws-sdk/client-s3'; |
| 9 | +import { createS3Client as createS3ClientFromUtils, S3ConfigError } from '@constructive-io/s3-utils'; |
| 10 | +import type { S3Client } from '@aws-sdk/client-s3'; |
9 | 11 | import type { StorageConnectionConfig } from './types'; |
10 | 12 | import { ProvisionerError } from './types'; |
| 13 | +import type { ProvisionerErrorCode } from './types'; |
11 | 14 |
|
12 | 15 | /** |
13 | 16 | * Create an S3Client from a storage connection config. |
14 | 17 | * |
15 | | - * Provider-specific defaults: |
16 | | - * - `minio`: forces path-style URLs (required by MinIO) |
17 | | - * - `r2`: forces path-style URLs (required by Cloudflare R2) |
18 | | - * - `s3`: uses virtual-hosted style (AWS default) |
19 | | - * - `gcs`: forces path-style URLs (GCS S3-compatible API) |
20 | | - * - `spaces`: uses virtual-hosted style (DigitalOcean default) |
| 18 | + * Delegates to @constructive-io/s3-utils/createS3Client. |
| 19 | + * This wrapper exists for backward compatibility — new code should |
| 20 | + * import createS3Client from @constructive-io/s3-utils directly. |
| 21 | + * |
| 22 | + * Catches S3ConfigError from s3-utils and re-throws as ProvisionerError |
| 23 | + * so existing consumers that catch ProvisionerError continue to work. |
21 | 24 | */ |
22 | 25 | export function createS3Client(config: StorageConnectionConfig): S3Client { |
23 | | - if (!config.accessKeyId || !config.secretAccessKey) { |
24 | | - throw new ProvisionerError( |
25 | | - 'INVALID_CONFIG', |
26 | | - 'accessKeyId and secretAccessKey are required', |
27 | | - ); |
28 | | - } |
29 | | - |
30 | | - if (!config.region) { |
31 | | - throw new ProvisionerError( |
32 | | - 'INVALID_CONFIG', |
33 | | - 'region is required', |
34 | | - ); |
| 26 | + try { |
| 27 | + return createS3ClientFromUtils(config); |
| 28 | + } catch (err) { |
| 29 | + if (err instanceof S3ConfigError) { |
| 30 | + throw new ProvisionerError(err.code as ProvisionerErrorCode, err.message); |
| 31 | + } |
| 32 | + throw err; |
35 | 33 | } |
36 | | - |
37 | | - // Providers that require path-style URLs |
38 | | - const pathStyleProviders = new Set(['minio', 'r2', 'gcs']); |
39 | | - const forcePathStyle = config.forcePathStyle ?? pathStyleProviders.has(config.provider); |
40 | | - |
41 | | - // Non-AWS providers require an endpoint |
42 | | - if (config.provider !== 's3' && !config.endpoint) { |
43 | | - throw new ProvisionerError( |
44 | | - 'INVALID_CONFIG', |
45 | | - `endpoint is required for provider '${config.provider}'`, |
46 | | - ); |
47 | | - } |
48 | | - |
49 | | - return new S3Client({ |
50 | | - region: config.region, |
51 | | - endpoint: config.endpoint, |
52 | | - forcePathStyle, |
53 | | - credentials: { |
54 | | - accessKeyId: config.accessKeyId, |
55 | | - secretAccessKey: config.secretAccessKey, |
56 | | - }, |
57 | | - }); |
58 | 34 | } |
0 commit comments