UNPKG

serverless-offline-streams

Version:

This plugin provides support for event driven systems using Serverless Offline

104 lines (82 loc) 3.71 kB
import {FilterPatterns} from "./dynamodb/filterPatterns/filterGrammar"; import * as Serverless from "serverless"; import {StringKeyObject} from "./utils"; export interface FunctionDefinition<EventType> { handler: string events: Array<EventType> } type ServerlessFunctionDefinition = FunctionDefinition<StringKeyObject<any>> export interface ParsedFunctionDefinition extends FunctionDefinition<StreamsEventMapping> { functionName: string } export interface SqsEventMappingDefinition { sqs: { arn: string batchSize?: number } } export interface DynamoEventMappingDefinition { stream: { type: "dynamodb" arn: string enabled?: boolean batchSize?: number startingPosition?: 'LATEST' | 'TRIM_HORIZON' filterPatterns: FilterPatterns[] } } type StreamsEventMappingDefinition = SqsEventMappingDefinition | DynamoEventMappingDefinition type StreamsFunctionType = 'DYNAMO' | 'SQS' export interface StreamsEventMapping { type: StreamsFunctionType sourceEvent: StreamsEventMappingDefinition } export const getFunctionDefinitionsWithStreamsEvents = (serverless: Serverless, type?: StreamsFunctionType): StringKeyObject<ParsedFunctionDefinition> => { const {service} = serverless const rawFunctionsConfig = (serverless as unknown as any).configurationInput.functions as StringKeyObject<any> const zipWithIndex = <T>(v: T, i: number) => [v, i] as [T, number] const parseFilterPatterns = (functionName: string, eventIndex: number) => { return rawFunctionsConfig[functionName]?.events[eventIndex]?.stream?.filterPatterns }; const isValidStreamsEvent = (event: any) => (!type && event.sqs || event.stream) || (type === 'DYNAMO' && event?.stream?.type === 'dynamodb') || (type === 'SQS' && event?.sqs) const toSqsStreamsEventMapping = (event: StringKeyObject<any>): StreamsEventMapping => ({ type: 'SQS', sourceEvent: event as SqsEventMappingDefinition }) const toDynamoStreamsEventMapping = (functionName: string, event: StringKeyObject<any>, eventIndex: number): StreamsEventMapping => ({ type: 'DYNAMO', sourceEvent: { ...event, stream: { ...event.stream, filterPatterns: event.filterPatterns ? parseFilterPatterns(functionName, eventIndex) : undefined } } }) const toStreamsEventMapping = (functionName: string, event: StringKeyObject<any>, eventIndex: number): StreamsEventMapping => { if (event.sqs) return toSqsStreamsEventMapping(event) if (event.stream) return toDynamoStreamsEventMapping(functionName, event, eventIndex) throw Error("Unable to parse streams event mapping") } const parseFunctionWithStreamsEvents = (functionName: string): ParsedFunctionDefinition => { const functionDef = service.getFunction(functionName) as ServerlessFunctionDefinition return { functionName, ...functionDef, events: functionDef.events .map(zipWithIndex) .filter(([e]) => isValidStreamsEvent(e)) .map(([e, i]) => toStreamsEventMapping(functionName, e, i)), } } const hasStreamsEvents = (functionDef: ParsedFunctionDefinition) => functionDef.events.length > 0 const zipWithName = (functionDef: ParsedFunctionDefinition) => [functionDef.functionName, functionDef] as [string, ParsedFunctionDefinition] return Object.fromEntries( service.getAllFunctions() .map(parseFunctionWithStreamsEvents) .filter(hasStreamsEvents) .map(zipWithName) ) }