import { Injectable } from '@nestjs/common'; import * as Joi from 'joi'; import { AbstractActionHandler, Format } from '../abstract-action.handler'; import { Action } from '../action.enum'; import { RequestContext } from '../_context/request.context'; import { S3Service } from './s3.service'; type QueryParams = { Bucket: string; Body?: string; }; @Injectable() export class PutBucketTaggingHandler extends AbstractActionHandler { constructor(private readonly s3Service: S3Service) { super(); } format = Format.Xml; action = Action.S3PutBucketTagging; validator = Joi.object({ Bucket: Joi.string().required(), Body: Joi.string().optional(), }); protected async handle({ Bucket, Body }: QueryParams, { awsProperties }: RequestContext) { // Parse XML body to extract tags const tags: Record = {}; if (Body) { // Decode from base64 const xmlBody = Buffer.from(Body, 'base64').toString('utf-8'); // Simple XML parsing for AWS S3 tagging format: ......... const tagMatches = xmlBody.matchAll(/\s*(.*?)<\/Key>\s*(.*?)<\/Value>\s*<\/Tag>/gs); for (const match of tagMatches) { const key = match[1].trim(); const value = match[2].trim(); if (key) { tags[key] = value; } } } await this.s3Service.putBucketTagging(Bucket, tags); // PutBucketTagging returns no content on success return {}; } }