@aws-lambda-powertools/parser
Version:
The parser package for the Powertools for AWS Lambda (TypeScript) library.
119 lines (118 loc) • 3.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Base64Encoded = exports.JSONStringified = void 0;
const node_zlib_1 = require("node:zlib");
const base64_1 = require("@aws-lambda-powertools/commons/utils/base64");
const zod_1 = require("zod");
const decoder = new TextDecoder();
const decompress = (data) => {
try {
return JSON.parse((0, node_zlib_1.gunzipSync)((0, base64_1.fromBase64)(data, 'base64')).toString('utf8'));
}
catch {
return data;
}
};
/**
* A helper function to parse a JSON string and validate it against a schema.
*
* Use it for built-in schemas like `AlbSchema`, `ApiGatewaySchema`, etc. that have some fields that are JSON stringified
* and extend them with your custom schema.
*
* For example, if you have an event with a JSON stringified body similar to the following:
*
* ```json
* {
* // ... other fields
* "body": "{\"name\": \"John\", \"age\": 30}",
* "isBase64Encoded": false,
* }
* ```
*
* You can extend any built-in schema with your custom schema using the `JSONStringified` helper function.
*
* @example
* ```typescript
* import { JSONStringified } from '@aws-lambda-powertools/parser/helpers';
* import { AlbSchema } from '@aws-lambda-powertools/parser/schemas/alb';
* import { z } from 'zod';
*
* const customSchema = z.object({
* name: z.string(),
* age: z.number(),
* });
*
* const extendedSchema = AlbSchema.extend({
* body: JSONStringified(customSchema),
* });
*
* type ExtendedAlbEvent = z.infer<typeof extendedSchema>;
* ```
*
* @param schema - The schema to validate the JSON string against
*/
const JSONStringified = (schema) => zod_1.z
.string()
.transform((str, ctx) => {
try {
return JSON.parse(str);
}
catch (error) {
ctx.addIssue({
code: 'custom',
message: `Invalid JSON - ${error.message}`,
fatal: true,
});
}
})
.pipe(schema);
exports.JSONStringified = JSONStringified;
/**
* A helper function to decode a Base64 string and validate it against a schema.
*
*
* Use it for built-in schemas like `KinesisDataStreamRecordPayload` that have fields that are base64 encoded
* and extend them with your custom schema.
*
* For example, if you have an event with a base64 encoded body similar to the following:
*
* ```json
* {
* // ... other fields
* "data": "e3Rlc3Q6ICJ0ZXN0In0=",
* }
* ```
*
* You can extend any built-in schema with your custom schema using the `Base64Encoded` helper function.
*
* @example
* ```typescript
* import { Base64Encoded } from '@aws-lambda-powertools/parser/helpers';
* import { KinesisDataStreamRecordPayload } from '@aws-lambda-powertools/parser/schemas/kinesis';
* import { z } from 'zod';
*
* const extendedSchema = KinesisDataStreamRecordPayload.extend({
* data: Base64Encoded(z.object({
* test: z.string(),
* }))
* });
* type _ExtendedKinesisDataStream = z.infer<typeof extendedSchema>;
* ```
*
* @param schema - The schema to validate the Base 64 decoded value against
*/
const Base64Encoded = (schema) => zod_1.z
.string()
.transform((data) => {
const decompressed = decompress(data);
const decoded = decoder.decode((0, base64_1.fromBase64)(data, 'base64'));
try {
// If data was not compressed, try to parse it as JSON otherwise it must be string
return decompressed === data ? JSON.parse(decoded) : decompressed;
}
catch {
return decoded;
}
})
.pipe(schema);
exports.Base64Encoded = Base64Encoded;