UNPKG

@aws-lambda-powertools/parser

Version:
96 lines (95 loc) 4.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DynamoDBStreamEnvelope = void 0; const zod_1 = require("zod"); const errors_js_1 = require("../errors.js"); const index_js_1 = require("../schemas/index.js"); const envelope_js_1 = require("./envelope.js"); /** * DynamoDB Stream Envelope to extract data within NewImage/OldImage * * Note: Values are the parsed models. Images' values can also be None, and * length of the list is the record's amount in the original event. */ exports.DynamoDBStreamEnvelope = { /** * This is a discriminator to differentiate whether an envelope returns an array or an object * @hidden */ [envelope_js_1.envelopeDiscriminator]: 'array', parse(data, schema) { const parsedEnvelope = index_js_1.DynamoDBStreamSchema.parse(data); const processImage = (image, imageType, recordIndex) => { try { return image ? schema.parse(image) : undefined; } catch (error) { throw new errors_js_1.ParseError(`Failed to parse DynamoDB record at index ${recordIndex}`, { cause: new zod_1.ZodError(error.issues.map((issue) => ({ ...issue, path: [ 'Records', recordIndex, 'dynamodb', imageType, ...issue.path, ], }))), }); } }; return parsedEnvelope.Records.map((record, index) => ({ NewImage: processImage(record.dynamodb.NewImage, 'NewImage', index), OldImage: processImage(record.dynamodb.OldImage, 'OldImage', index), })); }, safeParse(data, schema) { const parsedEnvelope = index_js_1.DynamoDBStreamSchema.safeParse(data); if (!parsedEnvelope.success) { return { success: false, error: new errors_js_1.ParseError('Failed to parse DynamoDB Stream envelope', { cause: parsedEnvelope.error, }), originalEvent: data, }; } const processImage = (image) => image ? schema.safeParse(image) : undefined; const result = parsedEnvelope.data.Records.reduce((acc, record, index) => { const newImage = processImage(record.dynamodb.NewImage); const oldImage = processImage(record.dynamodb.OldImage); if (newImage?.success === false || oldImage?.success === false) { const issues = []; for (const key of ['NewImage', 'OldImage']) { const image = key === 'NewImage' ? newImage : oldImage; if (image?.success === false) { issues.push(...image.error.issues.map((issue) => ({ ...issue, path: ['Records', index, 'dynamodb', key, ...issue.path], }))); } } acc.success = false; acc.errors[index] = { issues }; return acc; } acc.records.push({ NewImage: newImage?.data, OldImage: oldImage?.data, }); return acc; }, { success: true, records: [], errors: {} }); if (result.success) { return { success: true, data: result.records }; } const errorMessage = Object.keys(result.errors).length > 1 ? `Failed to parse records at indexes ${Object.keys(result.errors).join(', ')}` : `Failed to parse record at index ${Object.keys(result.errors)[0]}`; const errorCause = new zod_1.ZodError(Object.values(result.errors).flatMap((error) => error.issues)); return { success: false, error: new errors_js_1.ParseError(errorMessage, { cause: errorCause }), originalEvent: data, }; }, };