Class

S3Service

S3Service()

Constructor

# new S3Service()

S3 service class providing file storage operations.

Wraps AWS S3 SDK with application-specific error handling and logging. Uses dependency injection for testability (pass mock S3 client in tests).

Key Features:

  • Upload files to S3 buckets
  • Fetch files for processing
  • Get object metadata (size, content-type, etc.)
  • Get object tags (categorization, lifecycle rules)
  • Verify bucket existence

Production Deployment:

  • Credentials via IAM roles (Lambda execution role)
  • Bucket policies enforce encryption at rest
  • CloudFront sits in front for global delivery
  • S3 lifecycle policies move old files to Glacier

View Source src/aws/s3/S3Service.js, line 52

Methods

# async fetch(bucket, key) → {Promise.<AWS.S3.GetObjectOutput>}

Fetch an object from S3.

Retrieves file contents from S3 bucket. Used for downloading icon assets, reading metadata files, or fetching files for processing in Lambda functions.

Parameters:
Name Type Description
bucket string

S3 bucket name (e.g., 'vectoricons-assets')

key string

S3 object key (e.g., 'icons/home.svg')

View Source src/aws/s3/S3Service.js, line 125

If object doesn't exist or permission denied

Error

S3 object data with Body, ContentType, etc.

Promise.<AWS.S3.GetObjectOutput>
Example
const { Body, ContentType } = await s3.fetch('vectoricons-assets', 'icons/home.svg');
const svgContent = Body.toString('utf-8');
console.log(ContentType); // 'image/svg+xml'

# async getObjectMetadata(bucket, key) → {Promise.<AWS.S3.HeadObjectOutput>}

Get metadata for an S3 object without downloading the body.

Uses HEAD request (fast, no data transfer) to get object metadata like content type, size, last modified date. Useful for checking if object exists or getting info before download.

Parameters:
Name Type Description
bucket string

S3 bucket name

key string

S3 object key

View Source src/aws/s3/S3Service.js, line 186

If object doesn't exist or permission denied

Error

Object metadata (ContentType, ContentLength, LastModified, etc.)

Promise.<AWS.S3.HeadObjectOutput>
Example
const metadata = await s3.getObjectMetadata('vectoricons-assets', 'icons/home.svg');
console.log(metadata.ContentType);   // 'image/svg+xml'
console.log(metadata.ContentLength); // 1024 (bytes)
console.log(metadata.LastModified);  // Date object

# async getObjectTags(bucket, key) → {Promise.<AWS.S3.TagSet>}

Get tags for an S3 object.

Tags are used for categorization, cost allocation, and lifecycle rules. Common tags: environment (prod/staging), asset-type (icon/illustration), processing-status (pending/complete).

Parameters:
Name Type Description
bucket string

S3 bucket name

key string

S3 object key

View Source src/aws/s3/S3Service.js, line 155

If object doesn't exist or permission denied

Error

Array of { Key, Value } tag objects

Promise.<AWS.S3.TagSet>
Example
const tags = await s3.getObjectTags('vectoricons-assets', 'icons/home.svg');
// [{ Key: 'asset-type', Value: 'icon' }, { Key: 'status', Value: 'processed' }]
const assetType = tags.find(t => t.Key === 'asset-type')?.Value;

# async headBucket(bucket) → {Promise.<AWS.S3.HeadBucketOutput>}

Verify that an S3 bucket exists and is accessible.

Uses HEAD request to check bucket existence without listing objects. Useful for health checks or validation before batch operations.

Parameters:
Name Type Description
bucket string

S3 bucket name

View Source src/aws/s3/S3Service.js, line 256

If bucket doesn't exist or access denied

Error

Empty object (success = bucket exists)

Promise.<AWS.S3.HeadBucketOutput>
Example
try {
  await s3.headBucket('vectoricons-assets');
  console.log('Bucket exists and is accessible');
} catch (error) {
  console.error('Bucket not found or no permission');
}

# async upload(bucket, key, body) → {Promise.<AWS.S3.ManagedUpload.SendData>}

Upload a file to S3.

Uploads file contents to S3 bucket. Supports buffers, streams, and strings. Uses multipart upload automatically for large files (>5MB).

Production Pattern: After upload, CloudFront CDN serves files globally with low latency. S3 lifecycle policies move old files to cheaper storage (Glacier).

Parameters:
Name Type Description
bucket string

S3 bucket name (e.g., 'vectoricons-assets')

key string

S3 object key (e.g., 'icons/home.svg')

body Buffer | Stream | string

File contents to upload

View Source src/aws/s3/S3Service.js, line 225

If upload fails or permission denied

Error

Upload result with Location, ETag, Bucket, Key

Promise.<AWS.S3.ManagedUpload.SendData>
Examples
// Upload buffer
const svgBuffer = Buffer.from('<svg>...</svg>', 'utf-8');
const result = await s3.upload('vectoricons-assets', 'icons/new-icon.svg', svgBuffer);
console.log(result.Location); // 'https://vectoricons-assets.s3.amazonaws.com/icons/new-icon.svg'
// Upload stream (memory efficient for large files)
const fileStream = fs.createReadStream('/path/to/large-file.zip');
await s3.upload('vectoricons-assets', 'uploads/batch-123.zip', fileStream);

S3Service(clientopt)

Constructor

# new S3Service(clientopt)

Construct S3Service with AWS S3 client.

Uses dependency injection to allow mocking in tests. In production, credentials come from IAM role attached to Lambda execution role.

Parameters:
Name Type Attributes Description
client AWS.S3 <optional>

AWS S3 client instance (default: new S3 client with us-east-1)

View Source src/aws/s3/S3Service.js, line 97

Examples
// Production usage (default client)
const s3 = new S3Service();
// Testing with mock client
const mockS3 = {
  getObject: jest.fn().mockReturnValue({ promise: () => Promise.resolve(...) }),
  upload: jest.fn().mockReturnValue({ promise: () => Promise.resolve(...) })
};
const s3 = new S3Service(mockS3);

Methods

# async fetch(bucket, key) → {Promise.<AWS.S3.GetObjectOutput>}

Fetch an object from S3.

Retrieves file contents from S3 bucket. Used for downloading icon assets, reading metadata files, or fetching files for processing in Lambda functions.

Parameters:
Name Type Description
bucket string

S3 bucket name (e.g., 'vectoricons-assets')

key string

S3 object key (e.g., 'icons/home.svg')

View Source src/aws/s3/S3Service.js, line 125

If object doesn't exist or permission denied

Error

S3 object data with Body, ContentType, etc.

Promise.<AWS.S3.GetObjectOutput>
Example
const { Body, ContentType } = await s3.fetch('vectoricons-assets', 'icons/home.svg');
const svgContent = Body.toString('utf-8');
console.log(ContentType); // 'image/svg+xml'

# async getObjectMetadata(bucket, key) → {Promise.<AWS.S3.HeadObjectOutput>}

Get metadata for an S3 object without downloading the body.

Uses HEAD request (fast, no data transfer) to get object metadata like content type, size, last modified date. Useful for checking if object exists or getting info before download.

Parameters:
Name Type Description
bucket string

S3 bucket name

key string

S3 object key

View Source src/aws/s3/S3Service.js, line 186

If object doesn't exist or permission denied

Error

Object metadata (ContentType, ContentLength, LastModified, etc.)

Promise.<AWS.S3.HeadObjectOutput>
Example
const metadata = await s3.getObjectMetadata('vectoricons-assets', 'icons/home.svg');
console.log(metadata.ContentType);   // 'image/svg+xml'
console.log(metadata.ContentLength); // 1024 (bytes)
console.log(metadata.LastModified);  // Date object

# async getObjectTags(bucket, key) → {Promise.<AWS.S3.TagSet>}

Get tags for an S3 object.

Tags are used for categorization, cost allocation, and lifecycle rules. Common tags: environment (prod/staging), asset-type (icon/illustration), processing-status (pending/complete).

Parameters:
Name Type Description
bucket string

S3 bucket name

key string

S3 object key

View Source src/aws/s3/S3Service.js, line 155

If object doesn't exist or permission denied

Error

Array of { Key, Value } tag objects

Promise.<AWS.S3.TagSet>
Example
const tags = await s3.getObjectTags('vectoricons-assets', 'icons/home.svg');
// [{ Key: 'asset-type', Value: 'icon' }, { Key: 'status', Value: 'processed' }]
const assetType = tags.find(t => t.Key === 'asset-type')?.Value;

# async headBucket(bucket) → {Promise.<AWS.S3.HeadBucketOutput>}

Verify that an S3 bucket exists and is accessible.

Uses HEAD request to check bucket existence without listing objects. Useful for health checks or validation before batch operations.

Parameters:
Name Type Description
bucket string

S3 bucket name

View Source src/aws/s3/S3Service.js, line 256

If bucket doesn't exist or access denied

Error

Empty object (success = bucket exists)

Promise.<AWS.S3.HeadBucketOutput>
Example
try {
  await s3.headBucket('vectoricons-assets');
  console.log('Bucket exists and is accessible');
} catch (error) {
  console.error('Bucket not found or no permission');
}

# async upload(bucket, key, body) → {Promise.<AWS.S3.ManagedUpload.SendData>}

Upload a file to S3.

Uploads file contents to S3 bucket. Supports buffers, streams, and strings. Uses multipart upload automatically for large files (>5MB).

Production Pattern: After upload, CloudFront CDN serves files globally with low latency. S3 lifecycle policies move old files to cheaper storage (Glacier).

Parameters:
Name Type Description
bucket string

S3 bucket name (e.g., 'vectoricons-assets')

key string

S3 object key (e.g., 'icons/home.svg')

body Buffer | Stream | string

File contents to upload

View Source src/aws/s3/S3Service.js, line 225

If upload fails or permission denied

Error

Upload result with Location, ETag, Bucket, Key

Promise.<AWS.S3.ManagedUpload.SendData>
Examples
// Upload buffer
const svgBuffer = Buffer.from('<svg>...</svg>', 'utf-8');
const result = await s3.upload('vectoricons-assets', 'icons/new-icon.svg', svgBuffer);
console.log(result.Location); // 'https://vectoricons-assets.s3.amazonaws.com/icons/new-icon.svg'
// Upload stream (memory efficient for large files)
const fileStream = fs.createReadStream('/path/to/large-file.zip');
await s3.upload('vectoricons-assets', 'uploads/batch-123.zip', fileStream);