Node.js - Amazon Web Services support for TypeScript

AWS Lambda

Lambda services allow executing some source code on the cloud. The execution can be set to be triggered by some AWS events. Lambda functions can be deployed using several deployment frameworks. The supported deployment frameworks are listed on this page. When a lambda function is created and its runtime is Node.js, the TypeScript and Frameworks extension is responsible for linking the lambda objects and their triggers with the TypeScript handler functions.

Basic example

Let us consider a source code defining a lambda function that has two triggers: an SQS queue and an API Gateway. The lambda function has a nodejs runtime and the handler function is given by the handler function fullname. If the lambda function is deployed using a supported deployment framework (such as CloudFormation), the analysis will create a lambda function, an SQS receiver, and an API Gateway objects. Each of these objects has a runtime property (nodejs) and a handler property with the function fullname.  If the current extension finds a TypeScript function matching the handler fullname a link to that function will be added from the lambda function, the SQS queue, and the API Gateway objects.

Lambda invocation using SDK

The SDK provides APIs to execute (i.e. invoke) lambda function. The following APIs are supported:

  • invoke method of the Lambda “aws-sdk” client of the SDK V2
  • InvokeCommand of the SDK V3

Example

When analyzing the following source code:

import * as AWS from 'aws-sdk'
// Set region

function my_invoke(){
  AWS.config.update({region: 'REGION'});
  var lambda = new AWS.Lambda();
  var params = {
    FunctionName: 'mylambda', /* required */
    //...
  };

  lambda.invoke(params, function(err, data) {
    //...
  });
}

call to AWS lambda function object named mylambda is created. com.castsoftware.wbslinker links that call to lambda object to AWS Lambda Function objects having the same name: 

AWS SNS

The following APIs are supported:

SDK V2

The publish and subscribe methods of the SNS client are supported:

import AWS from 'aws-sdk'
const snsClient = new AWS.SNS({...})
snsClient.publish(...)
snsClient.subscribe(...)

SDK V3

The PublishCommand and SubscribeCommand (which are used with the snsClient.send method) are supported:

import { SNSClient, PublishCommand, SubscribeCOmmand } from "@aws-sdk/client-sns";
const snsClient = new SNSClient({ region: REGION });
snsClient.send(new PublishCommand(params))
snsClient.send(new SubscribeCommand(params))

Detailed support

A Nodejs SNS Publisher object is created whenever a publication to a topic is found by the analyzer. Its name is that of the topic. For subscriptions, a Nodejs SNS Subscriber object is created. Its name is that of the topic. Then for each supported protocol, an object is created with a callLink from the subscriber to that object. The following protocols are supported:

Protocol Object created Object name
email Nodejs Email an Email (the email addresses are not evaluated)
sms Nodejs SMS an SMS (the SMS numbers are not evaluated)
http/https Nodejs Post Service the url (evaluated from the endpoint)
sqs Nodejs AWS Simple Queue Service Publisher the name of the queue (evaluated from the endpoint)
lambda Nodejs Call to AWS Lambda Function the name of the lambda function (evaluated from the endpoint)

Example

When analyzing the following source code:

import {CreateTopicCommand, SNSClient, SubscribeCommand, PublishCommand } from "@aws-sdk/client-sns";

const REGION = "REGION"; //e.g. "us-east-1"
// Create SNS service object.
const snsClient = new SNSClient({ region: REGION });

function my_subscribe(protocol, topic_arn, endpoint){
  const params = {
    Protocol: protocol,
    TopicArn: topic_arn, //TOPIC_ARN
    Endpoint: endpoint, 
  };
  const data = await snsClient.send(new SubscribeCommand(params));
};

function subcribe_to_foo_topic(){
   const topic_arn = 'arn:aws:sns:us-east-2:123456789012:foo_topic';
   my_subscribe("email", topic_arn, "EMAIL_ADDRESS") 
   my_subscribe("sms", topic_arn, "007")
   my_subscribe("lambda", topic_arn, "fooarn:function:lambda_name:v2")
   my_subscribe("sqs", topic_arn, "https://sqs.us-east-2.amazonaws.com/123456789012/foo_queue")

   my_subscribe("http", topic_arn, "http://foourl")
}


function publish_to_foo_topic(){
  const params = {
      Message: "MESSAGE_TEXT", // MESSAGE_TEXT
      TopicArn: 'arn:aws:sns:us-east-2:123456789012:foo_topic'
  };
  const data = await snsClient.send(new PublishCommand(params));
}

This code will produce the following result:

AWS S3

The following links are created:

Link Type

Methods from SDK V2 s3client

import {AWS} from 'aws-sdk'
const s3client = new AWS.S3()

Methods from SDK V3 s3client

import {S3} from '@aws-sdk/client-s3'
const s3client = new S3()

Commands from SDK V3

imported from '@aws-sdk/client-s3'

No Link
  • createBucket

  • CreateBucketCommand
callLink
  • createMultipartUpload

  • createPresignedPost

  • abortMultipartUpload

  • completeMultipartUpload

  • deleteBucketAnalyticsConfiguration

  • deleteBucketCors

  • deleteBucketEncryption

  • deleteBucketInventoryConfiguration

  • deleteBucketLifecycle

  • deleteBucketMetricsConfiguration

  • deleteBucketPolicy

  • deleteBucketReplication

  • deleteBucketTagging

  • deleteBucketWebsite

  • deleteObjectTagging

  • deletePublicAccessBlock

  • getBucketAccelerateConfiguration

  • getBucketAcl

  • getBucketAnalyticsConfiguration

  • getBucketCors

  • getBucketEncryption

  • getBucketInventoryConfiguration

  • getBucketLifecycle

  • getBucketLifecycleConfiguration

  • getBucketLocation

  • getBucketLogging

  • getBucketMetricsConfiguration

  • getBucketNotification

  • getBucketNotificationConfiguration

  • getBucketPolicy

  • getBucketPolicyStatus

  • getBucketReplication

  • getBucketTagging

  • getBucketVersioning

  • getBucketWebsite

  • getObjectAcl

  • getObjectLegalHold

  • getObjectLockConfiguration

  • getObjectRetention

  • getObjectTagging

  • getPublicAccessBlock

  • getSignedUrl

  • listBuckets
  • listBucketAnalyticsConfigurations

  • listBucketInventoryConfigurations

  • listBucketMetricsConfigurations

  • listMultipartUploads

  • listObjectVersions

  • listParts

  • putBucketLogging
  • putBucketAnalyticsConfiguration
  • putBucketLifecycleConfiguration

  • putBucketMetricsConfiguration

  • putBucketNotification

  • putBucketNotificationConfiguration

  • putBucketPolicy

  • putBucketReplication

  • putBucketRequestPayment

  • putBucketTagging

  • putBucketVersioning

  • putObjectAcl

  • putObjectLegalHold

  • putObjectLockConfiguration

  • putObjectRetention

  • putObjectTagging

  • putPublicAccessBlock

  • putBucketAccelerateConfiguration

  • putBucketAcl

  • putBucketCors

  • putBucketEncryption

  • putBucketInventoryConfiguration

  • putBucketLifecycle

  • putBucketLogging
  • upload

  • uploadPart

  • uploadPartCopy

  • abortMultipartUpload
  • completeMultipartUpload
  • copyObject
  • createBucket
  • createMultipartUpload
  • deleteBucket
  • deleteBucketAnalyticsConfiguration
  • deleteBucketCors
  • deleteBucketEncryption
  • deleteBucketIntelligentTieringConfiguration
  • deleteBucketInventoryConfiguration
  • deleteBucketLifecycle
  • deleteBucketMetricsConfiguration
  • deleteBucketOwnershipControls
  • deleteBucketPolicy
  • deleteBucketReplication
  • deleteBucketTagging
  • deleteBucketWebsite
  • deleteObjectTagging
  • deletePublicAccessBlock
  • destroy
  • getBucketAccelerateConfiguration
  • getBucketAcl
  • getBucketAnalyticsConfiguration
  • getBucketCors
  • getBucketEncryption
  • getBucketIntelligentTieringConfiguration
  • getBucketInventoryConfiguration
  • getBucketLifecycleConfiguration
  • getBucketLocation
  • getBucketLogging
  • getBucketMetricsConfiguration
  • getBucketNotificationConfiguration
  • getBucketOwnershipControls
  • getBucketPolicy
  • getBucketPolicyStatus
  • getBucketReplication
  • getBucketRequestPayment
  • getBucketTagging
  • getBucketVersioning
  • getBucketWebsite
  • getObjectAcl
  • getObjectLegalHold
  • getObjectLockConfiguration
  • getObjectRetention
  • getObjectTagging
  • getPublicAccessBlock
  • headBucket
  • headObject
  • listBucketAnalyticsConfigurations
  • listBucketIntelligentTieringConfigurations
  • listBucketInventoryConfigurations
  • listBucketMetricsConfigurations
  • listBuckets
  • listMultipartUploads
  • listObjectVersions
  • listParts
  • putBucketAccelerateConfiguration
  • putBucketAcl
  • putBucketCors
  • putBucketEncryption
  • putBucketIntelligentTieringConfiguration
  • putBucketInventoryConfiguration
  • putBucketLifecycleConfiguration
  • putBucketLogging
  • putBucketMetricsConfiguration
  • putBucketNotificationConfiguration
  • putBucketOwnershipControls
  • putBucketPolicy
  • putBucketReplication
  • putBucketRequestPayment
  • putBucketTagging
  • putBucketVersioning
  • putBucketWebsite
  • putObjectAcl
  • putObjectLegalHold
  • putObjectLockConfiguration
  • putObjectRetention
  • putObjectTagging
  • putPublicAccessBlock
  • restoreObject
  • send
  • uploadPart
  • uploadPartCopy
  • writeGetObjectResponse
  • AbortMultipartUploadCommand
  • CompleteMultipartUploadCommand
  • CreateMultipartUploadCommand
  • DeleteBucketAnalyticsConfigurationCommand
  • DeleteBucketCorsCommand
  • DeleteBucketEncryptionCommand
  • DeleteBucketIntelligentTieringConfigurationCommand
  • DeleteBucketInventoryConfigurationCommand
  • DeleteBucketLifecycleCommand
  • DeleteBucketMetricsConfigurationCommand
  • DeleteBucketOwnershipControlsCommand
  • DeleteBucketPolicyCommand
  • DeleteBucketReplicationCommand
  • DeleteBucketTaggingCommand
  • GetBucketAccelerateConfigurationCommand
  • GetBucketAclCommand
  • DeleteBucketWebsiteCommand
  • DeleteObjectTaggingCommand
  • DeletePublicAccessBlockCommand
  • GetBucketAnalyticsConfigurationCommand
  • GetBucketCorsCommand
  • GetBucketEncryptionCommand
  • GetBucketIntelligentTieringConfigurationCommand
  • GetBucketInventoryConfigurationCommand
  • GetBucketLifecycleConfigurationCommand
  • GetBucketLocationCommand
  • GetBucketLoggingCommand
  • GetBucketMetricsConfigurationCommand
  • GetBucketNotificationConfigurationCommand
  • GetBucketOwnershipControlsCommand
  • GetBucketPolicyCommand
  • GetBucketPolicyStatusCommand
  • GetBucketReplicationCommand
  • GetBucketRequestPaymentCommand
  • GetBucketTaggingCommand
  • GetBucketVersioningCommand
  • GetBucketWebsiteCommand
  • GetObjectAclCommand
  • GetObjectLegalHoldCommand
  • GetObjectLockConfigurationCommand
  • GetObjectRetentionCommand
  • GetObjectTaggingCommand
  • GetPublicAccessBlockCommand
  • HeadBucketCommand
  • HeadObjectCommand
  • ListBucketAnalyticsConfigurationsCommand
  • ListBucketIntelligentTieringConfigurationsCommand
  • ListBucketInventoryConfigurationsCommand
  • ListBucketMetricsConfigurationsCommand
  • ListMultipartUploadsCommand
  • ListObjectVersionsCommand
  • ListPartsCommand
  • PutBucketAccelerateConfigurationCommand
  • PutBucketAclCommand
  • PutBucketAnalyticsConfigurationCommand
  • PutBucketCorsCommand
  • PutBucketEncryptionCommand
  • PutBucketIntelligentTieringConfigurationCommand
  • PutBucketInventoryConfigurationCommand
  • PutBucketLifecycleConfigurationCommand
  • PutBucketLoggingCommand
  • PutBucketMetricsConfigurationCommand
  • PutBucketNotificationConfigurationCommand
  • PutBucketOwnershipControlsCommand
  • PutBucketPolicyCommand
  • PutBucketReplicationCommand
  • PutBucketRequestPaymentCommand
  • PutBucketTaggingCommand
  • PutBucketVersioningCommand
  • PutBucketWebsiteCommand
  • PutObjectAclCommand
  • PutObjectLegalHoldCommand
  • PutObjectLockConfigurationCommand
  • PutObjectRetentionCommand
  • PutObjectTaggingCommand
  • PutPublicAccessBlockCommand
  • UploadPartCommand
  • UploadPartCopyCommand
  • WriteGetObjectResponseCommand
useInsertLink
  • putObject
  • copyObject
  • putObject
  • copyObject
  • RestoreObjectCommand
  • PutObjectCommand
  • CopyObjectCommand
useDeleteLink
  • deleteBucket
  • deleteObject

  • deleteObjects

  • deleteBucket
  • deleteObject

  • deleteObjects

  • DeleteBucketCommand
  • DeleteObjectCommand
  • DeleteObjectsCommand
useSelectLink
  • getObject
  • getObjectTorrent
  • listObjects

  • listObjectsV2

  • copyObject
  • getObject
  • getObjectTorrent
  • listObjects
  • listObjectsV2
  • copyObject
  • GetObjectCommand
  • ListObjectsCommand
  • ListObjectsV2Command
  • SelectObjectContentCommand
  • GetObjectTorrentCommand
  • CopyObjectCommand
useUpdateLink
  • putBucketAnalyticsConfiguration
  • putBucketAnalyticsConfiguration
  • RestoreObjectCommand
  • PutObjectCommand
  • CopyObjectCommand

Example

This code will create an S3 Bucket named “MyBucket” and a useInsert link to that bucket:

foo.ts

// Load the AWS SDK for Node.js
import * as AWS from 'aws-sdk'
// Set the region 
AWS.config.update({region: 'REGION'});

// Create S3 service object
s3 = new AWS.S3({apiVersion: '2006-03-01'});

// Create the parameters for calling createBucket
var bucketParams = {
  Bucket : "MyBucket",
  ACL : 'public-read'
};

// call S3 to create the bucket
s3.createBucket(bucketParams, function(err, data) {
  if (err) {
    console.log("Error", err);
  } else {
    console.log("Success", data.Location);
  }
});

params = {
    // ...
    Bucket: "MyBucket"
};
s3.putObject(params, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else     console.log(data);           // successful response
});

This code will produce the following result:

AWS SQS

Supported APIs

API

Methods from SDK V2 sqs client

Commands from SDK V3

imported from '@aws-sdk/client-sqs'

Publish
  • sendMessage

  • sendMessageBatch
  • SendMessageCommand
Receive
  • receiveMessage
  • ReceiveMessageCommand

Example

This code will publish a message into the “SQS_QUEUE_URL” queue:

import * as AWS from "aws-sdk";
AWS.config.update({ region: 'REGION' });

const sqs = new AWS.SQS({apiVersion: '2012-11-05'});

const queueUrl = "SQS_QUEUE_URL"

const params = {
    MessageBody: "This is a message",
    QueueUrl: queueUrl,
    MaxNumberOfMessages: 1,
    VisibilityTimeout: 0,
};
class Foo {
  sendMessage(){
    sqs.sendMessage(params, function (err, data) {
        if (err) {
            console.log("Error", err);
        } else {
         console.log("Success", data.MessageId);
        }
    });
 }
}

This code will receive a message from the queue “SQS_QUEUE_URL”:

import * as AWS from "aws-sdk";
AWS.config.update({ region: 'REGION' });

const sqs = new AWS.SQS({apiVersion: '2012-11-05'});

const queueUrl = "SQS_QUEUE_URL"

const params = {
    QueueUrl: queueUrl,
    MaxNumberOfMessages: 1,
    VisibilityTimeout: 0,
};

export class SqsReciver {
    constructor() {
        this.reciver();
    }
    private reciver(): void {
        sqs.receiveMessage(params, (err, data) => {
    // do something
        });
    }
}

This code will produce the following result:

When the evaluation of the queue name fails, a Node.js AWS SQS Unknown Publisher (or Receiver) will be created.

AWS DynamoDB

See DynamoDB support for Node.js source code - TypeScript.

AWS X-Ray

AWS X-Ray encapsulates AWS method calls in order to provide status and load status.

Example

This code will encapsulate AWS SDK then create a dynamoDB instance, and a Table instance:

import AWSXRay from 'aws-xray-sdk-core'
import AWS from 'aws-sdk'
const AWS = AWSXRay.captureAWS(AWS) // Encapsulate AWS SDK
const DDB = new AWS.DynamoDB({ apiVersion: "2012-10-08" }) // use AWS as usual
const { v1: uuidv1 } = require('uuid');
 
// environment variables
const { TABLE_NAME, ENDPOINT_OVERRIDE, REGION } = process.env
const options = { region: REGION }
AWS.config.update({ region: REGION })
 
if (ENDPOINT_OVERRIDE !== "") {
    options.endpoint = ENDPOINT_OVERRIDE
}
 
const docClient = new AWS.DynamoDB.DocumentClient(options)
// response helper
const response = (statusCode, body, additionalHeaders) => ({
    statusCode,
    body: JSON.stringify(body),
    headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', ...additionalHeaders },
})
 

 
function addRecord(event) {
 
    let usernameField = {
        "cognito-username": getCognitoUsername(event)
    }
 
    // auto generated date fields
    let d = new Date()
    let dISO = d.toISOString()
    let auto_fields = {
        "id": uuidv1(),
        "creation_date": dISO,
        "lastupdate_date": dISO
    }
 
    //merge the json objects
    let item_body = {...usernameField, ...auto_fields, ...JSON.parse(event.body) }
 
    console.log(item_body);
     
    //final params to DynamoDB
    const params = {
        TableName: TABLE_NAME,
        Item: item_body
    }
 
    return docClient.put(params)
}

This code will produce the following result:

Known limitations

  • The use of AWS.SQS with promises is not supported. For instance, no link would be created between the receiver and the handler function defined in .then() call in the following source code: 
this.sqs.receiveMessage(params).promise().then( () => {})
  • If the queueName is set using the createQueue API, the evaluation of the queue name will fail.
  • Use of access points is not supported