Compare commits
6 Commits
master
...
trial-by-f
Author | SHA1 | Date | |
---|---|---|---|
|
000024426b | ||
|
66524e5d79 | ||
|
876cd0d84f | ||
|
ace3670339 | ||
|
54f9250e53 | ||
|
2e0f6036b9 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,7 @@
|
||||
.now
|
||||
node_modules
|
||||
.env
|
||||
.serverless
|
||||
|
||||
# Environment Variables
|
||||
.env
|
||||
|
82
.serverless/cloudformation-template-create-stack.json
Normal file
82
.serverless/cloudformation-template-create-stack.json
Normal file
@ -0,0 +1,82 @@
|
||||
{
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "The AWS CloudFormation template for this Serverless application",
|
||||
"Resources": {
|
||||
"ServerlessDeploymentBucket": {
|
||||
"Type": "AWS::S3::Bucket",
|
||||
"Properties": {
|
||||
"BucketEncryption": {
|
||||
"ServerSideEncryptionConfiguration": [
|
||||
{
|
||||
"ServerSideEncryptionByDefault": {
|
||||
"SSEAlgorithm": "AES256"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"ServerlessDeploymentBucketPolicy": {
|
||||
"Type": "AWS::S3::BucketPolicy",
|
||||
"Properties": {
|
||||
"Bucket": {
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
},
|
||||
"PolicyDocument": {
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "s3:*",
|
||||
"Effect": "Deny",
|
||||
"Principal": "*",
|
||||
"Resource": [
|
||||
{
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":s3:::",
|
||||
{
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
},
|
||||
"/*"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":s3:::",
|
||||
{
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
],
|
||||
"Condition": {
|
||||
"Bool": {
|
||||
"aws:SecureTransport": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Outputs": {
|
||||
"ServerlessDeploymentBucketName": {
|
||||
"Value": {
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
404
.serverless/cloudformation-template-update-stack.json
Normal file
404
.serverless/cloudformation-template-update-stack.json
Normal file
@ -0,0 +1,404 @@
|
||||
{
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "The AWS CloudFormation template for this Serverless application",
|
||||
"Resources": {
|
||||
"ServerlessDeploymentBucket": {
|
||||
"Type": "AWS::S3::Bucket",
|
||||
"Properties": {
|
||||
"BucketEncryption": {
|
||||
"ServerSideEncryptionConfiguration": [
|
||||
{
|
||||
"ServerSideEncryptionByDefault": {
|
||||
"SSEAlgorithm": "AES256"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"ServerlessDeploymentBucketPolicy": {
|
||||
"Type": "AWS::S3::BucketPolicy",
|
||||
"Properties": {
|
||||
"Bucket": {
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
},
|
||||
"PolicyDocument": {
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "s3:*",
|
||||
"Effect": "Deny",
|
||||
"Principal": "*",
|
||||
"Resource": [
|
||||
{
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":s3:::",
|
||||
{
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
},
|
||||
"/*"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":s3:::",
|
||||
{
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
],
|
||||
"Condition": {
|
||||
"Bool": {
|
||||
"aws:SecureTransport": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"AppLogGroup": {
|
||||
"Type": "AWS::Logs::LogGroup",
|
||||
"Properties": {
|
||||
"LogGroupName": "/aws/lambda/localstack-lambda-dev-app"
|
||||
}
|
||||
},
|
||||
"IamRoleLambdaExecution": {
|
||||
"Type": "AWS::IAM::Role",
|
||||
"Properties": {
|
||||
"AssumeRolePolicyDocument": {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Service": [
|
||||
"lambda.amazonaws.com"
|
||||
]
|
||||
},
|
||||
"Action": [
|
||||
"sts:AssumeRole"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"Policies": [
|
||||
{
|
||||
"PolicyName": {
|
||||
"Fn::Join": [
|
||||
"-",
|
||||
[
|
||||
"localstack-lambda",
|
||||
"dev",
|
||||
"lambda"
|
||||
]
|
||||
]
|
||||
},
|
||||
"PolicyDocument": {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"logs:CreateLogStream",
|
||||
"logs:CreateLogGroup"
|
||||
],
|
||||
"Resource": [
|
||||
{
|
||||
"Fn::Sub": "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/localstack-lambda-dev*:*"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"logs:PutLogEvents"
|
||||
],
|
||||
"Resource": [
|
||||
{
|
||||
"Fn::Sub": "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/localstack-lambda-dev*:*:*"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"Path": "/",
|
||||
"RoleName": {
|
||||
"Fn::Join": [
|
||||
"-",
|
||||
[
|
||||
"localstack-lambda",
|
||||
"dev",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
"lambdaRole"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"AppLambdaFunction": {
|
||||
"Type": "AWS::Lambda::Function",
|
||||
"Properties": {
|
||||
"Code": {
|
||||
"S3Bucket": {
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
},
|
||||
"S3Key": "serverless/localstack-lambda/dev/1620092918879-2021-05-04T01:48:38.879Z/localstack-lambda.zip"
|
||||
},
|
||||
"Handler": "api/server.handler",
|
||||
"Runtime": "nodejs12.x",
|
||||
"FunctionName": "localstack-lambda-dev-app",
|
||||
"MemorySize": 512,
|
||||
"Timeout": 6,
|
||||
"Role": {
|
||||
"Fn::GetAtt": [
|
||||
"IamRoleLambdaExecution",
|
||||
"Arn"
|
||||
]
|
||||
}
|
||||
},
|
||||
"DependsOn": [
|
||||
"AppLogGroup"
|
||||
]
|
||||
},
|
||||
"AppLambdaVersionuvewJZYompWGhR7PreRGORUZWWNhF3zGn5TtfgsWIs": {
|
||||
"Type": "AWS::Lambda::Version",
|
||||
"DeletionPolicy": "Retain",
|
||||
"Properties": {
|
||||
"FunctionName": {
|
||||
"Ref": "AppLambdaFunction"
|
||||
},
|
||||
"CodeSha256": "3b8ZgXd14AZAi3l2N89aVQ4LE9Ty39V8tHZhL6Q1t3w="
|
||||
}
|
||||
},
|
||||
"ApiGatewayRestApi": {
|
||||
"Type": "AWS::ApiGateway::RestApi",
|
||||
"Properties": {
|
||||
"Name": "dev-localstack-lambda",
|
||||
"EndpointConfiguration": {
|
||||
"Types": [
|
||||
"EDGE"
|
||||
]
|
||||
},
|
||||
"Policy": ""
|
||||
}
|
||||
},
|
||||
"ApiGatewayResourceProxyVar": {
|
||||
"Type": "AWS::ApiGateway::Resource",
|
||||
"Properties": {
|
||||
"ParentId": {
|
||||
"Fn::GetAtt": [
|
||||
"ApiGatewayRestApi",
|
||||
"RootResourceId"
|
||||
]
|
||||
},
|
||||
"PathPart": "{proxy+}",
|
||||
"RestApiId": {
|
||||
"Ref": "ApiGatewayRestApi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ApiGatewayMethodAny": {
|
||||
"Type": "AWS::ApiGateway::Method",
|
||||
"Properties": {
|
||||
"HttpMethod": "ANY",
|
||||
"RequestParameters": {},
|
||||
"ResourceId": {
|
||||
"Fn::GetAtt": [
|
||||
"ApiGatewayRestApi",
|
||||
"RootResourceId"
|
||||
]
|
||||
},
|
||||
"RestApiId": {
|
||||
"Ref": "ApiGatewayRestApi"
|
||||
},
|
||||
"ApiKeyRequired": false,
|
||||
"AuthorizationType": "NONE",
|
||||
"Integration": {
|
||||
"IntegrationHttpMethod": "POST",
|
||||
"Type": "AWS_PROXY",
|
||||
"Uri": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":apigateway:",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
":lambda:path/2015-03-31/functions/",
|
||||
{
|
||||
"Fn::GetAtt": [
|
||||
"AppLambdaFunction",
|
||||
"Arn"
|
||||
]
|
||||
},
|
||||
"/invocations"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"MethodResponses": []
|
||||
}
|
||||
},
|
||||
"ApiGatewayMethodProxyVarAny": {
|
||||
"Type": "AWS::ApiGateway::Method",
|
||||
"Properties": {
|
||||
"HttpMethod": "ANY",
|
||||
"RequestParameters": {},
|
||||
"ResourceId": {
|
||||
"Ref": "ApiGatewayResourceProxyVar"
|
||||
},
|
||||
"RestApiId": {
|
||||
"Ref": "ApiGatewayRestApi"
|
||||
},
|
||||
"ApiKeyRequired": false,
|
||||
"AuthorizationType": "NONE",
|
||||
"Integration": {
|
||||
"IntegrationHttpMethod": "POST",
|
||||
"Type": "AWS_PROXY",
|
||||
"Uri": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":apigateway:",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
":lambda:path/2015-03-31/functions/",
|
||||
{
|
||||
"Fn::GetAtt": [
|
||||
"AppLambdaFunction",
|
||||
"Arn"
|
||||
]
|
||||
},
|
||||
"/invocations"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"MethodResponses": []
|
||||
}
|
||||
},
|
||||
"ApiGatewayDeployment1620092914902": {
|
||||
"Type": "AWS::ApiGateway::Deployment",
|
||||
"Properties": {
|
||||
"RestApiId": {
|
||||
"Ref": "ApiGatewayRestApi"
|
||||
},
|
||||
"StageName": "dev"
|
||||
},
|
||||
"DependsOn": [
|
||||
"ApiGatewayMethodAny",
|
||||
"ApiGatewayMethodProxyVarAny"
|
||||
]
|
||||
},
|
||||
"AppLambdaPermissionApiGateway": {
|
||||
"Type": "AWS::Lambda::Permission",
|
||||
"Properties": {
|
||||
"FunctionName": {
|
||||
"Fn::GetAtt": [
|
||||
"AppLambdaFunction",
|
||||
"Arn"
|
||||
]
|
||||
},
|
||||
"Action": "lambda:InvokeFunction",
|
||||
"Principal": "apigateway.amazonaws.com",
|
||||
"SourceArn": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":execute-api:",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
":",
|
||||
{
|
||||
"Ref": "AWS::AccountId"
|
||||
},
|
||||
":",
|
||||
{
|
||||
"Ref": "ApiGatewayRestApi"
|
||||
},
|
||||
"/*/*"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Outputs": {
|
||||
"ServerlessDeploymentBucketName": {
|
||||
"Value": {
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
},
|
||||
"Export": {
|
||||
"Name": "sls-localstack-lambda-dev-ServerlessDeploymentBucketName"
|
||||
}
|
||||
},
|
||||
"AppLambdaFunctionQualifiedArn": {
|
||||
"Description": "Current Lambda function version",
|
||||
"Value": {
|
||||
"Ref": "AppLambdaVersionuvewJZYompWGhR7PreRGORUZWWNhF3zGn5TtfgsWIs"
|
||||
},
|
||||
"Export": {
|
||||
"Name": "sls-localstack-lambda-dev-AppLambdaFunctionQualifiedArn"
|
||||
}
|
||||
},
|
||||
"ServiceEndpoint": {
|
||||
"Description": "URL of the service endpoint",
|
||||
"Value": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"https://",
|
||||
{
|
||||
"Ref": "ApiGatewayRestApi"
|
||||
},
|
||||
".execute-api.",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
".",
|
||||
{
|
||||
"Ref": "AWS::URLSuffix"
|
||||
},
|
||||
"/dev"
|
||||
]
|
||||
]
|
||||
},
|
||||
"Export": {
|
||||
"Name": "sls-localstack-lambda-dev-ServiceEndpoint"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
.serverless/localstack-lambda.zip
Normal file
BIN
.serverless/localstack-lambda.zip
Normal file
Binary file not shown.
546
.serverless/serverless-state.json
Normal file
546
.serverless/serverless-state.json
Normal file
@ -0,0 +1,546 @@
|
||||
{
|
||||
"service": {
|
||||
"service": "localstack-lambda",
|
||||
"serviceObject": {
|
||||
"name": "localstack-lambda"
|
||||
},
|
||||
"provider": {
|
||||
"name": "aws",
|
||||
"runtime": "nodejs12.x",
|
||||
"stage": "dev",
|
||||
"region": "us-east-1",
|
||||
"memorySize": 512,
|
||||
"variableSyntax": "\\${([^{}:]+?(?:\\(|:)(?:[^:{}][^{}]*?)?)}",
|
||||
"versionFunctions": true,
|
||||
"compiledCloudFormationTemplate": {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "The AWS CloudFormation template for this Serverless application",
|
||||
"Resources": {
|
||||
"ServerlessDeploymentBucket": {
|
||||
"Type": "AWS::S3::Bucket",
|
||||
"Properties": {
|
||||
"BucketEncryption": {
|
||||
"ServerSideEncryptionConfiguration": [
|
||||
{
|
||||
"ServerSideEncryptionByDefault": {
|
||||
"SSEAlgorithm": "AES256"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"ServerlessDeploymentBucketPolicy": {
|
||||
"Type": "AWS::S3::BucketPolicy",
|
||||
"Properties": {
|
||||
"Bucket": {
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
},
|
||||
"PolicyDocument": {
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "s3:*",
|
||||
"Effect": "Deny",
|
||||
"Principal": "*",
|
||||
"Resource": [
|
||||
{
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":s3:::",
|
||||
{
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
},
|
||||
"/*"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":s3:::",
|
||||
{
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
],
|
||||
"Condition": {
|
||||
"Bool": {
|
||||
"aws:SecureTransport": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"AppLogGroup": {
|
||||
"Type": "AWS::Logs::LogGroup",
|
||||
"Properties": {
|
||||
"LogGroupName": "/aws/lambda/localstack-lambda-dev-app"
|
||||
}
|
||||
},
|
||||
"IamRoleLambdaExecution": {
|
||||
"Type": "AWS::IAM::Role",
|
||||
"Properties": {
|
||||
"AssumeRolePolicyDocument": {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Service": [
|
||||
"lambda.amazonaws.com"
|
||||
]
|
||||
},
|
||||
"Action": [
|
||||
"sts:AssumeRole"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"Policies": [
|
||||
{
|
||||
"PolicyName": {
|
||||
"Fn::Join": [
|
||||
"-",
|
||||
[
|
||||
"localstack-lambda",
|
||||
"dev",
|
||||
"lambda"
|
||||
]
|
||||
]
|
||||
},
|
||||
"PolicyDocument": {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"logs:CreateLogStream",
|
||||
"logs:CreateLogGroup"
|
||||
],
|
||||
"Resource": [
|
||||
{
|
||||
"Fn::Sub": "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/localstack-lambda-dev*:*"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"logs:PutLogEvents"
|
||||
],
|
||||
"Resource": [
|
||||
{
|
||||
"Fn::Sub": "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/localstack-lambda-dev*:*:*"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"Path": "/",
|
||||
"RoleName": {
|
||||
"Fn::Join": [
|
||||
"-",
|
||||
[
|
||||
"localstack-lambda",
|
||||
"dev",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
"lambdaRole"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"AppLambdaFunction": {
|
||||
"Type": "AWS::Lambda::Function",
|
||||
"Properties": {
|
||||
"Code": {
|
||||
"S3Bucket": {
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
},
|
||||
"S3Key": "serverless/localstack-lambda/dev/1620092918879-2021-05-04T01:48:38.879Z/localstack-lambda.zip"
|
||||
},
|
||||
"Handler": "api/server.handler",
|
||||
"Runtime": "nodejs12.x",
|
||||
"FunctionName": "localstack-lambda-dev-app",
|
||||
"MemorySize": 512,
|
||||
"Timeout": 6,
|
||||
"Role": {
|
||||
"Fn::GetAtt": [
|
||||
"IamRoleLambdaExecution",
|
||||
"Arn"
|
||||
]
|
||||
}
|
||||
},
|
||||
"DependsOn": [
|
||||
"AppLogGroup"
|
||||
]
|
||||
},
|
||||
"AppLambdaVersionuvewJZYompWGhR7PreRGORUZWWNhF3zGn5TtfgsWIs": {
|
||||
"Type": "AWS::Lambda::Version",
|
||||
"DeletionPolicy": "Retain",
|
||||
"Properties": {
|
||||
"FunctionName": {
|
||||
"Ref": "AppLambdaFunction"
|
||||
},
|
||||
"CodeSha256": "3b8ZgXd14AZAi3l2N89aVQ4LE9Ty39V8tHZhL6Q1t3w="
|
||||
}
|
||||
},
|
||||
"ApiGatewayRestApi": {
|
||||
"Type": "AWS::ApiGateway::RestApi",
|
||||
"Properties": {
|
||||
"Name": "dev-localstack-lambda",
|
||||
"EndpointConfiguration": {
|
||||
"Types": [
|
||||
"EDGE"
|
||||
]
|
||||
},
|
||||
"Policy": ""
|
||||
}
|
||||
},
|
||||
"ApiGatewayResourceProxyVar": {
|
||||
"Type": "AWS::ApiGateway::Resource",
|
||||
"Properties": {
|
||||
"ParentId": {
|
||||
"Fn::GetAtt": [
|
||||
"ApiGatewayRestApi",
|
||||
"RootResourceId"
|
||||
]
|
||||
},
|
||||
"PathPart": "{proxy+}",
|
||||
"RestApiId": {
|
||||
"Ref": "ApiGatewayRestApi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ApiGatewayMethodAny": {
|
||||
"Type": "AWS::ApiGateway::Method",
|
||||
"Properties": {
|
||||
"HttpMethod": "ANY",
|
||||
"RequestParameters": {},
|
||||
"ResourceId": {
|
||||
"Fn::GetAtt": [
|
||||
"ApiGatewayRestApi",
|
||||
"RootResourceId"
|
||||
]
|
||||
},
|
||||
"RestApiId": {
|
||||
"Ref": "ApiGatewayRestApi"
|
||||
},
|
||||
"ApiKeyRequired": false,
|
||||
"AuthorizationType": "NONE",
|
||||
"Integration": {
|
||||
"IntegrationHttpMethod": "POST",
|
||||
"Type": "AWS_PROXY",
|
||||
"Uri": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":apigateway:",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
":lambda:path/2015-03-31/functions/",
|
||||
{
|
||||
"Fn::GetAtt": [
|
||||
"AppLambdaFunction",
|
||||
"Arn"
|
||||
]
|
||||
},
|
||||
"/invocations"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"MethodResponses": []
|
||||
}
|
||||
},
|
||||
"ApiGatewayMethodProxyVarAny": {
|
||||
"Type": "AWS::ApiGateway::Method",
|
||||
"Properties": {
|
||||
"HttpMethod": "ANY",
|
||||
"RequestParameters": {},
|
||||
"ResourceId": {
|
||||
"Ref": "ApiGatewayResourceProxyVar"
|
||||
},
|
||||
"RestApiId": {
|
||||
"Ref": "ApiGatewayRestApi"
|
||||
},
|
||||
"ApiKeyRequired": false,
|
||||
"AuthorizationType": "NONE",
|
||||
"Integration": {
|
||||
"IntegrationHttpMethod": "POST",
|
||||
"Type": "AWS_PROXY",
|
||||
"Uri": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":apigateway:",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
":lambda:path/2015-03-31/functions/",
|
||||
{
|
||||
"Fn::GetAtt": [
|
||||
"AppLambdaFunction",
|
||||
"Arn"
|
||||
]
|
||||
},
|
||||
"/invocations"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"MethodResponses": []
|
||||
}
|
||||
},
|
||||
"ApiGatewayDeployment1620092914902": {
|
||||
"Type": "AWS::ApiGateway::Deployment",
|
||||
"Properties": {
|
||||
"RestApiId": {
|
||||
"Ref": "ApiGatewayRestApi"
|
||||
},
|
||||
"StageName": "dev"
|
||||
},
|
||||
"DependsOn": [
|
||||
"ApiGatewayMethodAny",
|
||||
"ApiGatewayMethodProxyVarAny"
|
||||
]
|
||||
},
|
||||
"AppLambdaPermissionApiGateway": {
|
||||
"Type": "AWS::Lambda::Permission",
|
||||
"Properties": {
|
||||
"FunctionName": {
|
||||
"Fn::GetAtt": [
|
||||
"AppLambdaFunction",
|
||||
"Arn"
|
||||
]
|
||||
},
|
||||
"Action": "lambda:InvokeFunction",
|
||||
"Principal": "apigateway.amazonaws.com",
|
||||
"SourceArn": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":execute-api:",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
":",
|
||||
{
|
||||
"Ref": "AWS::AccountId"
|
||||
},
|
||||
":",
|
||||
{
|
||||
"Ref": "ApiGatewayRestApi"
|
||||
},
|
||||
"/*/*"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Outputs": {
|
||||
"ServerlessDeploymentBucketName": {
|
||||
"Value": {
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
},
|
||||
"Export": {
|
||||
"Name": "sls-localstack-lambda-dev-ServerlessDeploymentBucketName"
|
||||
}
|
||||
},
|
||||
"AppLambdaFunctionQualifiedArn": {
|
||||
"Description": "Current Lambda function version",
|
||||
"Value": {
|
||||
"Ref": "AppLambdaVersionuvewJZYompWGhR7PreRGORUZWWNhF3zGn5TtfgsWIs"
|
||||
},
|
||||
"Export": {
|
||||
"Name": "sls-localstack-lambda-dev-AppLambdaFunctionQualifiedArn"
|
||||
}
|
||||
},
|
||||
"ServiceEndpoint": {
|
||||
"Description": "URL of the service endpoint",
|
||||
"Value": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"https://",
|
||||
{
|
||||
"Ref": "ApiGatewayRestApi"
|
||||
},
|
||||
".execute-api.",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
".",
|
||||
{
|
||||
"Ref": "AWS::URLSuffix"
|
||||
},
|
||||
"/dev"
|
||||
]
|
||||
]
|
||||
},
|
||||
"Export": {
|
||||
"Name": "sls-localstack-lambda-dev-ServiceEndpoint"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"coreCloudFormationTemplate": {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "The AWS CloudFormation template for this Serverless application",
|
||||
"Resources": {
|
||||
"ServerlessDeploymentBucket": {
|
||||
"Type": "AWS::S3::Bucket",
|
||||
"Properties": {
|
||||
"BucketEncryption": {
|
||||
"ServerSideEncryptionConfiguration": [
|
||||
{
|
||||
"ServerSideEncryptionByDefault": {
|
||||
"SSEAlgorithm": "AES256"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"ServerlessDeploymentBucketPolicy": {
|
||||
"Type": "AWS::S3::BucketPolicy",
|
||||
"Properties": {
|
||||
"Bucket": {
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
},
|
||||
"PolicyDocument": {
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "s3:*",
|
||||
"Effect": "Deny",
|
||||
"Principal": "*",
|
||||
"Resource": [
|
||||
{
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":s3:::",
|
||||
{
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
},
|
||||
"/*"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"arn:",
|
||||
{
|
||||
"Ref": "AWS::Partition"
|
||||
},
|
||||
":s3:::",
|
||||
{
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
],
|
||||
"Condition": {
|
||||
"Bool": {
|
||||
"aws:SecureTransport": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Outputs": {
|
||||
"ServerlessDeploymentBucketName": {
|
||||
"Value": {
|
||||
"Ref": "ServerlessDeploymentBucket"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vpc": {}
|
||||
},
|
||||
"pluginsData": {},
|
||||
"functions": {
|
||||
"app": {
|
||||
"handler": "api/server.handler",
|
||||
"events": [
|
||||
{
|
||||
"http": "ANY /"
|
||||
},
|
||||
{
|
||||
"http": "ANY {proxy+}"
|
||||
}
|
||||
],
|
||||
"name": "localstack-lambda-dev-app",
|
||||
"package": {},
|
||||
"memory": 512,
|
||||
"timeout": 6,
|
||||
"runtime": "nodejs12.x",
|
||||
"vpc": {},
|
||||
"versionLogicalId": "AppLambdaVersionuvewJZYompWGhR7PreRGORUZWWNhF3zGn5TtfgsWIs"
|
||||
}
|
||||
},
|
||||
"configValidationMode": "warn",
|
||||
"serviceFilename": "serverless.yml",
|
||||
"layers": {},
|
||||
"initialServerlessConfig": {
|
||||
"service": {
|
||||
"$ref": "$[\"service\"][\"serviceObject\"]"
|
||||
},
|
||||
"frameworkVersion": "2",
|
||||
"provider": {
|
||||
"$ref": "$[\"service\"][\"provider\"]"
|
||||
},
|
||||
"functions": {
|
||||
"$ref": "$[\"service\"][\"functions\"]"
|
||||
}
|
||||
},
|
||||
"isDashboardMonitoringPreconfigured": false,
|
||||
"artifact": "/Users/duncanphelps/Documents/Learning/Javascript/sheetaki/sheetaki/.serverless/localstack-lambda.zip"
|
||||
},
|
||||
"package": {
|
||||
"artifactDirectoryName": "serverless/localstack-lambda/dev/1620092918879-2021-05-04T01:48:38.879Z",
|
||||
"artifact": "localstack-lambda.zip"
|
||||
}
|
||||
}
|
13
api/file/index.js
Normal file
13
api/file/index.js
Normal file
@ -0,0 +1,13 @@
|
||||
const URL = require('url');
|
||||
fs = require('fs');
|
||||
const { getFile } = require('../s3');
|
||||
|
||||
module.exports = function (req, res) {
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
const url = URL.parse(req.url, true);
|
||||
|
||||
if (!url.query.filename) return res.status(400).send("Must specify filename");
|
||||
if (url.query.filename){
|
||||
getFile(req, res, url, url.query.filename);
|
||||
}
|
||||
};
|
38
api/s3.js
Normal file
38
api/s3.js
Normal file
@ -0,0 +1,38 @@
|
||||
require('dotenv').config();
|
||||
const S3 = require('aws-sdk/clients/s3');
|
||||
const do_wb = require('../src/util');
|
||||
|
||||
const bucketName = process.env.AWS_BUCKET_NAME
|
||||
const region = process.env.AWS_BUCKET_REGION
|
||||
const secretAccessKey = process.env.AWS_SECRET_KEY
|
||||
const accessKeyId = process.env.AWS_ACCESS_KEY
|
||||
|
||||
const s3 = new S3({
|
||||
region,
|
||||
accessKeyId,
|
||||
secretAccessKey
|
||||
})
|
||||
|
||||
function uploadFile(filename, file){
|
||||
filename = filename.split("/");
|
||||
filename = filename[filename.length - 1]
|
||||
const uploadParams = {
|
||||
Bucket: bucketName,
|
||||
Key: filename,
|
||||
Body: file
|
||||
};
|
||||
return s3.upload(uploadParams).promise()
|
||||
}
|
||||
exports.uploadFile = uploadFile;
|
||||
|
||||
function getFile(req, res, url, filename){
|
||||
const params = {
|
||||
Key: filename,
|
||||
Bucket: bucketName,
|
||||
}
|
||||
s3.getObject(params, function (err, data) {
|
||||
if (err) return res.status(500).send(err.message || err);
|
||||
do_wb(req, data.Body, url, res);
|
||||
});
|
||||
}
|
||||
exports.getFile = getFile;
|
44
api/save/index.js
Normal file
44
api/save/index.js
Normal file
@ -0,0 +1,44 @@
|
||||
const URL = require('url'), fs = require('fs');
|
||||
const do_wb = require('../../src/util');
|
||||
const formidable = require('formidable-serverless');
|
||||
const tmp = require('tmp');
|
||||
const AWS = require('aws-sdk');
|
||||
const { uploadFile } = require('../s3');
|
||||
|
||||
module.exports = function (req, res) {
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
const url = URL.parse(req.url, true);
|
||||
// const s3 = new AWS.S3({ endpoint: 'http://localhost:4566', s3ForcePathStyle: true });
|
||||
const s3 = new AWS.S3();
|
||||
|
||||
/* parse form data */
|
||||
const form = formidable({ multiples: true, maxFileSize: 2 * 1024 * 1024 });
|
||||
|
||||
/*create temp file*/
|
||||
const newFile = () => {
|
||||
const tmpobj = tmp.fileSync({postfix: '.xlsx'});
|
||||
return tmpobj.name;
|
||||
}
|
||||
|
||||
form.parse(req, (err, fields, files) => {
|
||||
if (err) return res.status(400).send(err.message || err);
|
||||
if (!url.query) url.query = fields;
|
||||
["N", "t"].forEach(k => { if (!url.query[k] && fields[k] != null) url.query[k] = fields[k]; });
|
||||
|
||||
/* look for first uploaded file entry */
|
||||
if (!files) return res.status(400).send("Missing file");
|
||||
const fentries = Object.entries(files);
|
||||
if (fentries.length == 0) return res.status(400).send("Missing file");
|
||||
|
||||
/* read file */
|
||||
const file = fentries[0][1];
|
||||
|
||||
fs.readFile(file.path, async (err, body) => {
|
||||
if (err) return res.status(500).send(err.message || err);
|
||||
const tmpFile = newFile();
|
||||
const result = await uploadFile(tmpFile, body);
|
||||
console.log(result);
|
||||
res.send(result.key);
|
||||
});
|
||||
});
|
||||
};
|
@ -1,7 +1,10 @@
|
||||
const serverless = require('serverless-http');
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
const data = require('./data/index');
|
||||
const upload = require('./upload/index');
|
||||
const save = require('./save/index');
|
||||
const file = require('./file/index');
|
||||
const bodyParser = require('body-parser');
|
||||
const port = 3000;
|
||||
|
||||
@ -12,7 +15,10 @@ app.use(express.static('public'));
|
||||
|
||||
app.use('/api/data', data);
|
||||
app.use('/api/upload', upload);
|
||||
app.use('/api/save', save);
|
||||
app.use('/api/file', file);
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Listening on port: ${port}`);
|
||||
});
|
||||
// app.listen(port, () => {
|
||||
// console.log(`Listening on port: ${port}`);
|
||||
// });
|
||||
module.exports.handler = serverless(app);
|
14
docker-compose.yml
Executable file
14
docker-compose.yml
Executable file
@ -0,0 +1,14 @@
|
||||
version: '3.1'
|
||||
|
||||
services:
|
||||
localstack:
|
||||
image: localstack/localstack:latest
|
||||
environment:
|
||||
- AWS_DEFAULT_REGION=us-east-1
|
||||
- EDGE_PORT=4566
|
||||
- SERVICES=lambda,s3,cloudformation,sts,apigateway,iam,route53
|
||||
ports:
|
||||
- '4566-4597:4566-4597'
|
||||
volumes:
|
||||
- "${TEMPDIR:-/tmp/localstack}:/temp/localstack"
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
6
localstack_endpoints.json
Executable file
6
localstack_endpoints.json
Executable file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"CloudFormation" : "http://localhost:4566",
|
||||
"CloudWatch" : "http://localhost:4566",
|
||||
"Lambda" : "http://localhost:4566",
|
||||
"S3" : "http://localhost:4566"
|
||||
}
|
1541
package-lock.json
generated
1541
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -11,10 +11,15 @@
|
||||
"excel"
|
||||
],
|
||||
"dependencies": {
|
||||
"aws-sdk": "^2.896.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"dotenv": "^8.2.0",
|
||||
"express": "^4.17.1",
|
||||
"formidable-serverless": "",
|
||||
"request": "",
|
||||
"serverless-http": "^2.7.0",
|
||||
"serverless-localstack": "^0.4.30",
|
||||
"tmp": "^0.2.1",
|
||||
"xlsx": ""
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -66,6 +66,11 @@ for(var i = 0; i < URLS.length; ++i) {
|
||||
|
||||
<input type="submit" value="Click here to upload!">
|
||||
</form>
|
||||
<form method="POST" action="api/save" enctype="multipart/form-data"><input type="hidden" name="N" value="0">
|
||||
<label for="file">Upload a file</label>
|
||||
<input type="file" name="file" id="file">
|
||||
<input type="submit" value="Click here to save!">
|
||||
</form>
|
||||
|
||||
<b>This service is powered by <a href="http://sheetjs.com">SheetJS</a></b>
|
||||
|
||||
|
28
serverless.yml
Executable file
28
serverless.yml
Executable file
@ -0,0 +1,28 @@
|
||||
service: localstack-lambda
|
||||
# plugins:
|
||||
# - serverless-localstack
|
||||
|
||||
# custom:
|
||||
# localstack:
|
||||
# debug: true
|
||||
# stages:
|
||||
# - local
|
||||
# - dev
|
||||
# host: http://localhost # optional - LocalStack host to connect to
|
||||
# edgePort: 4566 # optional - LocalStack edge port to connect to
|
||||
# endpointFile: localstack_endpoints.json
|
||||
|
||||
frameworkVersion: '2'
|
||||
|
||||
provider:
|
||||
name: aws
|
||||
runtime: nodejs12.x
|
||||
stage: dev
|
||||
region: us-east-1
|
||||
memorySize: 512
|
||||
functions:
|
||||
app:
|
||||
handler: api/server.handler
|
||||
events:
|
||||
- http: ANY /
|
||||
- http: 'ANY {proxy+}'
|
11
src/util.js
11
src/util.js
@ -9,7 +9,13 @@ module.exports = function(req, body, url, res) {
|
||||
|
||||
/* N parameter specifies worksheet index */
|
||||
const N = url.query.N ? parseInt(url.query.N,10) : 0;
|
||||
|
||||
const addr = url.query.addr || null;
|
||||
const val = url.query.val || null;
|
||||
|
||||
if (addr != null && val != null) {
|
||||
XLSX.utils.sheet_add_aoa(wb.Sheets[wb.SheetNames[0]], [[val]], { origin: addr });
|
||||
}
|
||||
/* -1 -> return sheet names */
|
||||
if(N < 0) switch(url.query.t || "csv") {
|
||||
case "json": return res.status(200).send(JSON.stringify(wb.SheetNames.join("\n")));
|
||||
@ -28,6 +34,11 @@ module.exports = function(req, body, url, res) {
|
||||
switch(url.query.t) {
|
||||
case "json": return res.status(200).json(XLSX.utils.sheet_to_json(ws, {header:1, raw:true}));
|
||||
case "html": return XLSX.stream.to_html(ws).pipe(res);
|
||||
case "file":
|
||||
const buf = XLSX.write(wb, { type: "buffer", bookType: "xlsx" });
|
||||
res.header("Content-Type", "application/vnd.ms-excel");
|
||||
res.header("Content-Disposition", 'attachment; filename="test2.xlsx"');
|
||||
return res.status(200).end(buf);
|
||||
default: return XLSX.stream.to_csv(ws).pipe(res);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user