Created
August 4, 2021 17:56
-
-
Save cyberwombat/d33d31caa455ce51101278e394d3c8a0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import merge from 'deepmerge' | |
import { | |
DispatchAttributes, | |
WorkflowDefinition, | |
WorkflowModel | |
} from 'typings/workflow' | |
import { ActionEvent } from 'typings/lambda' | |
import { | |
APIGatewayProxyWithCognitoAuthorizerEvent, | |
AttributeValue, | |
Context, | |
CustomMessageAdminCreateUserTriggerEvent, | |
CustomMessageForgotPasswordTriggerEvent, | |
CustomMessageSignUpTriggerEvent, | |
CustomMessageUpdateUserAttributeTriggerEvent, | |
DynamoDBStreamEvent, | |
PostConfirmationConfirmSignUpTriggerEvent, | |
PreSignUpEmailTriggerEvent, | |
S3Event | |
} from 'aws-lambda' | |
import { generateId } from 'lib/utils/uidUtils' | |
import { | |
ActionContext, | |
ActionResponseStatus, | |
ActionType | |
} from 'typings/actions' | |
import { CollectionModel } from 'typings/collection' | |
import { deepMerge } from 'lib/utils/primitiveUtils' | |
import { ViewModel } from 'typings/view' | |
import { | |
InsightInterval, | |
InsightModel, | |
InsightQueryData | |
} from 'typings/insight' | |
import { ItemModel } from 'typings/item' | |
import { getTimestamp, getTimeToLive } from 'lib/utils/dateUtils' | |
import { | |
DynamoDBImage, | |
DynamoDBStreamEventType, | |
DynamoDBStreamViewType, | |
DynamoDBTable, | |
PartitionKeys | |
} from 'typings/dynamo' | |
import { seedDynamoDBTable } from './dynamoDBMockService' | |
import { ServiceModel } from 'typings/service' | |
import { AccountModel } from 'typings/account' | |
import { AccessModel, UserPermission } from 'typings/access' | |
import { ParameterModel } from 'typings/parameter' | |
import { PackageModel, PackageScope } from 'typings/package' | |
import { ModuleModel, ModuleScope } from 'typings/module' | |
import { StackUpsertInput } from 'typings/stack' | |
import { getConfig } from 'src/lib/utils/configUtils' | |
import { LogModel } from 'typings/log' | |
import { SocketModel } from 'typings/socket' | |
import { ThrottleModel } from 'typings/throttle' | |
import { ObjectLiteral } from 'typings/common' | |
import { SQSTaskDispatcherEvent } from 'typings/sqs' | |
import { marshallRecord } from 'lib/aws/dynamoDBService' | |
import { EventHandlerPayload } from 'typings/events' | |
type AwsLambdaContextMock = (props?: Record<keyof Context, any>) => Context | |
export const genericLabel = 'The label' | |
export const genericSummary = 'The summary' | |
export const genericDescription = | |
'Quis magna pariatur laboris cupidatat elit ut do nisi minim dolor labore nostrud aliqua.' | |
export const genericWorkflowDefinition: WorkflowDefinition = { | |
startStep: { | |
type: 'start', | |
description: 'Start workflow', | |
parameters: { | |
next: 'echoStep' | |
} | |
}, | |
echoStep: { | |
type: 'echo', | |
description: 'Return to sender', | |
parameters: { | |
payload: '$.payload.foo', | |
result: '$' | |
} | |
} | |
} | |
// Create a new item entry | |
export const generateInsightModel = async ( | |
payload?: Partial<InsightModel> | |
): Promise<InsightModel> => { | |
const model: InsightModel = { | |
accountId: generateId(), | |
collectionId: generateId(), | |
queries: {}, | |
...payload | |
} | |
await seedDynamoDBTable<InsightModel>(DynamoDBTable.INSIGHT, [model]) | |
return model | |
} | |
// Create a new item entry | |
export const generateItemModel = async ( | |
payload?: Partial<ItemModel> | |
): Promise<ItemModel> => { | |
const model: ItemModel = { | |
accountId: generateId(), | |
collectionId: generateId(), | |
itemId: generateId(), | |
createdAt: getTimestamp(), | |
updatedAt: getTimestamp(), | |
data: {}, | |
...payload | |
} | |
await seedDynamoDBTable<ItemModel>(DynamoDBTable.ITEM, [model]) | |
return model | |
} | |
// Create a new collection entry | |
export const generateCollectionModel = async ( | |
payload?: Partial<CollectionModel> | |
): Promise<CollectionModel> => { | |
const model: CollectionModel = { | |
accountId: generateId(), | |
collectionId: generateId(), | |
serviceId: generateId(), | |
createdAt: getTimestamp(), | |
updatedAt: getTimestamp(), | |
label: genericLabel, | |
summary: genericSummary, | |
options: {}, | |
mapping: {}, | |
triggers: {}, | |
queries: {}, | |
...payload | |
} | |
await seedDynamoDBTable<CollectionModel>(DynamoDBTable.COLLECTION, [model]) | |
return model | |
} | |
// Create a new workflow entry | |
export const generateWorkflowModel = async ( | |
payload?: Partial<WorkflowModel> | |
): Promise<WorkflowModel> => { | |
const model: WorkflowModel = { | |
accountId: generateId(), | |
workflowId: generateId(), | |
serviceId: generateId(), | |
createdAt: getTimestamp(), | |
updatedAt: getTimestamp(), | |
label: genericLabel, | |
summary: genericSummary, | |
definition: {}, | |
...payload | |
} | |
await seedDynamoDBTable<WorkflowModel>(DynamoDBTable.WORKFLOW, [model]) | |
return model | |
} | |
// Create a new view entry | |
export const generateViewModel = async ( | |
payload?: Partial<ViewModel> | |
): Promise<ViewModel> => { | |
const model: ViewModel = { | |
accountId: generateId(), | |
viewId: generateId(), | |
serviceId: generateId(), | |
createdAt: getTimestamp(), | |
updatedAt: getTimestamp(), | |
label: genericLabel, | |
summary: genericSummary, | |
...payload | |
} | |
await seedDynamoDBTable<ViewModel>(DynamoDBTable.VIEW, [model]) | |
return model | |
} | |
// Create a new service entry | |
export const generateServiceModel = async ( | |
payload?: Partial<ServiceModel> | |
): Promise<ServiceModel> => { | |
const model: ServiceModel = { | |
accountId: generateId(), | |
serviceId: generateId(), | |
createdAt: getTimestamp(), | |
updatedAt: getTimestamp(), | |
label: genericLabel, | |
summary: genericSummary, | |
description: genericDescription, | |
settings: {}, | |
domain: `foo.${getConfig('serviceDomain')}`, | |
...payload | |
} | |
await seedDynamoDBTable<ServiceModel>(DynamoDBTable.SERVICE, [model]) | |
return model | |
} | |
// Create a new web socket connection entry | |
export const generateSocketModel = async ( | |
payload?: Partial<SocketModel> | |
): Promise<SocketModel> => { | |
const model: SocketModel = { | |
connectionId: generateId(), | |
topicId: generateId(), | |
timeToLive: getTimeToLive(1000), | |
...payload | |
} | |
await seedDynamoDBTable<SocketModel>(DynamoDBTable.SOCKET, [model]) | |
return model | |
} | |
// Create a new throtte entry | |
export const generateThrottleModel = async ( | |
payload?: Partial<ThrottleModel> | |
): Promise<ThrottleModel> => { | |
const model: ThrottleModel = { | |
taskId: generateId(), | |
createdAt: getTimestamp(), | |
timeToLive: getTimeToLive(1000), | |
...payload | |
} | |
await seedDynamoDBTable<ThrottleModel>(DynamoDBTable.THROTTLE, [model]) | |
return model | |
} | |
// Create a new log entry | |
export const generateLogModel = async ( | |
payload?: Partial<LogModel> | |
): Promise<LogModel> => { | |
const model: LogModel = { | |
accountId: generateId(), | |
serviceId: generateId(), | |
processId: generateId(), | |
callerId: generateId(), | |
actionId: generateId(), | |
workflowId: generateId(), | |
logId: generateId(), | |
status: ActionResponseStatus.SUCCESS, | |
context: generateActionContext(), | |
result: { foo: 'bar' }, | |
name: 'someAction', | |
runtime: 2, | |
execution: 1, | |
type: ActionType.ECHO, | |
triggeredAt: getTimestamp(), | |
timeToLive: getTimeToLive(10000), | |
watch: false, | |
...payload | |
} | |
await seedDynamoDBTable<LogModel>(DynamoDBTable.LOG, [model]) | |
return model | |
} | |
// Create a new access entry | |
export const generateAccessModel = async ( | |
payload?: Partial<AccessModel> | |
): Promise<AccessModel> => { | |
const model: AccessModel = { | |
accountId: generateId(), | |
userId: generateId(), | |
permission: UserPermission.ADMIN, | |
createdAt: getTimestamp(), | |
updatedAt: getTimestamp(), | |
...payload | |
} | |
await seedDynamoDBTable<AccessModel>(DynamoDBTable.ACCESS, [model]) | |
return model | |
} | |
// Create a new account entry | |
export const generateAccountModel = async ( | |
payload?: Partial<AccountModel> | |
): Promise<AccountModel> => { | |
const model: AccountModel = { | |
accountId: generateId(), | |
createdAt: getTimestamp(), | |
updatedAt: getTimestamp(), | |
label: genericLabel, | |
isActive: true, | |
usage: { | |
storage: {}, | |
runtime: {}, | |
request: {} | |
}, | |
...payload | |
} | |
await seedDynamoDBTable<AccountModel>(DynamoDBTable.ACCOUNT, [model]) | |
return model | |
} | |
// Create a new parameter entry | |
export const generateParameterModel = async ( | |
payload?: Partial<ParameterModel> | |
): Promise<ParameterModel> => { | |
const model: ParameterModel = { | |
accountId: generateId(), | |
parameterId: generateId(), | |
createdAt: getTimestamp(), | |
updatedAt: getTimestamp(), | |
key: 'secret', | |
value: 'password', | |
summary: 'A secret', | |
...payload | |
} | |
await seedDynamoDBTable<ParameterModel>(DynamoDBTable.PARAMETER, [model]) | |
return model | |
} | |
// Create a new package entry | |
export const generatePackageModel = async ( | |
payload?: Partial<PackageModel> | |
): Promise<PackageModel> => { | |
const model: PackageModel = { | |
accountId: generateId(), | |
packageId: generateId(), | |
createdAt: getTimestamp(), | |
updatedAt: getTimestamp(), | |
label: genericLabel, | |
summary: genericSummary, | |
description: genericDescription, | |
stack: generateStack(), | |
scope: PackageScope.PUBLIC, | |
meta: {}, | |
...payload | |
} | |
await seedDynamoDBTable<PackageModel>(DynamoDBTable.PACKAGE, [model]) | |
return model | |
} | |
// Create a new moddule entry | |
export const generateModuleModel = async ( | |
payload?: Partial<ModuleModel> | |
): Promise<ModuleModel> => { | |
const model: ModuleModel = { | |
accountId: generateId(), | |
moduleId: generateId(), | |
createdAt: getTimestamp(), | |
updatedAt: getTimestamp(), | |
deployedAt: getTimestamp(), | |
scope: ModuleScope.PUBLIC, | |
label: genericLabel, | |
summary: genericSummary, | |
description: genericDescription, | |
options: {}, | |
events: {}, | |
hash: '123', | |
repository: 'foo/bar', | |
meta: {}, | |
...payload | |
} | |
await seedDynamoDBTable<ModuleModel>(DynamoDBTable.MODULE, [model]) | |
return model | |
} | |
export const generateStack = ( | |
payload: Partial<StackUpsertInput> = {} | |
): StackUpsertInput => { | |
const stack: StackUpsertInput = { | |
service: { | |
id: 'myService', | |
data: {} | |
}, | |
collections: [], | |
views: [], | |
workflows: [] | |
} | |
return { ...stack, ...payload } | |
} | |
// Action context | |
export const generateActionContext = ( | |
props: Partial<ActionContext> = {} | |
): ActionContext => { | |
const defaults: ActionContext = { | |
payload: {}, | |
query: {}, | |
loops: [], | |
headers: {}, | |
parameters: {}, | |
config: { | |
accountId: generateId(), | |
processId: generateId(), | |
workflowId: generateId(), | |
serviceId: generateId() | |
} | |
} | |
return merge(defaults, props) | |
} | |
// Generic AWS lambda context | |
export const generateLambdaContext: AwsLambdaContextMock = ( | |
props?: Record<keyof Context, any> | |
): Context => ({ | |
callbackWaitsForEmptyEventLoop: false, | |
functionName: 'viewer-request', | |
functionVersion: '1234', | |
invokedFunctionArn: 'fakearn', | |
memoryLimitInMB: '5000', | |
awsRequestId: '1234', | |
logGroupName: 'groupname', | |
logStreamName: 'streamname', | |
identity: { | |
cognitoIdentityId: '12345', | |
cognitoIdentityPoolId: '45678' | |
}, | |
clientContext: { | |
client: { | |
installationId: '123456', | |
appTitle: 'app', | |
appVersionName: 'v2', | |
appVersionCode: '000', | |
appPackageName: 'pkg' | |
}, | |
Custom: { custom: '12345' }, | |
env: { | |
platformVersion: '12345', | |
platform: '12345', | |
make: '12345', | |
model: '12345', | |
locale: 'de' | |
} | |
}, | |
getRemainingTimeInMillis: () => 500, | |
done: () => { | |
return | |
}, | |
fail: () => { | |
return | |
}, | |
succeed: () => { | |
return | |
}, | |
...props | |
}) | |
// This trigger is invoked when admin creates a user | |
export const generateCognitoCustomMessageAdminCreateUserTriggerEvent = | |
(): CustomMessageAdminCreateUserTriggerEvent => ({ | |
version: '1', | |
region: 'us-east-1', | |
userPoolId: 'us-east-1_bZJX2Eq4j', | |
userName: '7fea21dd-6bfd-443c-aae0-cf2a16172896', | |
callerContext: { | |
awsSdkVersion: 'aws-sdk-js-3.11.0', | |
clientId: 'CLIENT_ID_NOT_APPLICABLE' | |
}, | |
triggerSource: 'CustomMessage_AdminCreateUser', | |
request: { | |
userAttributes: { | |
sub: '7fea21dd-6bfd-443c-aae0-cf2a16172896', | |
'cognito:user_status': 'FORCE_CHANGE_PASSWORD', | |
email_verified: 'true', | |
email: '[email protected]' | |
}, | |
codeParameter: '{####}', | |
//linkParameter: '{##Click Here##}', // Not in TS but we dont need it | |
usernameParameter: '{username}' | |
}, | |
response: { | |
smsMessage: '', | |
emailMessage: '', | |
emailSubject: '' | |
} | |
}) | |
// This trigger is invoked when user resets their email from dashboard | |
export const generateCognitoCustomMessageUpdateUserAttributeLambdaEvent = | |
(): CustomMessageUpdateUserAttributeTriggerEvent => ({ | |
version: '1', | |
region: 'us-east-1', | |
userPoolId: 'us-east-1_fzb5VyAM7', | |
userName: '4fec8342-e5d7-48c1-9773-8938e33e1947', | |
callerContext: { | |
awsSdkVersion: 'aws-sdk-unknown-unknown', | |
clientId: '79ljespnt8ackn4neofoujimjr' | |
}, | |
triggerSource: 'CustomMessage_UpdateUserAttribute', | |
request: { | |
userAttributes: { | |
sub: '4fec8342-e5d7-48c1-9773-8938e33e1947', | |
'cognito:user_status': 'CONFIRMED', | |
email_verified: 'false', | |
email: '[email protected]' | |
}, | |
codeParameter: '{####}', | |
usernameParameter: '4fec8342-e5d7-48c1-9773-8938e33e1947' | |
}, | |
response: { | |
smsMessage: '', | |
emailMessage: '', | |
emailSubject: '' | |
} | |
}) | |
// This trigger is invoked when user resets their password | |
export const generateCognitoPostConfirmationConfirmForgotPasswordLambdaEvent = | |
() => ({ | |
version: '1', | |
region: 'us-east-1', | |
userPoolId: 'us-east-1_fzb5VyAM7', | |
userName: '4fec8342-e5d7-48c1-9773-8938e33e1947', | |
callerContext: { | |
awsSdkVersion: 'aws-sdk-unknown-unknown', | |
clientId: '79ljespnt8ackn4neofoujimjr' | |
}, | |
triggerSource: 'PostConfirmation_ConfirmForgotPassword', | |
request: { | |
userAttributes: { | |
sub: '4fec8342-e5d7-48c1-9773-8938e33e1947', | |
'cognito:email_alias': '[email protected]', | |
'cognito:user_status': 'CONFIRMED', | |
email_verified: 'true', | |
email: '[email protected]' | |
} | |
}, | |
response: {} | |
}) | |
// This trigger is invoked when user requests password reset - we use this to create custom confirm email | |
export const generateCognitoCustomMessageForgotPasswordLambdaEvent = | |
(): CustomMessageForgotPasswordTriggerEvent => ({ | |
version: '1', | |
region: 'us-east-1', | |
userPoolId: 'us-east-1_fzb5VyAM7', | |
userName: '4fec8342-e5d7-48c1-9773-8938e33e1947', | |
callerContext: { | |
awsSdkVersion: 'aws-sdk-unknown-unknown', | |
clientId: '79ljespnt8ackn4neofoujimjr' | |
}, | |
triggerSource: 'CustomMessage_ForgotPassword', | |
request: { | |
userAttributes: { | |
sub: '4fec8342-e5d7-48c1-9773-8938e33e1947', | |
email_verified: 'true', | |
'cognito:user_status': 'CONFIRMED', | |
'cognito:email_alias': '[email protected]', | |
email: '[email protected]' | |
}, | |
codeParameter: '{####}', | |
usernameParameter: '' | |
}, | |
response: { | |
smsMessage: '', | |
emailMessage: '', | |
emailSubject: '' | |
} | |
}) | |
// This trigger is invoked when user submits signup info - we use this to create custom confirm email | |
export const generateCognitoCustomMessageSignUpLambdaEvent = | |
(): CustomMessageSignUpTriggerEvent => ({ | |
version: '1', | |
region: 'us-east-1', | |
userPoolId: 'us-east-1_fzb5VyAM7', | |
userName: '4fec8342-e5d7-48c1-9773-8938e33e1947', | |
callerContext: { | |
awsSdkVersion: 'aws-sdk-unknown-unknown', | |
clientId: '79ljespnt8ackn4neofoujimjr' | |
}, | |
triggerSource: 'CustomMessage_SignUp', | |
request: { | |
userAttributes: { | |
sub: '4fec8342-e5d7-48c1-9773-8938e33e1947', | |
'cognito:user_status': 'UNCONFIRMED', | |
email_verified: 'false', | |
'cognito:email_alias': '[email protected]', | |
email: '[email protected]' | |
}, | |
codeParameter: '{####}', | |
usernameParameter: '' | |
}, | |
response: { | |
smsMessage: '', | |
emailMessage: '', | |
emailSubject: '' | |
} | |
}) | |
// This trigger is invoked after a user is confirmed, allowing you to send custom messages or to add custom logic, for example for analytics. | |
export const generateCognitoPostConfirmationConfirmSignUpLambdaEvent = | |
(): PostConfirmationConfirmSignUpTriggerEvent => ({ | |
version: '1', | |
region: 'us-east-1', | |
userPoolId: 'us-east-1_fzb5VyAM7', | |
userName: 'fbcf1a78-f623-47ae-a6c5-04147507c548', | |
callerContext: { | |
awsSdkVersion: 'aws-sdk-unknown-unknown', | |
clientId: '79ljespnt8ackn4neofoujimjr' | |
}, | |
triggerSource: 'PostConfirmation_ConfirmSignUp', | |
request: { | |
userAttributes: { | |
sub: 'fbcf1a78-f623-47ae-a6c5-04147507c548', | |
'cognito:email_alias': '[email protected]', | |
'cognito:user_status': 'CONFIRMED', | |
email_verified: 'true', | |
email: '[email protected]' | |
} | |
}, | |
response: {} | |
}) | |
// This trigger is invoked when a user submits their information to sign up, allowing you to perform custom validation to accept or deny the sign up request. | |
export const generateCognitoPreSignUpSignUpLambdaEvent = | |
(): PreSignUpEmailTriggerEvent => ({ | |
version: '1', | |
region: 'us-east-1', | |
userPoolId: 'us-east-1_fzb5VyAM7', | |
userName: '9132e892-976e-4e38-b6be-ab250adf90c5', | |
callerContext: { | |
awsSdkVersion: 'aws-sdk-unknown-unknown', | |
clientId: '79ljespnt8ackn4neofoujimjr' | |
}, | |
triggerSource: 'PreSignUp_SignUp', | |
request: { | |
userAttributes: { | |
email: '[email protected]' | |
}, | |
validationData: {} | |
}, | |
response: { | |
autoConfirmUser: false, | |
autoVerifyEmail: false, | |
autoVerifyPhone: false | |
} | |
}) | |
// This trigger is invoked when a user submits their information to be authenticated, allowing you to perform custom validations to accept or deny the sign in request. | |
export const generateCognitoPreAuthenticationAuthenticationLambdaEvent = | |
() => ({ | |
version: '1', | |
region: 'us-east-1', | |
userPoolId: 'us-east-1_fzb5VyAM7', | |
userName: 'fbcf1a78-f623-47ae-a6c5-04147507c548', | |
callerContext: { | |
awsSdkVersion: 'aws-sdk-unknown-unknown', | |
clientId: '79ljespnt8ackn4neofoujimjr' | |
}, | |
triggerSource: 'PreAuthentication_Authentication', | |
request: { | |
userAttributes: { | |
sub: 'fbcf1a78-f623-47ae-a6c5-04147507c548', | |
email_verified: 'true', | |
'cognito:user_status': 'CONFIRMED', | |
'cognito:email_alias': '[email protected]', | |
email: '[email protected]' | |
}, | |
validationData: {} | |
}, | |
response: {} | |
}) | |
// This trigger is invoked after a user is authenticated, allowing you to add custom logic, for example for analytics. | |
export const generateCognitoPostAuthenticationAuthenticationLambdaEvent = | |
() => ({ | |
version: '1', | |
region: 'us-east-1', | |
userPoolId: 'us-east-1_fzb5VyAM7', | |
userName: 'fbcf1a78-f623-47ae-a6c5-04147507c548', | |
callerContext: { | |
awsSdkVersion: 'aws-sdk-unknown-unknown', | |
clientId: '79ljespnt8ackn4neofoujimjr' | |
}, | |
triggerSource: 'PostAuthentication_Authentication', | |
request: { | |
userAttributes: { | |
sub: 'fbcf1a78-f623-47ae-a6c5-04147507c548', | |
email_verified: 'true', | |
'cognito:user_status': 'CONFIRMED', | |
'cognito:email_alias': '[email protected]', | |
email: '[email protected]' | |
}, | |
newDeviceUsed: false | |
}, | |
response: {} | |
}) | |
// Event sent to lambda by EventBridge - doesn't do much :) | |
export const generateEventBridgeLambdaEvent = < | |
T extends EventHandlerPayload = never, // Require arg: https://stackoverflow.com/a/57683742/856498 | |
U extends T = T | |
>( | |
data: U | |
): U => data | |
// Generate websocket disconnection event | |
export const generateWebSocketDisconnectionEvent = () => { | |
return { | |
headers: { | |
Host: 'localhost', | |
'X-Api-Key': '', | |
'x-restapi': '' | |
}, | |
isBase64Encoded: false, | |
multiValueHeaders: { | |
Host: ['localhost'], | |
'X-Api-Key': [''], | |
'x-restapi': [''] | |
}, | |
requestContext: { | |
apiId: 'private', | |
connectedAt: 1602170789631, | |
connectionId: 'ckg0z4d8b0000b1yp1uyngc5v', | |
domainName: 'localhost', | |
eventType: 'DISCONNECT', | |
extendedRequestId: 'ckg0z9dip0005b1yp1v1dhb76', | |
identity: { | |
accessKey: null, | |
accountId: null, | |
caller: null, | |
cognitoAuthenticationProvider: null, | |
cognitoAuthenticationType: null, | |
cognitoIdentityId: null, | |
cognitoIdentityPoolId: null, | |
principalOrgId: null, | |
sourceIp: '127.0.0.1', | |
user: null, | |
userAgent: null, | |
userArn: null | |
}, | |
messageDirection: 'IN', | |
messageId: 'ckg0z9dip0006b1ypd1eea0zm', | |
requestId: 'ckg0z9dip0007b1yp33ywanf7', | |
requestTime: '08/Oct/2020:08:30:23 -0700', | |
requestTimeEpoch: 1602171023281, | |
routeKey: '$disconnect', | |
stage: 'local' | |
} | |
} | |
} | |
// Generate websocket message event | |
export const generateWebSocketMessageEvent = () => { | |
return { | |
body: '{ "action": "$trigger", "payload": "boom" }', | |
isBase64Encoded: false, | |
requestContext: { | |
apiId: 'private', | |
connectedAt: 1602172894830, | |
connectionId: 'ckg10dhm400009sypbx424rre', | |
domainName: 'localhost', | |
eventType: 'MESSAGE', | |
extendedRequestId: 'ckg10had000109sypc8kh9r0d', | |
identity: { | |
accessKey: null, | |
accountId: null, | |
caller: null, | |
cognitoAuthenticationProvider: null, | |
cognitoAuthenticationType: null, | |
cognitoIdentityId: null, | |
cognitoIdentityPoolId: null, | |
principalOrgId: null, | |
sourceIp: '127.0.0.1', | |
user: null, | |
userAgent: null, | |
userArn: null | |
}, | |
messageDirection: 'IN', | |
messageId: 'ckg10had000119syp51v90a4z', | |
requestId: 'ckg10had100129sypg55lhlnd', | |
requestTime: '08/Oct/2020:09:04:32 -0700', | |
requestTimeEpoch: 1602173072052, | |
routeKey: '$trigger', | |
stage: 'local' | |
} | |
} | |
} | |
// Generate workflow definition | |
export const generateWorkflowDefinition = ( | |
customDefiniiton?: WorkflowDefinition | |
): WorkflowDefinition => { | |
return deepMerge(genericWorkflowDefinition, customDefiniiton || {}) | |
} | |
// Generate insight query data | |
export const generateInsightQueryData = ( | |
customData?: Partial<InsightQueryData> | |
): InsightQueryData => { | |
return deepMerge( | |
{ | |
[InsightInterval.YEAR]: [], | |
[InsightInterval.MONTH]: [], | |
[InsightInterval.WEEK]: [], | |
[InsightInterval.DAY]: [], | |
[InsightInterval.HOUR]: [] | |
}, | |
customData || {} | |
) | |
} | |
// export const generateWorkflowDefinition = (args = {}) => { | |
// const { triggers, steps, start = 'startStep' } = args | |
// const definition = { | |
// start: start, | |
// triggers: triggers || { | |
// events: {}, | |
// webhook: { | |
// throttle: false, | |
// active: true, | |
// keys: [], | |
// origins: ['*'] | |
// } | |
// }, | |
// steps: steps || { | |
// [start]: { | |
// type: 'echo', | |
// description: 'Return to sender', | |
// parameters: { | |
// boom: 'boom' | |
// } | |
// } | |
// } | |
// } | |
// return definition | |
// } | |
// Generate action dispatch attributes | |
export const generateDispatchAttributes = ( | |
args: Partial<DispatchAttributes> = {} | |
): DispatchAttributes => { | |
const { workflowId, callerId, processId, accountId, serviceId } = args | |
return { | |
workflowId: workflowId || generateId(), | |
callerId: callerId || generateId(), | |
processId: processId || generateId(), | |
serviceId: serviceId || generateId(), | |
accountId: accountId || '00000000-0000-0000-0000-00000000000' | |
} | |
} | |
// Generate action payload | |
export const generateActionPayload = (args: any = {}) => { | |
const { payload } = args | |
return { | |
stash: {}, | |
payload: payload || { foo: 'bar' } | |
} | |
} | |
// Generate DynamoDB stream event | |
export const generateDynamoDBStreamEvent = ({ | |
oldImage, | |
newImage, | |
partitionKeys, | |
eventName, | |
tableName, | |
streamViewType = DynamoDBStreamViewType.NEW_AND_OLD_IMAGES | |
}: { | |
oldImage?: DynamoDBImage | |
newImage?: DynamoDBImage | |
partitionKeys?: PartitionKeys | |
eventName: DynamoDBStreamEventType | |
tableName: DynamoDBTable | |
streamViewType?: DynamoDBStreamViewType | |
}) => { | |
const event: DynamoDBStreamEvent = { | |
Records: [ | |
{ | |
eventID: '1', | |
eventVersion: '1.0', | |
dynamodb: { | |
SequenceNumber: '111', | |
SizeBytes: 26, | |
StreamViewType: streamViewType | |
}, | |
awsRegion: 'eu-east-1', | |
eventName, | |
eventSourceARN: `arn:aws:dynamodb:${getConfig('awsRegion')}:${getConfig( | |
'awsAccountId' | |
)}:table/${tableName}/stream/${getTimestamp()}/`, | |
eventSource: 'aws:dynamodb' | |
} | |
] | |
} | |
if (!event.Records || !event.Records[0].dynamodb) return | |
if (partitionKeys) { | |
event.Records[0].dynamodb.Keys = marshallRecord(partitionKeys) as { | |
[key: string]: AttributeValue // Cast as AWSLambda.AttributeValue instead of native aws type to resolve conflict | |
} | |
} | |
if (oldImage) | |
event.Records[0].dynamodb.OldImage = marshallRecord(oldImage) as { | |
[key: string]: AttributeValue | |
} | |
if (newImage) | |
event.Records[0].dynamodb.NewImage = marshallRecord(newImage) as { | |
[key: string]: AttributeValue | |
} | |
return event | |
} | |
// Generate API gateway proxy event | |
export const generateLambdaProxyEvent = ( | |
event?: ObjectLiteral | |
): APIGatewayProxyWithCognitoAuthorizerEvent => { | |
const base: APIGatewayProxyWithCognitoAuthorizerEvent = { | |
body: 'eyJ0ZXN0IjoiYm9keSJ9', | |
resource: '/{proxy+}', | |
path: '/path/to/resource', | |
httpMethod: 'POST', | |
isBase64Encoded: true, | |
queryStringParameters: { | |
foo: 'bar' | |
}, | |
multiValueQueryStringParameters: { | |
foo: ['bar'] | |
}, | |
pathParameters: { | |
proxy: '/path/to/resource' | |
}, | |
stageVariables: { | |
baz: 'qux' | |
}, | |
headers: { | |
Accept: | |
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', | |
'Accept-Encoding': 'gzip, deflate, sdch', | |
'Accept-Language': 'en-US,en;q=0.8', | |
'Cache-Control': 'max-age=0', | |
'CloudFront-Forwarded-Proto': 'https', | |
'CloudFront-Is-Desktop-Viewer': 'true', | |
'CloudFront-Is-Mobile-Viewer': 'false', | |
'CloudFront-Is-SmartTV-Viewer': 'false', | |
'CloudFront-Is-Tablet-Viewer': 'false', | |
'CloudFront-Viewer-Country': 'US', | |
Host: '1234567890.execute-api.us-east-1.amazonaws.com', | |
'Upgrade-Insecure-Requests': '1', | |
'User-Agent': 'Custom User Agent String', | |
Via: '1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)', | |
'X-Amz-Cf-Id': 'cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==', | |
'X-Forwarded-For': '127.0.0.1, 127.0.0.2', | |
'X-Forwarded-Port': '443', | |
'X-Forwarded-Proto': 'https' | |
}, | |
multiValueHeaders: { | |
Accept: [ | |
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' | |
], | |
'Accept-Encoding': ['gzip, deflate, sdch'], | |
'Accept-Language': ['en-US,en;q=0.8'], | |
'Cache-Control': ['max-age=0'], | |
'CloudFront-Forwarded-Proto': ['https'], | |
'CloudFront-Is-Desktop-Viewer': ['true'], | |
'CloudFront-Is-Mobile-Viewer': ['false'], | |
'CloudFront-Is-SmartTV-Viewer': ['false'], | |
'CloudFront-Is-Tablet-Viewer': ['false'], | |
'CloudFront-Viewer-Country': ['US'], | |
Host: ['0123456789.execute-api.us-east-1.amazonaws.com'], | |
'Upgrade-Insecure-Requests': ['1'], | |
'User-Agent': ['Custom User Agent String'], | |
Via: ['1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)'], | |
'X-Amz-Cf-Id': [ | |
'cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==' | |
], | |
'X-Forwarded-For': ['127.0.0.1, 127.0.0.2'], | |
'X-Forwarded-Port': ['443'], | |
'X-Forwarded-Proto': ['https'] | |
}, | |
requestContext: { | |
authorizer: { | |
claims: {} | |
}, | |
accountId: '123456789012', | |
resourceId: '123456', | |
stage: 'prod', | |
requestId: 'c6af9ac6-7b61-11e6-9a41-93e8deadbeef', | |
requestTime: '09/Apr/2015:12:34:56 +0000', | |
requestTimeEpoch: 1428582896000, | |
identity: { | |
cognitoIdentityPoolId: null, | |
accountId: null, | |
cognitoIdentityId: null, | |
caller: null, | |
accessKey: null, | |
sourceIp: '127.0.0.1', | |
cognitoAuthenticationType: null, | |
cognitoAuthenticationProvider: null, | |
userArn: null, | |
userAgent: 'Custom User Agent String', | |
user: null, | |
apiKey: null, | |
apiKeyId: null, | |
principalOrgId: null, | |
clientCert: null | |
}, | |
path: '/prod/path/to/resource', | |
resourcePath: '/{proxy+}', | |
httpMethod: 'POST', | |
apiId: '1234567890', | |
protocol: 'HTTP/1.1' | |
} | |
} | |
return deepMerge(base, event) | |
} | |
// Generate API gateway proxy event | |
export const generateLambdaWebSocketEvent = ( | |
event?: ObjectLiteral | |
): APIGatewayProxyWithCognitoAuthorizerEvent => { | |
const base = generateLambdaProxyEvent({ | |
requestContext: { | |
connectedAt: 1602170789631, | |
connectionId: 'ckg0z4d8b0000b1yp1uyngc5v', | |
domainName: 'localhost', | |
eventType: 'CONNECT' | |
} | |
}) | |
return deepMerge(base, event) | |
} | |
// Event when calling an AppSync lambda source | |
export function generateAppSyncLambdaEvent(action: string, payload?: any): any { | |
return { | |
field: action, | |
arguments: payload | |
} | |
} | |
// Event passed from SQS provision handler to invoked tasks | |
export const generateLambdaSQSTaskInvokeEvent = ( | |
event?: ObjectLiteral | |
): SQSTaskDispatcherEvent<unknown> => { | |
const base = { | |
actionParams: {}, | |
receiptHandle: generateId() | |
} | |
return deepMerge(base, event) | |
} | |
// Eveent when S3 updated | |
export const generateLambdaS3PutEvent = ( | |
name: string, | |
key: string | |
): S3Event => ({ | |
Records: [ | |
{ | |
eventVersion: '2.0', | |
eventSource: 'aws:s3', | |
awsRegion: 'us-east-1', | |
eventTime: '1970-01-01T00:00:00.000Z', | |
eventName: 'ObjectCreated:Put', | |
userIdentity: { | |
principalId: 'EXAMPLE' | |
}, | |
requestParameters: { | |
sourceIPAddress: '127.0.0.1' | |
}, | |
responseElements: { | |
'x-amz-request-id': 'EXAMPLE123456789', | |
'x-amz-id-2': | |
'EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH' | |
}, | |
s3: { | |
s3SchemaVersion: '1.0', | |
configurationId: 'testConfigRule', | |
bucket: { | |
name, | |
ownerIdentity: { | |
principalId: 'EXAMPLE' | |
}, | |
arn: 'arn:aws:s3:::example-bucket' | |
}, | |
object: { | |
key, | |
size: 1024, | |
eTag: '0123456789abcdef0123456789abcdef', | |
sequencer: '0A1B2C3D4E5F678901' | |
} | |
} | |
} | |
] | |
}) | |
// Workflow action invoke | |
export const generateWorkflowActionLambdaInvokeEvent = ( | |
workflow: WorkflowDefinition, | |
action: string, | |
context?: Partial<ActionContext> | |
): ActionEvent => { | |
const attributes = { | |
accountId: getConfig('mockId'), | |
workflowId: generateId(), | |
callerId: generateId(), | |
processId: generateId(), | |
serviceId: generateId() | |
} | |
return { | |
action, | |
workflow, | |
context: generateActionContext({ config: attributes, ...context }), | |
attributes | |
} | |
} | |
// Lambda SQS event - sent to recipient of queue event | |
export const generateSQSActionQueuedEvent = () => ({ | |
Records: [ | |
{ | |
messageId: '9cf06c9b-e919-4ef9-8485-3d13c347a4d1', | |
receiptHandle: 'AQEBJRZxkQUWQYAwBMPpN4...rVCoU70HTdEVH4eKZXuPUVBw==', | |
body: '{"fooId":"222c74e3140-f132-11e9-aaae-4b1bd7694168"}', | |
attributes: { | |
ApproximateReceiveCount: '1', | |
SentTimestamp: '1530189332727', | |
SenderId: 'AROAI62MWIO3S4UBJVPVG:sqs-flooder', | |
ApproximateFirstReceiveTimestamp: '1530189332728' | |
}, | |
messageAttributes: { | |
someId: { | |
Type: 'String', | |
Value: 'fb6a1900-acc5-11e9-8742-0d36cbe54355' | |
} | |
}, | |
md5OfBody: '7ce3453347fd9bd30281384c304a1f9d', | |
eventSource: 'aws:sqs', | |
eventSourceARN: 'arn:aws:sqs:us-east-1:XXXXXXXX:test-sqs-trigger-queue', | |
awsRegion: 'us-east-1' | |
} | |
] | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment