mirror of
https://github.com/gosticks/DefinitelyTyped.git
synced 2026-10-06 15:57:13 +00:00
[aws-lambda] Some docs, split up types and tests (#42080)
* [aws-lambda] Some docs, split up index.d.ts into multiple files. Documents handler type and conventions for adding triggers more explicitly. The same index.d.ts docs should explain the thinking for the new layout convention. No changes to the type tests in this first commit, to show that the tests still passs, and because I think they deserve more attention (and I need lunch right now). Most event structures have little to no changes other than re-ordering or removing inaccurately copy/pasted comments in a case or two. Loses history, but github doesn't support rename history anyway, and it's even more ugly to get git to track file splits even for local usage. Apologies for the huge diff. * [aws-lambda] Split tests to per-service files, add contributor README.md Updates most of the files to a consistent style.
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
Types helpful for implementing handlers in the AWS Lambda NodeJS runtimes,
|
||||
the handler interface and types for AWS-defined trigger sources.
|
||||
|
||||
Unrelated to the npm package `aws-lambda`, a CLI tool.
|
||||
|
||||
## Contributing
|
||||
|
||||
Follow all the rules for [modifying a type package](../../README.md#edit-an-existing-package),
|
||||
of course, but as this package has gotten quite large, please
|
||||
also follow the established conventions to keep things simple
|
||||
for future contributors:
|
||||
|
||||
### Common types
|
||||
|
||||
The main entry point, [index.d.ts]() simply does `export * from "..."`
|
||||
for all type declaration files in the package. Make sure if you are
|
||||
adding any files for new trigger sources that you add the
|
||||
re-export here; the user should only need to import from `"aws-lambda"`.
|
||||
|
||||
Similarly, [aws-lambda-tests.ts]() has declarations for the common type and tests
|
||||
for [handler.d.ts](), while the actual service specific tests are all in [test/]()
|
||||
|
||||
The mentioned [handler.d.ts]() contains definitions for `Handler<TEvent, TResult>`
|
||||
and its associated types like `Context` and `Callback<TResult>`,
|
||||
which describe the Lambda NodeJS runtime API.
|
||||
|
||||
### Triggers
|
||||
|
||||
Each trigger-specific event structure should have a separate file in [trigger/]() based
|
||||
on the service name and optionally the trigger type, if it's not a clear "default".
|
||||
|
||||
If multiple triggers for a service share types, the common types
|
||||
should be in a file in [common/]() named for the containing service.
|
||||
|
||||
For a service `foo` and trigger `bar`, there should ideally be
|
||||
a file `trigger/foo-bar.d.ts` containing something like:
|
||||
|
||||
```ts
|
||||
import { Callback, Handler } from "../handler";
|
||||
|
||||
import { FooCommonType } from "../common/foo";
|
||||
|
||||
export type FooBarHandler = Handler<FooBarEvent, FooBarResult>;
|
||||
export type FooBarCallback = Callback<FooBarResult>;
|
||||
// or, if there is no FooBarResult:
|
||||
export type FooBarHandler = Handler<FooBarEvent, void>;
|
||||
|
||||
export interface FooBarEvent {
|
||||
// ...
|
||||
}
|
||||
|
||||
export interface FooBarEventSpecificType {
|
||||
// ...
|
||||
}
|
||||
|
||||
export interface FooBarResult {
|
||||
// ...
|
||||
}
|
||||
|
||||
export interface FooBarResultSpecificType {
|
||||
// ...
|
||||
}
|
||||
|
||||
export interface FooBarCommonType {
|
||||
// ...
|
||||
}
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
As implied, all names are exported flat, try to ensure that it's clear what service
|
||||
or trigger a type is for. (Note that especially the earlier types are not always
|
||||
consistent with this)
|
||||
|
||||
### Tests
|
||||
|
||||
Each trigger should have a type test that exercises the type roughly as the user
|
||||
would, in particular reading properties from the event, and creating each
|
||||
valid result structure in general. When making any change: adding a property,
|
||||
to a new trigger, also add the change to the tests.
|
||||
|
||||
Tests are grouped by each service in [test/](), and must also be explicitly
|
||||
added to `tsconfig.json`'s `files` list (use of `include` is banned by
|
||||
DefinitelyTyped at the moment).
|
||||
|
||||
The test file for a service `foo` with two triggers `bar` and `baz` may look like:
|
||||
|
||||
```ts
|
||||
import {
|
||||
FooBarHandler,
|
||||
FooBarResult,
|
||||
// ...
|
||||
} from "aws-lambda";
|
||||
|
||||
const barHandler: FooBarHandler = async (event, context, callback) => {
|
||||
// Check event type
|
||||
// Declarations for e.g. strOrNull, bool are in aws-lambda-tests.ts
|
||||
strOrNull = event.body;
|
||||
str = event.headers[str];
|
||||
str = event.multiValueHeaders[str][num];
|
||||
str = event.httpMethod;
|
||||
bool = event.isBase64Encoded;
|
||||
// this property is of a named type, validate that:
|
||||
let requestContext: FooBarEventRequestContext;
|
||||
requestContext = event.requestContext;
|
||||
// for each accessible property declared in FooBarEvent...
|
||||
|
||||
// recurse into each declared type
|
||||
str = requestContext.accountId;
|
||||
str = requestContext.apiId;
|
||||
const authContext: AuthResponseContext | null | undefined = requestContext.authorizer;
|
||||
numOrUndefined = requestContext.connectedAt;
|
||||
strOrUndefined = requestContext.connectionId;
|
||||
// ...
|
||||
|
||||
|
||||
// Check result type
|
||||
let result: FooBarResult;
|
||||
// check minimally assignable case
|
||||
result = {
|
||||
statusCode: num,
|
||||
body: str,
|
||||
};
|
||||
// check maximally assignable case
|
||||
result = {
|
||||
statusCode: num,
|
||||
headers: {
|
||||
[str]: str,
|
||||
[str]: bool,
|
||||
[str]: num,
|
||||
},
|
||||
multiValueHeaders: {
|
||||
[str]: [str, bool, num],
|
||||
},
|
||||
isBase64Encoded: true,
|
||||
body: str,
|
||||
};
|
||||
|
||||
// check reasonable result-returning styles
|
||||
callback(new Error());
|
||||
callback(null, result);
|
||||
return result;
|
||||
};
|
||||
|
||||
const bazHandler: FooBazHandler = async (event, context, callback) => {
|
||||
// ... as above, for each untested type
|
||||
|
||||
// for handlers without a result
|
||||
callback();
|
||||
callback(new Error());
|
||||
};
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
Not that currently many tests have not been updated to this style.
|
||||
As always, PRs welcome, but simply adding your change in the new style
|
||||
is a start.
|
||||
|
||||
Ideally the existing test should still pass with your new change: if it doesn't that
|
||||
implies that your change is incompatible with existing user code (if the
|
||||
test is done correctly) This isn't always the wrong thing to do, but be
|
||||
prepared to make a decently strong case for why this is an exception.
|
||||
|
||||
## Future ideas
|
||||
|
||||
* Adding JSDocs for types and properties (copied from AWS docs?). Many
|
||||
triggers have unintuitive formats and requirements.
|
||||
|
||||
* Splitting `import { Context, FooBarHandler, FooCommonType } from "aws-lambda"` into
|
||||
|
||||
* `import { Context } from "@aws-lambda/runtime"` and
|
||||
* `import { BarHandler, CommonType } from "@aws-lambda/foo"`
|
||||
|
||||
With forwarding from the current package to preserve back-compat.
|
||||
This would allow not only more fine-grained dependencies, but also
|
||||
support backward-incompatible changes to triggers as they could be
|
||||
independently major versioned.
|
||||
|
||||
It's a lot of busywork to do all that renaming though, and ensuring
|
||||
compatibility is kept.
|
||||
|
||||
* Possibly related to the above, migrating this to, or somehow in support of,
|
||||
an npm package with runtime support for implementing handlers correctly.
|
||||
For example, catching and formatting `ClientError` into an API Gateway
|
||||
400 error, or parsing CloudWatch log payloads.
|
||||
|
||||
This one is much more fraught, as it by default loses all the existing
|
||||
DefinitelyTyped tooling and community support (e.g. cross package typing).
|
||||
+101
-1313
File diff suppressed because it is too large
Load Diff
+46
@@ -0,0 +1,46 @@
|
||||
// Used by both APIGatewayPraxyEvent and APIGatewayAuthorizerEvent
|
||||
export interface APIGatewayEventRequestContext {
|
||||
accountId: string;
|
||||
apiId: string;
|
||||
authorizer?: AuthResponseContext | null;
|
||||
connectedAt?: number;
|
||||
connectionId?: string;
|
||||
domainName?: string;
|
||||
domainPrefix?: string;
|
||||
eventType?: string;
|
||||
extendedRequestId?: string;
|
||||
httpMethod: string;
|
||||
identity: {
|
||||
accessKey: string | null;
|
||||
accountId: string | null;
|
||||
apiKey: string | null;
|
||||
apiKeyId: string | null;
|
||||
caller: string | null;
|
||||
cognitoAuthenticationProvider: string | null;
|
||||
cognitoAuthenticationType: string | null;
|
||||
cognitoIdentityId: string | null;
|
||||
cognitoIdentityPoolId: string | null;
|
||||
principalOrgId: string | null;
|
||||
sourceIp: string;
|
||||
user: string | null;
|
||||
userAgent: string | null;
|
||||
userArn: string | null;
|
||||
};
|
||||
messageDirection?: string;
|
||||
messageId?: string | null;
|
||||
path: string;
|
||||
stage: string;
|
||||
requestId: string;
|
||||
requestTime?: string;
|
||||
requestTimeEpoch: number;
|
||||
resourceId: string;
|
||||
resourcePath: string;
|
||||
routeKey?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html#api-gateway-custom-authorizer-output
|
||||
*/
|
||||
export interface AuthResponseContext {
|
||||
[name: string]: any;
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* CloudFront events
|
||||
* http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html
|
||||
* Bear in mind that the "example" event structure in the page above includes
|
||||
* both an S3 and a Custom origin, which is not strictly allowed. Only one
|
||||
* of these per event may be present.
|
||||
*/
|
||||
export interface CloudFrontHeaders {
|
||||
[name: string]: Array<{
|
||||
key?: string;
|
||||
value: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export type CloudFrontOrigin =
|
||||
| { s3: CloudFrontS3Origin; custom?: never }
|
||||
| { custom: CloudFrontCustomOrigin; s3?: never };
|
||||
|
||||
export interface CloudFrontCustomOrigin {
|
||||
customHeaders: CloudFrontHeaders;
|
||||
domainName: string;
|
||||
keepaliveTimeout: number;
|
||||
path: string;
|
||||
port: number;
|
||||
protocol: 'http' | 'https';
|
||||
readTimeout: number;
|
||||
sslProtocols: string[];
|
||||
}
|
||||
|
||||
export interface CloudFrontS3Origin {
|
||||
authMethod: 'origin-access-identity' | 'none';
|
||||
customHeaders: CloudFrontHeaders;
|
||||
domainName: string;
|
||||
path: string;
|
||||
region: string;
|
||||
}
|
||||
|
||||
export interface CloudFrontResponse {
|
||||
status: string;
|
||||
statusDescription: string;
|
||||
headers: CloudFrontHeaders;
|
||||
}
|
||||
|
||||
export interface CloudFrontRequest {
|
||||
body?: {
|
||||
action: 'read-only' | 'replace';
|
||||
data: string;
|
||||
encoding: 'base64' | 'text';
|
||||
readonly inputTruncated: boolean;
|
||||
};
|
||||
readonly clientIp: string;
|
||||
readonly method: string;
|
||||
uri: string;
|
||||
querystring: string;
|
||||
headers: CloudFrontHeaders;
|
||||
origin?: CloudFrontOrigin;
|
||||
}
|
||||
|
||||
export interface CloudFrontEvent {
|
||||
config: {
|
||||
readonly distributionDomainName: string;
|
||||
readonly distributionId: string;
|
||||
} & (
|
||||
| { readonly eventType: 'origin-request' | 'origin-response' }
|
||||
| { readonly eventType: 'viewer-request' | 'viewer-response'; readonly requestId: string });
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated HTTP response in viewer request event or origin request event
|
||||
*
|
||||
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-generating-http-responses-in-requests.html#lambda-generating-http-responses-object
|
||||
*/
|
||||
export interface CloudFrontResultResponse {
|
||||
status: string;
|
||||
statusDescription?: string;
|
||||
headers?: CloudFrontHeaders;
|
||||
bodyEncoding?: 'text' | 'base64';
|
||||
body?: string;
|
||||
}
|
||||
Vendored
+171
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* The interface that AWS Lambda will invoke your handler with.
|
||||
* There are more specialized types for many cases where AWS services
|
||||
* invoke your lambda, but you can directly use this type for when you are invoking
|
||||
* your lambda directly.
|
||||
*
|
||||
* See tme {@link http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html AWS documentation}
|
||||
* for more information about the runtime behavior, and the
|
||||
* {@link https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/ AWS Blog post}
|
||||
* introducing the async handler behavior in the 8.10 runtime.
|
||||
*
|
||||
* @example <caption>Defining a custom handler type</caption>
|
||||
* import { Handler } from 'aws-lambda'
|
||||
*
|
||||
* interface NameEvent {
|
||||
* fullName: string
|
||||
* }
|
||||
* interface NameResult {
|
||||
* firstName: string
|
||||
* middleNames: string
|
||||
* lastName: string
|
||||
* }
|
||||
* type PersonHandler = Handler<NameEvent, NameResult>
|
||||
*
|
||||
* export const handler: PersonHandler = async (event) => {
|
||||
* const names = event.fullName.split(' ')
|
||||
* const firstName = names.shift()
|
||||
* const lastName = names.pop()
|
||||
* return { firstName, middleNames: names, lastName }
|
||||
* }
|
||||
*
|
||||
* @example <caption>Logs the contents of the event object and returns the location of the logs</caption>
|
||||
* import { Handler } from 'aws-lambda'
|
||||
*
|
||||
* export const handler: Handler = async (event, context) => {
|
||||
* console.log("EVENT: \n" + JSON.stringify(event, null, 2))
|
||||
* return context.logStreamName
|
||||
* }
|
||||
*
|
||||
* @example <caption>AWS SDK with Async Function and Promises</caption>
|
||||
* import { Handler } from 'aws-lambda'
|
||||
* import AWS from 'aws-sdk'
|
||||
*
|
||||
* const s3 = new AWS.S3()
|
||||
*
|
||||
* export const handler: Handler = async (event) => {
|
||||
* const response = await s3.listBuckets().promise()
|
||||
* return response?.Buckets.map((bucket) => bucket.Name)
|
||||
* }
|
||||
*
|
||||
* @example <caption>HTTP Request with Callback</caption>
|
||||
* import { Handler } from 'aws-lambda'
|
||||
* import https from 'https'
|
||||
*
|
||||
* let url = "https://docs.aws.amazon.com/lambda/latest/dg/welcome.html"
|
||||
*
|
||||
* export const handler: Handler<void, number> = (event, context, callback) => {
|
||||
* https.get(url, (res) => {
|
||||
* callback(null, res.statusCode)
|
||||
* }).on('error', (e) => {
|
||||
* callback(Error(e))
|
||||
* })
|
||||
* }
|
||||
*
|
||||
* @param event
|
||||
* Parsed JSON data in the lambda request payload. For an AWS service triggered
|
||||
* lambda this should be in the format of a type ending in Event, for example the
|
||||
* S3Handler receives an event of type S3Event.
|
||||
* @param context
|
||||
* Runtime contextual information of the current invocation, for example the caller
|
||||
* identity, available memory and time remaining, legacy completion callbacks, and
|
||||
* a mutable property controlling when the lambda execution completes.
|
||||
* @param callback
|
||||
* NodeJS-style completion callback that the AWS Lambda runtime will provide that can
|
||||
* be used to provide the lambda result payload value, or any execution error. Can
|
||||
* instead return a promise that resolves with the result payload value or rejects
|
||||
* with the execution error.
|
||||
* @return
|
||||
* A promise that resolves with the lambda result payload value, or rejects with the
|
||||
* execution error. Note that if you implement your handler as an async function,
|
||||
* you will automatically return a promise that will resolve with a returned value,
|
||||
* or reject with a thrown value.
|
||||
*/
|
||||
export type Handler<TEvent = any, TResult = any> = (
|
||||
event: TEvent,
|
||||
context: Context,
|
||||
callback: Callback<TResult>,
|
||||
) => void | Promise<TResult>;
|
||||
|
||||
/**
|
||||
* {@link Handler} context parameter.
|
||||
* See {@link https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html AWS documentation}.
|
||||
*/
|
||||
export interface Context {
|
||||
callbackWaitsForEmptyEventLoop: boolean;
|
||||
functionName: string;
|
||||
functionVersion: string;
|
||||
invokedFunctionArn: string;
|
||||
memoryLimitInMB: string;
|
||||
awsRequestId: string;
|
||||
logGroupName: string;
|
||||
logStreamName: string;
|
||||
identity?: CognitoIdentity;
|
||||
clientContext?: ClientContext;
|
||||
|
||||
getRemainingTimeInMillis(): number;
|
||||
|
||||
// Functions for compatibility with earlier Node.js Runtime v0.10.42
|
||||
// No longer documented, so they are deprecated, but they still work
|
||||
// as of the 12.x runtime, so they are not removed from the types.
|
||||
|
||||
/** @deprecated Use handler callback or promise result */
|
||||
done(error?: Error, result?: any): void;
|
||||
/** @deprecated Use handler callback with first argument or reject a promise result */
|
||||
fail(error: Error | string): void;
|
||||
/** @deprecated Use handler callback with second argument or resolve a promise result */
|
||||
succeed(messageOrObject: any): void;
|
||||
// Unclear what behavior this is supposed to have, I couldn't find any still extant reference,
|
||||
// and it behaves like the above, ignoring the object parameter.
|
||||
/** @deprecated Use handler callback or promise result */
|
||||
succeed(message: string, object: any): void;
|
||||
}
|
||||
|
||||
export interface CognitoIdentity {
|
||||
cognitoIdentityId: string;
|
||||
cognitoIdentityPoolId: string;
|
||||
}
|
||||
|
||||
export interface ClientContext {
|
||||
client: ClientContextClient;
|
||||
Custom?: any;
|
||||
env: ClientContextEnv;
|
||||
}
|
||||
|
||||
export interface ClientContextClient {
|
||||
installationId: string;
|
||||
appTitle: string;
|
||||
appVersionName: string;
|
||||
appVersionCode: string;
|
||||
appPackageName: string;
|
||||
}
|
||||
|
||||
export interface ClientContextEnv {
|
||||
platformVersion: string;
|
||||
platform: string;
|
||||
make: string;
|
||||
model: string;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* NodeJS-style callback parameter for the {@link Handler} type.
|
||||
* Can be used instead of returning a promise, see the
|
||||
* {@link https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html AWS documentation}
|
||||
* for the handler programming model.
|
||||
*
|
||||
* @param error
|
||||
* Parameter to use to provide the error payload for a failed lambda execution.
|
||||
* See {@link https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-mode-exceptions.html AWS documentation}
|
||||
* for error handling.
|
||||
* If an Error instance is passed, the error payload uses the `name` property as the `errorType`,
|
||||
* the `message` property as the `errorMessage`, and parses the `stack` property string into
|
||||
* the `trace` array.
|
||||
* For other values, the `errorType` is `typeof value`, the `errorMessage` is `String(value)`, and
|
||||
* `trace` is an empty array.
|
||||
*
|
||||
* @param result
|
||||
* Parameter to use to provide the result payload for a successful lambda execution.
|
||||
* Pass `null` or `undefined` for the `error` parameter to use this parameter.
|
||||
*/
|
||||
export type Callback<TResult = any> = (error?: Error | string | null, result?: TResult) => void;
|
||||
Vendored
+37
-1167
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
||||
import { ALBHandler, ALBResult } from "aws-lambda";
|
||||
|
||||
const handler: ALBHandler = async (event, context, callback) => {
|
||||
str = event.httpMethod;
|
||||
str = event.path;
|
||||
str = event.queryStringParameters![str];
|
||||
str = event.headers![str];
|
||||
str = event.multiValueQueryStringParameters![str][num];
|
||||
str = event.multiValueHeaders![str][num];
|
||||
strOrNull = event.body;
|
||||
bool = event.isBase64Encoded;
|
||||
str = event.requestContext.elb.targetGroupArn;
|
||||
|
||||
let result: ALBResult = {
|
||||
statusCode: num,
|
||||
statusDescription: str,
|
||||
isBase64Encoded: bool,
|
||||
};
|
||||
result = {
|
||||
statusCode: num,
|
||||
statusDescription: str,
|
||||
headers: { [str]: boolOrNumOrStr },
|
||||
multiValueHeaders: { [str]: [boolOrNumOrStr] },
|
||||
body: str,
|
||||
isBase64Encoded: bool,
|
||||
};
|
||||
callback(new Error());
|
||||
callback(null, result);
|
||||
return result;
|
||||
};
|
||||
@@ -0,0 +1,186 @@
|
||||
import {
|
||||
APIGatewayEvent,
|
||||
APIGatewayEventRequestContext,
|
||||
APIGatewayProxyHandler,
|
||||
APIGatewayProxyResult,
|
||||
AuthResponseContext,
|
||||
Context,
|
||||
CustomAuthorizerHandler,
|
||||
CustomAuthorizerResult,
|
||||
PolicyDocument,
|
||||
ProxyHandler,
|
||||
ProxyCallback,
|
||||
Statement,
|
||||
} from "aws-lambda";
|
||||
|
||||
let proxyHandler: APIGatewayProxyHandler = async (event, context, callback) => {
|
||||
strOrNull = event.body;
|
||||
str = event.headers['example'];
|
||||
str = event.multiValueHeaders['example'][0];
|
||||
str = event.httpMethod;
|
||||
bool = event.isBase64Encoded;
|
||||
str = event.path;
|
||||
str = event.pathParameters!['example'];
|
||||
str = event.queryStringParameters!['example'];
|
||||
str = event.multiValueQueryStringParameters!['example'][0];
|
||||
str = event.stageVariables!['example'];
|
||||
let requestContext: APIGatewayEventRequestContext;
|
||||
requestContext = event.requestContext;
|
||||
str = event.resource;
|
||||
|
||||
str = requestContext.accountId;
|
||||
str = requestContext.apiId;
|
||||
const authContext: AuthResponseContext | null | undefined = requestContext.authorizer;
|
||||
numOrUndefined = requestContext.connectedAt;
|
||||
strOrUndefined = requestContext.connectionId;
|
||||
strOrUndefined = requestContext.domainName;
|
||||
strOrUndefined = requestContext.eventType;
|
||||
strOrUndefined = requestContext.extendedRequestId;
|
||||
str = requestContext.httpMethod;
|
||||
strOrNull = requestContext.identity.accessKey;
|
||||
strOrNull = requestContext.identity.accountId;
|
||||
strOrNull = requestContext.identity.apiKey;
|
||||
strOrNull = requestContext.identity.apiKeyId;
|
||||
strOrNull = requestContext.identity.caller;
|
||||
strOrNull = requestContext.identity.cognitoAuthenticationProvider;
|
||||
strOrNull = requestContext.identity.cognitoAuthenticationType;
|
||||
strOrNull = requestContext.identity.cognitoIdentityId;
|
||||
strOrNull = requestContext.identity.cognitoIdentityPoolId;
|
||||
strOrNull = requestContext.identity.principalOrgId;
|
||||
str = requestContext.identity.sourceIp;
|
||||
strOrNull = requestContext.identity.user;
|
||||
strOrNull = requestContext.identity.userAgent;
|
||||
strOrNull = requestContext.identity.userArn;
|
||||
strOrUndefined = requestContext.messageDirection;
|
||||
strOrUndefinedOrNull = requestContext.messageId;
|
||||
str = requestContext.path;
|
||||
str = requestContext.stage;
|
||||
str = requestContext.requestId;
|
||||
strOrUndefined = requestContext.requestTime;
|
||||
str = requestContext.resourceId;
|
||||
str = requestContext.resourcePath;
|
||||
strOrUndefined = requestContext.routeKey;
|
||||
|
||||
let result: APIGatewayProxyResult = {
|
||||
statusCode: num,
|
||||
body: str,
|
||||
};
|
||||
result = {
|
||||
statusCode: num,
|
||||
headers: {
|
||||
[str]: str,
|
||||
[str]: bool,
|
||||
[str]: num,
|
||||
},
|
||||
multiValueHeaders: {
|
||||
[str]: [str, bool, num],
|
||||
},
|
||||
isBase64Encoded: true,
|
||||
body: str,
|
||||
};
|
||||
|
||||
callback(new Error());
|
||||
callback(null, result);
|
||||
return result;
|
||||
};
|
||||
|
||||
const authorizerHandler: CustomAuthorizerHandler = async (event, context, callback) => {
|
||||
str = event.type;
|
||||
str = event.methodArn;
|
||||
strOrUndefined = event.authorizationToken;
|
||||
strOrUndefined = event.resource;
|
||||
strOrUndefined = event.path;
|
||||
strOrUndefined = event.httpMethod;
|
||||
str = event.headers![str];
|
||||
str = event.multiValueHeaders![str][num];
|
||||
str = event.pathParameters![str];
|
||||
str = event.queryStringParameters![str];
|
||||
str = event.multiValueQueryStringParameters![str][num];
|
||||
str = event.stageVariables![str];
|
||||
let requestContext: APIGatewayEventRequestContext;
|
||||
requestContext = event.requestContext!;
|
||||
strOrUndefined = event.domainName;
|
||||
strOrUndefined = event.apiId;
|
||||
|
||||
let statement: Statement = {
|
||||
Action: str,
|
||||
Effect: str,
|
||||
Resource: str,
|
||||
};
|
||||
|
||||
// $ExpectError
|
||||
statement = { Effect: str, Action: str, Principal: 123, };
|
||||
|
||||
// Bad Resource
|
||||
// $ExpectError
|
||||
statement = { Effect: str, Action: str, Resource: 123, };
|
||||
|
||||
// Bad Resource with valid Principal
|
||||
// $ExpectError
|
||||
statement = { Effect: str, Action: str, Principal: { Service: str }, Resource: 123, };
|
||||
|
||||
// Bad principal with valid Resource
|
||||
// $ExpectError
|
||||
statement = { Effect: str, Action: str, Principal: 123, Resource: str, };
|
||||
|
||||
// No Effect
|
||||
// $ExpectError
|
||||
statement = { Action: str, Principal: str };
|
||||
|
||||
statement = {
|
||||
Sid: str,
|
||||
Action: [str, str],
|
||||
Effect: str,
|
||||
Resource: [str, str],
|
||||
Condition: {
|
||||
condition1: { key: 'value' },
|
||||
condition2: [
|
||||
{
|
||||
key1: 'value',
|
||||
key2: 'value',
|
||||
},
|
||||
{
|
||||
key3: 'value',
|
||||
},
|
||||
],
|
||||
},
|
||||
Principal: [str, str],
|
||||
NotPrincipal: [str, str],
|
||||
};
|
||||
|
||||
statement = { Action: str, Principal: str, Effect: str };
|
||||
|
||||
statement = { Action: str, NotPrincipal: { Service: str }, Effect: str };
|
||||
|
||||
statement = { Effect: str, NotAction: str, NotResource: str };
|
||||
|
||||
let policyDocument: PolicyDocument = { Version: str, Statement: [statement] };
|
||||
|
||||
policyDocument = { Version: str, Statement: [statement, statement] };
|
||||
|
||||
const authResponseContext: AuthResponseContext = {
|
||||
stringKey: str,
|
||||
numberKey: num,
|
||||
booleanKey: bool,
|
||||
};
|
||||
|
||||
let result: CustomAuthorizerResult = {
|
||||
principalId: str,
|
||||
policyDocument,
|
||||
context: authResponseContext,
|
||||
};
|
||||
|
||||
result = {
|
||||
principalId: str,
|
||||
policyDocument,
|
||||
};
|
||||
|
||||
callback(new Error());
|
||||
callback(null, result);
|
||||
return result;
|
||||
};
|
||||
|
||||
// Test old names
|
||||
const oldNameProxyHandler: ProxyHandler = (event: APIGatewayEvent, context: Context, cb: ProxyCallback) => {};
|
||||
|
||||
proxyHandler = oldNameProxyHandler;
|
||||
@@ -0,0 +1,74 @@
|
||||
import {
|
||||
CloudFormationCustomResourceFailedResponse,
|
||||
CloudFormationCustomResourceHandler,
|
||||
CloudFormationCustomResourceResponse, CloudFormationCustomResourceSuccessResponse,
|
||||
} from "aws-lambda";
|
||||
|
||||
const handler: CloudFormationCustomResourceHandler = async (event, context, callback) => {
|
||||
switch (event.RequestType) {
|
||||
case 'Create':
|
||||
str = event.LogicalResourceId;
|
||||
str = event.RequestId;
|
||||
anyObj = event.ResourceProperties;
|
||||
str = event.ResourceProperties.ServiceToken;
|
||||
str = event.ResourceType;
|
||||
str = event.ResponseURL;
|
||||
str = event.ServiceToken;
|
||||
str = event.StackId;
|
||||
break;
|
||||
case 'Update':
|
||||
anyObj = event.OldResourceProperties;
|
||||
break;
|
||||
case 'Delete':
|
||||
str = event.PhysicalResourceId;
|
||||
break;
|
||||
}
|
||||
|
||||
let response: CloudFormationCustomResourceResponse;
|
||||
response = {
|
||||
Data: {
|
||||
[str]: anyObj,
|
||||
},
|
||||
LogicalResourceId: str,
|
||||
PhysicalResourceId: str,
|
||||
Reason: strOrUndefined,
|
||||
RequestId: str,
|
||||
StackId: str,
|
||||
Status: "SUCCESS",
|
||||
NoEcho: boolOrUndefined,
|
||||
};
|
||||
|
||||
let successResponse: CloudFormationCustomResourceSuccessResponse;
|
||||
let failedResponse: CloudFormationCustomResourceFailedResponse;
|
||||
successResponse = {
|
||||
LogicalResourceId: str,
|
||||
PhysicalResourceId: str,
|
||||
RequestId: str,
|
||||
StackId: str,
|
||||
Status: "SUCCESS",
|
||||
};
|
||||
successResponse = {
|
||||
Data: anyObj,
|
||||
LogicalResourceId: str,
|
||||
PhysicalResourceId: str,
|
||||
Reason: strOrUndefined,
|
||||
RequestId: str,
|
||||
StackId: str,
|
||||
Status: "SUCCESS",
|
||||
NoEcho: boolOrUndefined,
|
||||
};
|
||||
failedResponse = {
|
||||
Data: anyObj,
|
||||
LogicalResourceId: str,
|
||||
PhysicalResourceId: str,
|
||||
Reason: str,
|
||||
RequestId: str,
|
||||
StackId: str,
|
||||
Status: "FAILED",
|
||||
};
|
||||
response = successResponse;
|
||||
response = failedResponse;
|
||||
|
||||
callback();
|
||||
callback(new Error());
|
||||
};
|
||||
@@ -0,0 +1,279 @@
|
||||
import {
|
||||
CloudFrontHeaders,
|
||||
CloudFrontRequestEvent,
|
||||
CloudFrontRequestHandler,
|
||||
CloudFrontRequestResult,
|
||||
CloudFrontResponseEvent,
|
||||
CloudFrontResponseHandler,
|
||||
CloudFrontResponseResult,
|
||||
CloudFrontS3Origin,
|
||||
CloudFrontCustomOrigin,
|
||||
} from "aws-lambda";
|
||||
|
||||
// TODO: Update test to read all event properties, and write all result
|
||||
// properties, like the user will.
|
||||
|
||||
const cloudFrontHeaders: CloudFrontHeaders = {
|
||||
'content-type': [{ value: 'text/plain' }],
|
||||
'x-foo-bar': [{ key: 'X-Foo-Bar', value: 'example' }],
|
||||
};
|
||||
|
||||
const requestHandler: CloudFrontRequestHandler = async (event, context, cb) => {
|
||||
event = requestWithCustomOriginEvent;
|
||||
// $ExpectType CloudFrontRequestEvent
|
||||
event;
|
||||
let request = event.Records[0].cf.request;
|
||||
|
||||
let s3Origin: CloudFrontS3Origin = {
|
||||
authMethod: 'none',
|
||||
customHeaders: {},
|
||||
domainName: 'example.com',
|
||||
path: '/',
|
||||
region: 'us-east-1',
|
||||
};
|
||||
|
||||
if (request.origin && request.origin.custom) {
|
||||
request.origin.custom.domainName;
|
||||
request.origin.custom.domainName = 'example2.com';
|
||||
|
||||
// $ExpectError
|
||||
s3Origin = request.origin.s3;
|
||||
|
||||
// $ExpectError
|
||||
request.origin.s3.path = '/';
|
||||
}
|
||||
|
||||
let customOrigin: CloudFrontCustomOrigin = {
|
||||
customHeaders: {},
|
||||
domainName: 'example.com',
|
||||
keepaliveTimeout: 60,
|
||||
path: '/',
|
||||
port: 80,
|
||||
protocol: 'http',
|
||||
readTimeout: 30,
|
||||
sslProtocols: [],
|
||||
};
|
||||
|
||||
event = requestWithS3OriginEvent;
|
||||
// $ExpectType CloudFrontRequestEvent
|
||||
event;
|
||||
request = event.Records[0].cf.request;
|
||||
if (request.origin && request.origin.s3) {
|
||||
request.origin.s3.path;
|
||||
request.origin.s3.path = '/new_path';
|
||||
|
||||
// $ExpectError
|
||||
customOrigin = request.origin.custom;
|
||||
|
||||
// $ExpectError
|
||||
request.origin.custom.path = '/';
|
||||
}
|
||||
|
||||
let result: CloudFrontRequestResult;
|
||||
// Result can be either nullish (use current request), a replaced request, or an immediate response
|
||||
result = undefined;
|
||||
result = null;
|
||||
result = { clientIp: str, method: str, uri: str, querystring: str, headers: cloudFrontHeaders };
|
||||
result = { status: str };
|
||||
result = { status: str, statusDescription: str, headers: cloudFrontHeaders, bodyEncoding: "text", body: str };
|
||||
// $ExpectError
|
||||
result = {};
|
||||
|
||||
cb(new Error());
|
||||
cb(null, result);
|
||||
return result;
|
||||
};
|
||||
|
||||
const responseHandler: CloudFrontResponseHandler = async (event, context, callback) => {
|
||||
let result: CloudFrontResponseResult;
|
||||
// Result can be either nullish (use current response) or a replaced response, but not a request
|
||||
result = undefined;
|
||||
result = null;
|
||||
result = { status: str };
|
||||
// $ExpectError
|
||||
result = { clientIp: str, method: str, uri: str, querystring: str, headers: cloudFrontHeaders };
|
||||
result = { status: str, statusDescription: str, headers: cloudFrontHeaders, bodyEncoding: "text", body: str };
|
||||
result = { status: str, bodyEncoding: "base64", body: str };
|
||||
// $ExpectError
|
||||
result = { status: str, bodyEncoding: "invalid-encoding", body: str };
|
||||
|
||||
callback(new Error());
|
||||
callback(null, result);
|
||||
return result;
|
||||
};
|
||||
|
||||
/* CloudFront events, see http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html */
|
||||
|
||||
const requestWithCustomOriginEvent: CloudFrontRequestEvent = {
|
||||
Records: [
|
||||
{
|
||||
cf: {
|
||||
config: {
|
||||
distributionDomainName: 'd123.cloudfront.net',
|
||||
distributionId: 'EDFDVBD6EXAMPLE',
|
||||
eventType: 'viewer-request',
|
||||
requestId: 'MRVMF7KydIvxMWfJIglgwHQwZsbG2IhRJ07sn9AkKUFSHS9EXAMPLE==',
|
||||
},
|
||||
request: {
|
||||
body: {
|
||||
action: 'read-only',
|
||||
data: 'eyJ1c2VybmFtZSI6IkxhbWJkYUBFZGdlIiwiY29tbWVudCI6IlRoaXMgaXMgcmVxdWVzdCBib2R5In0=',
|
||||
encoding: 'base64',
|
||||
inputTruncated: false,
|
||||
},
|
||||
clientIp: '2001:0db8:85a3:0:0:8a2e:0370:7334',
|
||||
querystring: 'size=large',
|
||||
uri: '/picture.jpg',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
host: [
|
||||
{
|
||||
key: 'Host',
|
||||
value: 'd111111abcdef8.cloudfront.net',
|
||||
},
|
||||
],
|
||||
'user-agent': [
|
||||
{
|
||||
key: 'User-Agent',
|
||||
value: 'curl/7.51.0',
|
||||
},
|
||||
],
|
||||
},
|
||||
origin: {
|
||||
custom: {
|
||||
customHeaders: {
|
||||
'my-origin-custom-header': [
|
||||
{
|
||||
key: 'My-Origin-Custom-Header',
|
||||
value: 'Test',
|
||||
},
|
||||
],
|
||||
},
|
||||
domainName: 'example.com',
|
||||
keepaliveTimeout: 5,
|
||||
path: '/custom_path',
|
||||
port: 443,
|
||||
protocol: 'https',
|
||||
readTimeout: 5,
|
||||
sslProtocols: ['TLSv1', 'TLSv1.1'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const requestWithS3OriginEvent: CloudFrontRequestEvent = {
|
||||
Records: [
|
||||
{
|
||||
cf: {
|
||||
config: {
|
||||
distributionDomainName: 'd123.cloudfront.net',
|
||||
distributionId: 'EDFDVBD6EXAMPLE',
|
||||
eventType: 'viewer-request',
|
||||
requestId: 'MRVMF7KydIvxMWfJIglgwHQwZsbG2IhRJ07sn9AkKUFSHS9EXAMPLE==',
|
||||
},
|
||||
request: {
|
||||
body: {
|
||||
action: 'read-only',
|
||||
data: 'eyJ1c2VybmFtZSI6IkxhbWJkYUBFZGdlIiwiY29tbWVudCI6IlRoaXMgaXMgcmVxdWVzdCBib2R5In0=',
|
||||
encoding: 'base64',
|
||||
inputTruncated: false,
|
||||
},
|
||||
clientIp: '2001:0db8:85a3:0:0:8a2e:0370:7334',
|
||||
querystring: 'size=large',
|
||||
uri: '/picture.jpg',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
host: [
|
||||
{
|
||||
key: 'Host',
|
||||
value: 'd111111abcdef8.cloudfront.net',
|
||||
},
|
||||
],
|
||||
'user-agent': [
|
||||
{
|
||||
key: 'User-Agent',
|
||||
value: 'curl/7.51.0',
|
||||
},
|
||||
],
|
||||
},
|
||||
origin: {
|
||||
s3: {
|
||||
authMethod: 'origin-access-identity',
|
||||
customHeaders: {
|
||||
'my-origin-custom-header': [
|
||||
{
|
||||
key: 'My-Origin-Custom-Header',
|
||||
value: 'Test',
|
||||
},
|
||||
],
|
||||
},
|
||||
domainName: 'my-bucket.s3.amazonaws.com',
|
||||
path: '/s3_path',
|
||||
region: 'us-east-1',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const responseEvent: CloudFrontResponseEvent = {
|
||||
Records: [
|
||||
{
|
||||
cf: {
|
||||
config: {
|
||||
distributionDomainName: 'd123.cloudfront.net',
|
||||
distributionId: 'EDFDVBD6EXAMPLE',
|
||||
eventType: 'viewer-response',
|
||||
requestId: 'xGN7KWpVEmB9Dp7ctcVFQC4E-nrcOcEKS3QyAez--06dV7TEXAMPLE==',
|
||||
},
|
||||
request: {
|
||||
clientIp: '2001:0db8:85a3:0:0:8a2e:0370:7334',
|
||||
method: 'GET',
|
||||
uri: '/picture.jpg',
|
||||
querystring: 'size=large',
|
||||
headers: {
|
||||
host: [
|
||||
{
|
||||
key: 'Host',
|
||||
value: 'd111111abcdef8.cloudfront.net',
|
||||
},
|
||||
],
|
||||
'user-agent': [
|
||||
{
|
||||
key: 'User-Agent',
|
||||
value: 'curl/7.18.1',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
response: {
|
||||
status: '200',
|
||||
statusDescription: 'OK',
|
||||
headers: {
|
||||
server: [
|
||||
{
|
||||
key: 'Server',
|
||||
value: 'MyCustomOrigin',
|
||||
},
|
||||
],
|
||||
'set-cookie': [
|
||||
{
|
||||
key: 'Set-Cookie',
|
||||
value: 'theme=light',
|
||||
},
|
||||
{
|
||||
key: 'Set-Cookie',
|
||||
value: 'sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import {
|
||||
CloudWatchLogsDecodedData,
|
||||
CloudWatchLogsHandler,
|
||||
CloudWatchLogsLogEvent,
|
||||
ScheduledHandler,
|
||||
} from "aws-lambda";
|
||||
|
||||
import { gunzipSync } from "zlib";
|
||||
|
||||
const logsHandler: CloudWatchLogsHandler = async (event, context, callback) => {
|
||||
const data: CloudWatchLogsDecodedData = JSON.parse(
|
||||
gunzipSync(Buffer.from(event.awslogs.data, "base64")).toString()
|
||||
);
|
||||
|
||||
str = data.owner;
|
||||
str = data.logGroup;
|
||||
str = data.logStream;
|
||||
str = data.subscriptionFilters[0];
|
||||
str = data.messageType;
|
||||
|
||||
const logEvent: CloudWatchLogsLogEvent = data.logEvents[0];
|
||||
str = logEvent.id;
|
||||
num = logEvent.timestamp;
|
||||
str = logEvent.message;
|
||||
str = logEvent.extractedFields!['example'];
|
||||
|
||||
callback();
|
||||
callback(new Error());
|
||||
};
|
||||
|
||||
// Technically part of cloudwatch
|
||||
const scheduledHandler: ScheduledHandler = async (event, context, callback) => {
|
||||
str = event.account;
|
||||
anyObj = event.detail;
|
||||
str = event.id;
|
||||
str = event.region;
|
||||
str = event.resources[0];
|
||||
str = event.source;
|
||||
str = event.time;
|
||||
|
||||
callback();
|
||||
callback(new Error());
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
import { CodePipelineCloudWatchEvent, CodePipelineEvent } from "aws-lambda";
|
||||
|
||||
// TODO
|
||||
|
||||
/* CodePipeline events https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html#actions-invoke-lambda-function-json-event-example */
|
||||
const CodePipelineEvent: CodePipelineEvent = {
|
||||
'CodePipeline.job': {
|
||||
id: '11111111-abcd-1111-abcd-111111abcdef',
|
||||
accountId: '111111111111',
|
||||
data: {
|
||||
actionConfiguration: {
|
||||
configuration: {
|
||||
FunctionName: 'MyLambdaFunctionForAWSCodePipeline',
|
||||
UserParameters: 'some-input-such-as-a-URL',
|
||||
},
|
||||
},
|
||||
inputArtifacts: [
|
||||
{
|
||||
location: {
|
||||
s3Location: {
|
||||
bucketName:
|
||||
'the name of the bucket configured as the pipeline artifact store in Amazon S3, for example codepipeline-us-east-2-1234567890',
|
||||
objectKey: 'the name of the application, for example CodePipelineDemoApplication.zip',
|
||||
},
|
||||
type: 'S3',
|
||||
},
|
||||
revision: null,
|
||||
name: 'ArtifactName',
|
||||
},
|
||||
],
|
||||
outputArtifacts: [],
|
||||
artifactCredentials: {
|
||||
secretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
|
||||
sessionToken: `MIICiTCCAfICCQD6m7oRw0uXOjANBgkqhkiG9w
|
||||
0BAQUFADCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZ
|
||||
WF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIw
|
||||
EAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5
|
||||
jb20wHhcNMTEwNDI1MjA0NTIxWhcNMTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBh
|
||||
MCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBb
|
||||
WF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMx
|
||||
HzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wgZ8wDQYJKoZIhvcNAQE
|
||||
BBQADgY0AMIGJAoGBAMaK0dn+a4GmWIWJ21uUSfwfEvySWtC2XADZ4nB+BLYgVI
|
||||
k60CpiwsZ3G93vUEIO3IyNoH/f0wYK8m9TrDHudUZg3qX4waLG5M43q7Wgc/MbQ
|
||||
ITxOUSQv7c7ugFFDzQGBzZswY6786m86gpEIbb3OhjZnzcvQAaRHhdlQWIMm2nr
|
||||
AgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtCu4nUhVVxYUntneD9+h8Mg9q6q+auN
|
||||
KyExzyLwaxlAoo7TJHidbtS4J5iNmZgXL0FkbFFBjvSfpJIlJ00zbhNYS5f6Guo
|
||||
EDmFJl0ZxBHjJnyp378OD8uTs7fLvjx79LjSTbNYiytVbZPQUQ5Yaxu2jXnimvw
|
||||
3rrszlaEXAMPLE=`,
|
||||
accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
|
||||
},
|
||||
continuationToken: 'A continuation token if continuing job',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
CodePipelineEvent['CodePipeline.job'].data.encryptionKey = { type: 'KMS', id: 'key' };
|
||||
|
||||
/* CodePipeline CloudWatch Events
|
||||
* see https://docs.aws.amazon.com/codepipeline/latest/userguide/detect-state-changes-cloudwatch-events.html
|
||||
* Their documentation says that detail.version is a string, but it is actually an integer
|
||||
*/
|
||||
const CodePipelineCloudWatchEvent: CodePipelineCloudWatchEvent = {
|
||||
version: '0',
|
||||
id: 'event_Id',
|
||||
'detail-type': 'CodePipeline Pipeline Execution State Change',
|
||||
source: 'aws.codepipeline',
|
||||
account: 'Pipeline_Account',
|
||||
time: 'TimeStamp',
|
||||
region: 'us-east-1',
|
||||
resources: ['arn:aws:codepipeline:us-east-1:account_ID:myPipeline'],
|
||||
detail: {
|
||||
pipeline: 'myPipeline',
|
||||
version: 1,
|
||||
state: 'STARTED',
|
||||
'execution-id': 'execution_Id',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,114 @@
|
||||
// TODO: Update test to read all event properties, and write all result
|
||||
// properties, like the user will.
|
||||
|
||||
import { CognitoUserPoolTriggerHandler } from "aws-lambda";
|
||||
|
||||
const handler: CognitoUserPoolTriggerHandler = async (event, context, callback) => {
|
||||
num = event.version;
|
||||
event.triggerSource === 'PreSignUp_SignUp';
|
||||
event.triggerSource === 'PreSignUp_ExternalProvider';
|
||||
event.triggerSource === 'PostConfirmation_ConfirmSignUp';
|
||||
event.triggerSource === 'PreAuthentication_Authentication';
|
||||
event.triggerSource === 'PostAuthentication_Authentication';
|
||||
event.triggerSource === 'CustomMessage_SignUp';
|
||||
event.triggerSource === 'CustomMessage_AdminCreateUser';
|
||||
event.triggerSource === 'CustomMessage_ResendCode';
|
||||
event.triggerSource === 'CustomMessage_ForgotPassword';
|
||||
event.triggerSource === 'CustomMessage_UpdateUserAttribute';
|
||||
event.triggerSource === 'CustomMessage_VerifyUserAttribute';
|
||||
event.triggerSource === 'CustomMessage_Authentication';
|
||||
event.triggerSource === 'DefineAuthChallenge_Authentication';
|
||||
event.triggerSource === 'CreateAuthChallenge_Authentication';
|
||||
event.triggerSource === 'VerifyAuthChallengeResponse_Authentication';
|
||||
event.triggerSource === 'PreSignUp_AdminCreateUser';
|
||||
event.triggerSource === 'PostConfirmation_ConfirmForgotPassword';
|
||||
event.triggerSource === 'TokenGeneration_HostedAuth';
|
||||
event.triggerSource === 'TokenGeneration_Authentication';
|
||||
event.triggerSource === 'TokenGeneration_NewPasswordChallenge';
|
||||
event.triggerSource === 'TokenGeneration_AuthenticateDevice';
|
||||
event.triggerSource === 'TokenGeneration_RefreshTokens';
|
||||
event.triggerSource === 'UserMigration_Authentication';
|
||||
event.triggerSource === 'UserMigration_ForgotPassword';
|
||||
// $ExpectError
|
||||
event.triggerSource === 'NoSuch_Trigger';
|
||||
|
||||
str = event.region;
|
||||
str = event.userPoolId;
|
||||
strOrUndefined = event.userName;
|
||||
str = event.callerContext.awsSdkVersion;
|
||||
str = event.callerContext.clientId;
|
||||
str = event.request.userAttributes['email'];
|
||||
str = event.request.validationData!['k1'];
|
||||
strOrUndefined = event.request.codeParameter;
|
||||
strOrUndefined = event.request.linkParameter;
|
||||
strOrUndefined = event.request.usernameParameter;
|
||||
boolOrUndefined = event.request.newDeviceUsed;
|
||||
event.request.session![0].challengeName === 'CUSTOM_CHALLENGE';
|
||||
event.request.session![0].challengeName === 'PASSWORD_VERIFIER';
|
||||
event.request.session![0].challengeName === 'SMS_MFA';
|
||||
event.request.session![0].challengeName === 'DEVICE_SRP_AUTH';
|
||||
event.request.session![0].challengeName === 'DEVICE_PASSWORD_VERIFIER';
|
||||
event.request.session![0].challengeName === 'ADMIN_NO_SRP_AUTH';
|
||||
bool = event.request.session![0].challengeResult;
|
||||
strOrUndefined = event.request.session![0].challengeMetadata;
|
||||
strOrUndefined = event.request.challengeName;
|
||||
str = event.request.privateChallengeParameters!['answer'];
|
||||
str = event.request.challengeAnswer!;
|
||||
strOrUndefined = event.request.password;
|
||||
boolOrUndefined = event.response.answerCorrect;
|
||||
strOrUndefined = event.response.smsMessage;
|
||||
strOrUndefined = event.response.emailMessage;
|
||||
strOrUndefined = event.response.emailSubject;
|
||||
strOrUndefined = event.response.challengeName;
|
||||
boolOrUndefined = event.response.issueTokens;
|
||||
boolOrUndefined = event.response.failAuthentication;
|
||||
str = event.response.publicChallengeParameters!['captchaUrl'];
|
||||
str = event.response.privateChallengeParameters!['answer'];
|
||||
strOrUndefined = event.response.challengeMetadata;
|
||||
boolOrUndefined = event.response.answerCorrect;
|
||||
str = event.response.userAttributes!['username'];
|
||||
event.response.finalUserStatus === 'CONFIRMED';
|
||||
event.response.finalUserStatus === 'RESET_REQUIRED';
|
||||
event.response.messageAction === 'SUPPRESS';
|
||||
event.response.desiredDeliveryMediums === ['EMAIL'];
|
||||
event.response.desiredDeliveryMediums === ['SMS'];
|
||||
event.response.desiredDeliveryMediums === ['SMS', 'EMAIL'];
|
||||
boolOrUndefined = event.response.forceAliasCreation;
|
||||
|
||||
// From AWS examples
|
||||
event.response = {
|
||||
claimsOverrideDetails: {
|
||||
claimsToAddOrOverride: {
|
||||
attribute_key2: 'attribute_value2',
|
||||
attribute_key: 'attribute_value',
|
||||
},
|
||||
claimsToSuppress: ['email'],
|
||||
},
|
||||
};
|
||||
event.response = {
|
||||
claimsOverrideDetails: {
|
||||
claimsToAddOrOverride: {
|
||||
attribute_key2: 'attribute_value2',
|
||||
attribute_key: 'attribute_value',
|
||||
},
|
||||
claimsToSuppress: ['email'],
|
||||
groupOverrideDetails: {
|
||||
groupsToOverride: ['group-A', 'group-B', 'group-C'],
|
||||
iamRolesToOverride: [
|
||||
'arn:aws:iam::XXXXXXXXXXXX:role/sns_callerA',
|
||||
'arn:aws:iam::XXXXXXXXX:role/sns_callerB',
|
||||
'arn:aws:iam::XXXXXXXXXX:role/sns_callerC',
|
||||
],
|
||||
preferredRole: 'arn:aws:iam::XXXXXXXXXXX:role/sns_caller',
|
||||
},
|
||||
},
|
||||
};
|
||||
event.response.claimsOverrideDetails!.groupOverrideDetails = null;
|
||||
|
||||
callback(new Error());
|
||||
callback(null, event);
|
||||
callback(null, {
|
||||
response: event.response,
|
||||
});
|
||||
return event;
|
||||
};
|
||||
@@ -0,0 +1,98 @@
|
||||
import { DynamoDBStreamEvent } from "aws-lambda";
|
||||
|
||||
// TODO: Update test to read all event properties, and write all result
|
||||
// properties, like the user will.
|
||||
|
||||
const event: DynamoDBStreamEvent = {
|
||||
Records: [
|
||||
{
|
||||
eventID: '1',
|
||||
eventVersion: '1.0',
|
||||
dynamodb: {
|
||||
Keys: {
|
||||
Id: {
|
||||
N: '101',
|
||||
},
|
||||
},
|
||||
NewImage: {
|
||||
Message: {
|
||||
S: 'New item!',
|
||||
},
|
||||
Id: {
|
||||
N: '101',
|
||||
},
|
||||
},
|
||||
StreamViewType: 'NEW_AND_OLD_IMAGES',
|
||||
SequenceNumber: '111',
|
||||
SizeBytes: 26,
|
||||
},
|
||||
awsRegion: 'us-west-2',
|
||||
eventName: 'INSERT',
|
||||
eventSourceARN:
|
||||
'arn:aws:dynamodb:us-west-2:account-id:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899',
|
||||
eventSource: 'aws:dynamodb',
|
||||
},
|
||||
{
|
||||
eventID: '2',
|
||||
eventVersion: '1.0',
|
||||
dynamodb: {
|
||||
OldImage: {
|
||||
Message: {
|
||||
S: 'New item!',
|
||||
},
|
||||
Id: {
|
||||
N: '101',
|
||||
},
|
||||
},
|
||||
SequenceNumber: '222',
|
||||
Keys: {
|
||||
Id: {
|
||||
N: '101',
|
||||
},
|
||||
},
|
||||
SizeBytes: 59,
|
||||
NewImage: {
|
||||
Message: {
|
||||
S: 'This item has changed',
|
||||
},
|
||||
Id: {
|
||||
N: '101',
|
||||
},
|
||||
},
|
||||
StreamViewType: 'NEW_AND_OLD_IMAGES',
|
||||
},
|
||||
awsRegion: 'us-west-2',
|
||||
eventName: 'MODIFY',
|
||||
eventSourceARN:
|
||||
'arn:aws:dynamodb:us-west-2:account-id:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899',
|
||||
eventSource: 'aws:dynamodb',
|
||||
},
|
||||
{
|
||||
eventID: '3',
|
||||
eventVersion: '1.0',
|
||||
dynamodb: {
|
||||
Keys: {
|
||||
Id: {
|
||||
N: '101',
|
||||
},
|
||||
},
|
||||
SizeBytes: 38,
|
||||
SequenceNumber: '333',
|
||||
OldImage: {
|
||||
Message: {
|
||||
S: 'This item has changed',
|
||||
},
|
||||
Id: {
|
||||
N: '101',
|
||||
},
|
||||
},
|
||||
StreamViewType: 'NEW_AND_OLD_IMAGES',
|
||||
},
|
||||
awsRegion: 'us-west-2',
|
||||
eventName: 'REMOVE',
|
||||
eventSourceARN:
|
||||
'arn:aws:dynamodb:us-west-2:account-id:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899',
|
||||
eventSource: 'aws:dynamodb',
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
import {
|
||||
FirehoseRecordTransformationStatus,
|
||||
FirehoseTransformationHandler, FirehoseTransformationResult,
|
||||
KinesisStreamHandler,
|
||||
KinesisStreamRecord,
|
||||
KinesisStreamRecordPayload,
|
||||
} from "aws-lambda";
|
||||
|
||||
const handler: KinesisStreamHandler = async (event, context, callback) => {
|
||||
let kinesisStreamRecord: KinesisStreamRecord;
|
||||
let kinesisStreamRecordPayload: KinesisStreamRecordPayload;
|
||||
|
||||
kinesisStreamRecord = event.Records[num];
|
||||
|
||||
str = kinesisStreamRecord.awsRegion;
|
||||
str = kinesisStreamRecord.eventID;
|
||||
str = kinesisStreamRecord.eventName;
|
||||
str = kinesisStreamRecord.eventSource;
|
||||
str = kinesisStreamRecord.eventSourceARN;
|
||||
str = kinesisStreamRecord.eventVersion;
|
||||
str = kinesisStreamRecord.invokeIdentityArn;
|
||||
kinesisStreamRecordPayload = kinesisStreamRecord.kinesis;
|
||||
|
||||
num = kinesisStreamRecordPayload.approximateArrivalTimestamp;
|
||||
str = kinesisStreamRecordPayload.data;
|
||||
str = kinesisStreamRecordPayload.kinesisSchemaVersion;
|
||||
str = kinesisStreamRecordPayload.partitionKey;
|
||||
str = kinesisStreamRecordPayload.sequenceNumber;
|
||||
|
||||
callback();
|
||||
callback(new Error());
|
||||
};
|
||||
|
||||
const firehoseHandler: FirehoseTransformationHandler = async (event, context, callback) => {
|
||||
str = event.records[0].recordId;
|
||||
|
||||
const result: FirehoseTransformationResult = {
|
||||
records: [
|
||||
{
|
||||
recordId: event.records[0].recordId,
|
||||
result: 'Ok' as FirehoseRecordTransformationStatus,
|
||||
data: 'eyJmb28iOiJiYXIifQ==',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
callback(new Error());
|
||||
callback(null, result);
|
||||
return result;
|
||||
};
|
||||
@@ -0,0 +1,122 @@
|
||||
import {
|
||||
LexDialogAction,
|
||||
LexDialogActionBase,
|
||||
LexDialogActionClose,
|
||||
LexDialogActionConfirmIntent,
|
||||
LexDialogActionDelegate,
|
||||
LexDialogActionElicitIntent,
|
||||
LexDialogActionElicitSlot,
|
||||
LexEvent,
|
||||
LexGenericAttachment,
|
||||
LexHandler,
|
||||
LexResult,
|
||||
} from "aws-lambda";
|
||||
|
||||
// TODO: Update test to read all event properties, and write all result
|
||||
// properties, like the user will.
|
||||
|
||||
const handler: LexHandler = async (event, context, callback) => {
|
||||
lexEvent = event;
|
||||
|
||||
let result: LexResult;
|
||||
result = {
|
||||
dialogAction: lexDialogAction,
|
||||
};
|
||||
result = {
|
||||
sessionAttributes: {
|
||||
attrib1: 'Value One',
|
||||
},
|
||||
dialogAction: {
|
||||
type: 'Close',
|
||||
fulfillmentState: 'Failed',
|
||||
},
|
||||
};
|
||||
|
||||
callback(new Error());
|
||||
callback(null, result);
|
||||
return result;
|
||||
};
|
||||
|
||||
declare let lexEvent: LexEvent;
|
||||
lexEvent = {
|
||||
currentIntent: {
|
||||
name: 'intent-name',
|
||||
slots: {
|
||||
slot1: null,
|
||||
slot2: 'value2',
|
||||
},
|
||||
slotDetails: {
|
||||
slot1: {
|
||||
resolutions: [{ value: 'value1' }],
|
||||
originalValue: 'originalValue',
|
||||
},
|
||||
},
|
||||
confirmationStatus: 'None',
|
||||
},
|
||||
bot: {
|
||||
name: 'bot name',
|
||||
alias: 'bot alias',
|
||||
version: 'bot version',
|
||||
},
|
||||
userId: 'User ID specified in the POST request to Amazon Lex.',
|
||||
inputTranscript: 'Text used to process the request',
|
||||
invocationSource: 'FulfillmentCodeHook',
|
||||
outputDialogMode: 'Text',
|
||||
messageVersion: '1.0',
|
||||
sessionAttributes: {
|
||||
key1: 'value1',
|
||||
key2: 'value2',
|
||||
},
|
||||
requestAttributes: {
|
||||
key1: 'value1',
|
||||
key2: 'value2',
|
||||
},
|
||||
};
|
||||
|
||||
declare let lexDialogAction: LexDialogAction;
|
||||
declare let lexDialogActionBase: LexDialogActionBase;
|
||||
declare let lexDialogActionClose: LexDialogActionClose;
|
||||
declare let lexDialogActionConfirmIntent: LexDialogActionConfirmIntent;
|
||||
declare let lexDialogActionDelegate: LexDialogActionDelegate;
|
||||
declare let lexDialogActionElicitIntent: LexDialogActionElicitIntent;
|
||||
declare let lexDialogActionElicitSlot: LexDialogActionElicitSlot;
|
||||
declare let lexGenericAttachment: LexGenericAttachment;
|
||||
|
||||
str = lexGenericAttachment.title;
|
||||
str = lexGenericAttachment.subTitle;
|
||||
str = lexGenericAttachment.imageUrl;
|
||||
str = lexGenericAttachment.attachmentLinkUrl;
|
||||
str = lexGenericAttachment.buttons[0].text;
|
||||
str = lexGenericAttachment.buttons[0].value;
|
||||
|
||||
lexDialogAction.type === 'Close';
|
||||
lexDialogAction.type === 'ConfirmIntent';
|
||||
lexDialogAction.type === 'Delegate';
|
||||
lexDialogAction.type === 'ElicitIntent';
|
||||
lexDialogAction.type === 'ElicitSlot';
|
||||
|
||||
lexDialogActionBase.message!.contentType === 'CustomPayload';
|
||||
lexDialogActionBase.message!.contentType === 'PlainText';
|
||||
lexDialogActionBase.message!.contentType === 'SSML';
|
||||
str = lexDialogActionBase.message!.content;
|
||||
num = lexDialogActionBase.responseCard!.version;
|
||||
lexDialogActionBase.responseCard!.contentType === 'application/vnd.amazonaws.card.generic';
|
||||
// $ExpectType LexGenericAttachment
|
||||
lexDialogActionBase.responseCard!.genericAttachments[0];
|
||||
|
||||
lexDialogActionClose.type === 'Close';
|
||||
lexDialogActionClose.fulfillmentState === 'Failed';
|
||||
lexDialogActionClose.fulfillmentState === 'Fulfilled';
|
||||
|
||||
lexDialogActionConfirmIntent.type === 'ConfirmIntent';
|
||||
str = lexDialogActionConfirmIntent.intentName;
|
||||
strOrNull = lexDialogActionConfirmIntent.slots['example'];
|
||||
|
||||
lexDialogActionDelegate.type === 'Delegate';
|
||||
strOrNull = lexDialogActionDelegate.slots['example'];
|
||||
|
||||
lexDialogActionElicitIntent.type === 'ElicitIntent';
|
||||
lexDialogActionElicitSlot.type === 'ElicitSlot';
|
||||
strOrNull = lexDialogActionElicitSlot.slots['example'];
|
||||
str = lexDialogActionElicitSlot.slotToElicit;
|
||||
str = lexDialogActionElicitSlot.intentName;
|
||||
@@ -0,0 +1,102 @@
|
||||
import { Callback, Context, S3BatchEvent, S3BatchResult, S3CreateEvent, S3EventRecord, S3Handler } from "aws-lambda";
|
||||
|
||||
// TODO: Update test to read event properties, like the user will
|
||||
let handler: S3Handler = async (event, context, callback) => {
|
||||
callback(new Error());
|
||||
};
|
||||
|
||||
// Test old event name
|
||||
handler = (event: S3CreateEvent, context: Context, cb: Callback<void>) => {};
|
||||
|
||||
const record: S3EventRecord = {
|
||||
eventVersion: '2.1',
|
||||
eventSource: 'aws:s3',
|
||||
awsRegion: 'us-east-1',
|
||||
eventTime: '1970-01-01T00:00:00.000Z',
|
||||
eventName: 'ObjectRestore:Completed',
|
||||
userIdentity: {
|
||||
principalId: 'AIDAJDPLRKLG7UEXAMPLE',
|
||||
},
|
||||
requestParameters: {
|
||||
sourceIPAddress: '127.0.0.1',
|
||||
},
|
||||
responseElements: {
|
||||
'x-amz-request-id': 'C3D13FE58DE4C810',
|
||||
'x-amz-id-2': 'FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD',
|
||||
},
|
||||
s3: {
|
||||
s3SchemaVersion: '1.0',
|
||||
configurationId: 'testConfigRule',
|
||||
bucket: {
|
||||
name: 'mybucket',
|
||||
ownerIdentity: {
|
||||
principalId: 'A3NL1KOZZKExample',
|
||||
},
|
||||
arn: 'arn:aws:s3:::mybucket',
|
||||
},
|
||||
object: {
|
||||
key: 'HappyFace.jpg',
|
||||
size: 1024,
|
||||
eTag: 'd41d8cd98f00b204e9800998ecf8427e',
|
||||
versionId: '096fKKXTRTtl3on89fVO.nfljtsv6qko',
|
||||
sequencer: '0055AED6DCD90281E5',
|
||||
},
|
||||
},
|
||||
glacierEventData: {
|
||||
restoreEventData: {
|
||||
lifecycleRestorationExpiryTime: '1970-01-01T00:00:00.000Z',
|
||||
lifecycleRestoreStorageClass: 'glacier-deep-archive',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const event: S3CreateEvent = {
|
||||
Records: [record],
|
||||
};
|
||||
|
||||
/**
|
||||
* S3 Batch Operations event
|
||||
* https://docs.aws.amazon.com/AmazonS3/latest/dev/batch-ops-invoke-lambda.html
|
||||
*/
|
||||
const batchEvent: S3BatchEvent = {
|
||||
invocationSchemaVersion: '1.0',
|
||||
invocationId: 'foo_invocation_id',
|
||||
job: { id: 'foo_job_id' },
|
||||
tasks: [
|
||||
{
|
||||
taskId: '11111',
|
||||
s3Key: 'example.json',
|
||||
s3BucketArn: 'arn:aws:s3:::foo-bucket',
|
||||
s3VersionId: null,
|
||||
},
|
||||
{
|
||||
taskId: '11111',
|
||||
s3Key: 'example.json',
|
||||
s3BucketArn: 'arn:aws:s3:::foo-bucket',
|
||||
s3VersionId: 'asdf',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const batchResult: S3BatchResult = {
|
||||
invocationSchemaVersion: '1.0',
|
||||
treatMissingKeysAs: 'PermanentFailure',
|
||||
invocationId: 'foo_invocation_id',
|
||||
results: [
|
||||
{
|
||||
taskId: '11111',
|
||||
resultCode: 'Succeeded',
|
||||
resultString: 'foo',
|
||||
},
|
||||
{
|
||||
taskId: '22222',
|
||||
resultCode: 'TemporaryFailure',
|
||||
resultString: 'Error: failure',
|
||||
},
|
||||
{
|
||||
taskId: '33333',
|
||||
resultCode: 'PermanentFailure',
|
||||
resultString: 'Error: failure',
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import { SNSEventRecord, SNSHandler, SNSMessage, SNSMessageAttribute, SNSMessageAttributes } from "aws-lambda";
|
||||
|
||||
const handler: SNSHandler = async (event, context, callback) => {
|
||||
const record: SNSEventRecord = event.Records[num];
|
||||
|
||||
str = record.EventSource;
|
||||
str = record.EventSubscriptionArn;
|
||||
str = record.EventVersion;
|
||||
const message: SNSMessage = record.Sns;
|
||||
|
||||
str = message.SignatureVersion;
|
||||
str = message.Timestamp;
|
||||
str = message.Signature;
|
||||
str = message.SigningCertUrl;
|
||||
str = message.MessageId;
|
||||
str = message.Message;
|
||||
const attributes: SNSMessageAttributes = message.MessageAttributes;
|
||||
str = message.Type;
|
||||
str = message.UnsubscribeUrl;
|
||||
str = message.TopicArn;
|
||||
str = message.Subject;
|
||||
|
||||
const attribute: SNSMessageAttribute = attributes[str];
|
||||
str = attribute.Type;
|
||||
str = attribute.Value;
|
||||
|
||||
callback();
|
||||
callback(new Error());
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
import { SQSEvent, SQSHandler } from "aws-lambda";
|
||||
|
||||
// TODO: Update test to read all event properties, like the user will.
|
||||
|
||||
const handler: SQSHandler = async (event, context, callback) => {
|
||||
str = event.Records[0].messageId;
|
||||
anyObj = event.Records[0].body;
|
||||
strOrUndefined = event.Records[0].messageAttributes.testAttr.stringValue;
|
||||
strOrUndefined = event.Records[0].messageAttributes.testAttr.binaryValue;
|
||||
str = event.Records[0].messageAttributes.testAttr.dataType;
|
||||
|
||||
callback();
|
||||
callback(new Error());
|
||||
};
|
||||
|
||||
// See https://docs.aws.amazon.com/lambda/latest/dg/eventsources.html#eventsources-sqs
|
||||
const event: SQSEvent = {
|
||||
Records: [
|
||||
{
|
||||
messageId: 'c80e8021-a70a-42c7-a470-796e1186f753',
|
||||
receiptHandle: 'AQEBJQ+/u6NsnT5t8Q/VbVxgdUl4TMKZ5FqhksRdIQvLBhwNvADoBxYSOVeCBXdnS9P+',
|
||||
body: '{"foo":"bar"}',
|
||||
attributes: {
|
||||
ApproximateReceiveCount: '3',
|
||||
SentTimestamp: '1529104986221',
|
||||
SenderId: '594035263019',
|
||||
ApproximateFirstReceiveTimestamp: '1529104986230',
|
||||
},
|
||||
messageAttributes: {
|
||||
testAttr: {
|
||||
stringValue: '100',
|
||||
binaryValue: 'base64Str',
|
||||
stringListValues: [],
|
||||
binaryListValues: [],
|
||||
dataType: 'Number',
|
||||
},
|
||||
},
|
||||
md5OfBody: '9bb58f26192e4ba00f01e2e7b136bbd8',
|
||||
eventSource: 'aws:sqs',
|
||||
eventSourceARN: 'arn:aws:sqs:us-west-2:594035263019:NOTFIFOQUEUE',
|
||||
awsRegion: 'us-west-2',
|
||||
},
|
||||
],
|
||||
};
|
||||
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
import { Handler, Callback } from "../hander";
|
||||
|
||||
export type ALBHandler = Handler<ALBEvent, ALBResult>;
|
||||
export type ALBCallback = Callback<ALBResult>;
|
||||
|
||||
// https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html
|
||||
export interface ALBEventRequestContext {
|
||||
elb: {
|
||||
targetGroupArn: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ALBEvent {
|
||||
requestContext: ALBEventRequestContext;
|
||||
httpMethod: string;
|
||||
path: string;
|
||||
queryStringParameters?: { [parameter: string]: string }; // URL encoded
|
||||
headers?: { [header: string]: string };
|
||||
multiValueQueryStringParameters?: { [parameter: string]: string[] }; // URL encoded
|
||||
multiValueHeaders?: { [header: string]: string[] };
|
||||
body: string | null;
|
||||
isBase64Encoded: boolean;
|
||||
}
|
||||
|
||||
export interface ALBResult {
|
||||
statusCode: number;
|
||||
statusDescription: string;
|
||||
headers?: { [header: string]: boolean | number | string };
|
||||
multiValueHeaders?: { [header: string]: Array<boolean | number | string> };
|
||||
body?: string;
|
||||
isBase64Encoded: boolean;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import { APIGatewayEventRequestContext, AuthResponseContext } from "../common/api-gateway";
|
||||
import { Callback, Handler } from "../hander";
|
||||
|
||||
export type CustomAuthorizerHandler = Handler<CustomAuthorizerEvent, CustomAuthorizerResult>;
|
||||
export type CustomAuthorizerCallback = Callback<CustomAuthorizerResult>;
|
||||
|
||||
// API Gateway CustomAuthorizer "event"
|
||||
export interface CustomAuthorizerEvent {
|
||||
type: string;
|
||||
methodArn: string;
|
||||
authorizationToken?: string;
|
||||
resource?: string;
|
||||
path?: string;
|
||||
httpMethod?: string;
|
||||
headers?: { [name: string]: string };
|
||||
multiValueHeaders?: { [name: string]: string[] };
|
||||
pathParameters?: { [name: string]: string } | null;
|
||||
queryStringParameters?: { [name: string]: string } | null;
|
||||
multiValueQueryStringParameters?: { [name: string]: string[] } | null;
|
||||
stageVariables?: { [name: string]: string };
|
||||
requestContext?: APIGatewayEventRequestContext;
|
||||
domainName?: string;
|
||||
apiId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* API Gateway CustomAuthorizer AuthResponse.
|
||||
* http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html#api-gateway-custom-authorizer-output
|
||||
*/
|
||||
export interface CustomAuthorizerResult {
|
||||
principalId: string;
|
||||
policyDocument: PolicyDocument;
|
||||
context?: AuthResponseContext;
|
||||
usageIdentifierKey?: string;
|
||||
}
|
||||
export type AuthResponse = CustomAuthorizerResult;
|
||||
|
||||
/**
|
||||
* API Gateway CustomAuthorizer AuthResponse.PolicyDocument.
|
||||
* https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html
|
||||
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Condition
|
||||
*/
|
||||
export interface PolicyDocument {
|
||||
Version: string;
|
||||
Id?: string;
|
||||
Statement: Statement[];
|
||||
}
|
||||
|
||||
/**
|
||||
* API Gateway CustomAuthorizer AuthResponse.PolicyDocument.Condition.
|
||||
* https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-policy-language-overview.html
|
||||
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html
|
||||
*/
|
||||
export interface ConditionBlock {
|
||||
[condition: string]: Condition | Condition[];
|
||||
}
|
||||
|
||||
export interface Condition {
|
||||
[key: string]: string | string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* API Gateway CustomAuthorizer AuthResponse.PolicyDocument.Statement.
|
||||
* https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-policy-language-overview.html
|
||||
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html
|
||||
*/
|
||||
export type Statement = BaseStatement & StatementAction & (StatementResource | StatementPrincipal);
|
||||
|
||||
export interface BaseStatement {
|
||||
Effect: string;
|
||||
Sid?: string;
|
||||
Condition?: ConditionBlock;
|
||||
}
|
||||
|
||||
export type PrincipalValue = { [key: string]: string | string[] } | string | string[];
|
||||
export interface MaybeStatementPrincipal {
|
||||
Principal?: PrincipalValue;
|
||||
NotPrincipal?: PrincipalValue;
|
||||
}
|
||||
export interface MaybeStatementResource {
|
||||
Resource?: string | string[];
|
||||
NotResource?: string | string[];
|
||||
}
|
||||
export type StatementAction = { Action: string | string[] } | { NotAction: string | string[] };
|
||||
export type StatementResource = MaybeStatementPrincipal &
|
||||
({ Resource: string | string[] } | { NotResource: string | string[] });
|
||||
export type StatementPrincipal = MaybeStatementResource &
|
||||
({ Principal: PrincipalValue } | { NotPrincipal: PrincipalValue });
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import { APIGatewayEventRequestContext } from "../common/api-gateway";
|
||||
import { Callback, Handler } from "../hander";
|
||||
|
||||
export type APIGatewayProxyHandler = Handler<APIGatewayProxyEvent, APIGatewayProxyResult>;
|
||||
export type APIGatewayProxyCallback = Callback<APIGatewayProxyResult>;
|
||||
|
||||
export type ProxyHandler = APIGatewayProxyHandler; // Old name
|
||||
export type ProxyCallback = APIGatewayProxyCallback; // Old name
|
||||
export type APIGatewayEvent = APIGatewayProxyEvent; // Old name
|
||||
export type ProxyResult = APIGatewayProxyResult; // Old name
|
||||
|
||||
// API Gateway "event"
|
||||
export interface APIGatewayProxyEvent {
|
||||
body: string | null;
|
||||
headers: { [name: string]: string };
|
||||
multiValueHeaders: { [name: string]: string[] };
|
||||
httpMethod: string;
|
||||
isBase64Encoded: boolean;
|
||||
path: string;
|
||||
pathParameters: { [name: string]: string } | null;
|
||||
queryStringParameters: { [name: string]: string } | null;
|
||||
multiValueQueryStringParameters: { [name: string]: string[] } | null;
|
||||
stageVariables: { [name: string]: string } | null;
|
||||
requestContext: APIGatewayEventRequestContext;
|
||||
resource: string;
|
||||
}
|
||||
|
||||
export interface APIGatewayProxyResult {
|
||||
statusCode: number;
|
||||
headers?: {
|
||||
[header: string]: boolean | number | string;
|
||||
};
|
||||
multiValueHeaders?: {
|
||||
[header: string]: Array<boolean | number | string>;
|
||||
};
|
||||
body: string;
|
||||
isBase64Encoded?: boolean;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
// Note, responses are *not* lambda results, they are sent to the event ResponseURL.
|
||||
export type CloudFormationCustomResourceHandler = Handler<CloudFormationCustomResourceEvent, void>;
|
||||
|
||||
export type CloudFormationCustomResourceEvent =
|
||||
| CloudFormationCustomResourceCreateEvent
|
||||
| CloudFormationCustomResourceUpdateEvent
|
||||
| CloudFormationCustomResourceDeleteEvent;
|
||||
|
||||
export type CloudFormationCustomResourceResponse =
|
||||
| CloudFormationCustomResourceSuccessResponse
|
||||
| CloudFormationCustomResourceFailedResponse;
|
||||
|
||||
/**
|
||||
* CloudFormation Custom Resource event and response
|
||||
* http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref.html
|
||||
*/
|
||||
export interface CloudFormationCustomResourceEventCommon {
|
||||
ServiceToken: string;
|
||||
ResponseURL: string;
|
||||
StackId: string;
|
||||
RequestId: string;
|
||||
LogicalResourceId: string;
|
||||
ResourceType: string;
|
||||
ResourceProperties: {
|
||||
ServiceToken: string;
|
||||
[Key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CloudFormationCustomResourceCreateEvent extends CloudFormationCustomResourceEventCommon {
|
||||
RequestType: 'Create';
|
||||
}
|
||||
|
||||
export interface CloudFormationCustomResourceUpdateEvent extends CloudFormationCustomResourceEventCommon {
|
||||
RequestType: 'Update';
|
||||
PhysicalResourceId: string;
|
||||
OldResourceProperties: {
|
||||
[Key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CloudFormationCustomResourceDeleteEvent extends CloudFormationCustomResourceEventCommon {
|
||||
RequestType: 'Delete';
|
||||
PhysicalResourceId: string;
|
||||
}
|
||||
|
||||
export interface CloudFormationCustomResourceResponseCommon {
|
||||
PhysicalResourceId: string;
|
||||
StackId: string;
|
||||
RequestId: string;
|
||||
LogicalResourceId: string;
|
||||
Data?: {
|
||||
[Key: string]: any;
|
||||
};
|
||||
NoEcho?: boolean;
|
||||
}
|
||||
|
||||
export interface CloudFormationCustomResourceSuccessResponse extends CloudFormationCustomResourceResponseCommon {
|
||||
Status: 'SUCCESS';
|
||||
Reason?: string;
|
||||
}
|
||||
|
||||
export interface CloudFormationCustomResourceFailedResponse extends CloudFormationCustomResourceResponseCommon {
|
||||
Status: 'FAILED';
|
||||
Reason: string;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { CloudFrontEvent, CloudFrontRequest, CloudFrontResultResponse } from "../common/cloudfront";
|
||||
import { Handler, Callback } from "../hander";
|
||||
|
||||
export type CloudFrontRequestHandler = Handler<CloudFrontRequestEvent, CloudFrontRequestResult>;
|
||||
export type CloudFrontRequestCallback = Callback<CloudFrontRequestResult>;
|
||||
|
||||
/**
|
||||
* CloudFront viewer request or origin request event
|
||||
*
|
||||
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html#lambda-event-structure-request
|
||||
*/
|
||||
export interface CloudFrontRequestEvent {
|
||||
Records: Array<{
|
||||
cf: CloudFrontEvent & {
|
||||
request: CloudFrontRequest;
|
||||
};
|
||||
}>;
|
||||
}
|
||||
|
||||
export type CloudFrontRequestResult = undefined | null | CloudFrontResultResponse | CloudFrontRequest;
|
||||
@@ -0,0 +1,21 @@
|
||||
import { CloudFrontEvent, CloudFrontRequest, CloudFrontResponse, CloudFrontResultResponse } from "../common/cloudfront";
|
||||
import { Callback, Handler } from "../hander";
|
||||
|
||||
export type CloudFrontResponseHandler = Handler<CloudFrontResponseEvent, CloudFrontResponseResult>;
|
||||
export type CloudFrontResponseCallback = Callback<CloudFrontResponseResult>;
|
||||
|
||||
/**
|
||||
* CloudFront viewer response or origin response event
|
||||
*
|
||||
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html#lambda-event-structure-response
|
||||
*/
|
||||
export interface CloudFrontResponseEvent {
|
||||
Records: Array<{
|
||||
cf: CloudFrontEvent & {
|
||||
readonly request: Pick<CloudFrontRequest, Exclude<keyof CloudFrontRequest, 'body'>>;
|
||||
response: CloudFrontResponse;
|
||||
};
|
||||
}>;
|
||||
}
|
||||
|
||||
export type CloudFrontResponseResult = undefined | null | CloudFrontResultResponse;
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
export type ScheduledHandler = Handler<ScheduledEvent, void>;
|
||||
|
||||
// TODO: generic cloudwatch event types.
|
||||
|
||||
/**
|
||||
* https://docs.aws.amazon.com/lambda/latest/dg/with-scheduled-events.html
|
||||
*/
|
||||
export interface ScheduledEvent {
|
||||
account: string;
|
||||
region: string;
|
||||
detail: any;
|
||||
'detail-type': string;
|
||||
source: string;
|
||||
time: string;
|
||||
id: string;
|
||||
resources: string[];
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
export type CloudWatchLogsHandler = Handler<CloudWatchLogsEvent, void>;
|
||||
|
||||
/**
|
||||
* See http://docs.aws.amazon.com/lambda/latest/dg/eventsources.html#eventsources-cloudwatch-logs
|
||||
*/
|
||||
export interface CloudWatchLogsEvent {
|
||||
awslogs: CloudWatchLogsEventData;
|
||||
}
|
||||
|
||||
export interface CloudWatchLogsEventData {
|
||||
data: string;
|
||||
}
|
||||
|
||||
export interface CloudWatchLogsDecodedData {
|
||||
owner: string;
|
||||
logGroup: string;
|
||||
logStream: string;
|
||||
subscriptionFilters: string[];
|
||||
messageType: string;
|
||||
logEvents: CloudWatchLogsLogEvent[];
|
||||
}
|
||||
|
||||
/**
|
||||
* See http://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#LambdaFunctionExample
|
||||
*/
|
||||
export interface CloudWatchLogsLogEvent {
|
||||
id: string;
|
||||
timestamp: number;
|
||||
message: string;
|
||||
extractedFields?: { [key: string]: string };
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
export type CodePipelineCloudWatchActionHandler = Handler<CodePipelineCloudWatchActionEvent, void>;
|
||||
|
||||
export type CodePipelineActionCategory = 'Approval' | 'Build' | 'Deploy' | 'Invoke' | 'Source' | 'Test';
|
||||
export type CodePipelineActionState = 'STARTED' | 'SUCCEEDED' | 'FAILED' | 'CANCELED';
|
||||
|
||||
export interface CodePipelineCloudWatchActionEvent {
|
||||
version: string;
|
||||
id: string;
|
||||
'detail-type': 'CodePipeline Action Execution State Change';
|
||||
source: 'aws.codepipeline';
|
||||
account: string;
|
||||
time: string;
|
||||
region: string;
|
||||
resources: string[];
|
||||
detail: {
|
||||
pipeline: string;
|
||||
version: number;
|
||||
'execution-id': string;
|
||||
stage: string;
|
||||
action: string;
|
||||
state: CodePipelineActionState;
|
||||
type: {
|
||||
owner: 'AWS' | 'Custom' | 'ThirdParty';
|
||||
category: CodePipelineActionCategory;
|
||||
provider: string;
|
||||
version: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
export type CodePipelineCloudWatchPipelineHandler = Handler<CodePipelineCloudWatchPipelineEvent, void>;
|
||||
|
||||
export type CodePipelineState = 'STARTED' | 'SUCCEEDED' | 'RESUMED' | 'FAILED' | 'CANCELED' | 'SUPERSEDED';
|
||||
|
||||
/**
|
||||
* CodePipeline CloudWatch Events
|
||||
* https://docs.aws.amazon.com/codepipeline/latest/userguide/detect-state-changes-cloudwatch-events.html
|
||||
*
|
||||
* The above CodePipelineEvent is when a lambda is invoked by a CodePipeline.
|
||||
* These events are when you subscribe to CodePipeline events in CloudWatch.
|
||||
*
|
||||
* Their documentation says that detail.version is a string, but it is actually an integer
|
||||
*/
|
||||
|
||||
export interface CodePipelineCloudWatchPipelineEvent {
|
||||
version: string;
|
||||
id: string;
|
||||
'detail-type': 'CodePipeline Pipeline Execution State Change';
|
||||
source: 'aws.codepipeline';
|
||||
account: string;
|
||||
time: string;
|
||||
region: string;
|
||||
resources: string[];
|
||||
detail: {
|
||||
pipeline: string;
|
||||
version: number;
|
||||
state: CodePipelineState;
|
||||
'execution-id': string;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
export type CodePipelineCloudWatchStageHandler = Handler<CodePipelineCloudWatchStageEvent, void>;
|
||||
|
||||
export type CodePipelineStageState = 'STARTED' | 'SUCCEEDED' | 'RESUMED' | 'FAILED' | 'CANCELED';
|
||||
|
||||
export interface CodePipelineCloudWatchStageEvent {
|
||||
version: string;
|
||||
id: string;
|
||||
'detail-type': 'CodePipeline Stage Execution State Change';
|
||||
source: 'aws.codepipeline';
|
||||
account: string;
|
||||
time: string;
|
||||
region: string;
|
||||
resources: string[];
|
||||
detail: {
|
||||
pipeline: string;
|
||||
version: number;
|
||||
'execution-id': string;
|
||||
stage: string;
|
||||
state: CodePipelineStageState;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Handler } from "../hander";
|
||||
import { CodePipelineCloudWatchActionEvent } from "./codepipeline-cloudwatch-action";
|
||||
import { CodePipelineCloudWatchPipelineEvent } from "./codepipeline-cloudwatch-pipeline";
|
||||
import { CodePipelineCloudWatchStageEvent } from "./codepipeline-cloudwatch-stage";
|
||||
|
||||
export type CodePipelineCloudWatchHandler = Handler<CodePipelineCloudWatchEvent, void>;
|
||||
|
||||
export type CodePipelineCloudWatchEvent =
|
||||
| CodePipelineCloudWatchPipelineEvent
|
||||
| CodePipelineCloudWatchStageEvent
|
||||
| CodePipelineCloudWatchActionEvent;
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
export type CodePipelineHandler = Handler<CodePipelineEvent, void>;
|
||||
|
||||
/**
|
||||
* CodePipeline events
|
||||
* https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html
|
||||
*/
|
||||
export interface S3ArtifactLocation {
|
||||
bucketName: string;
|
||||
objectKey: string;
|
||||
}
|
||||
export interface S3ArtifactStore {
|
||||
type: 'S3';
|
||||
s3Location: S3ArtifactLocation;
|
||||
}
|
||||
|
||||
export type ArtifactLocation = S3ArtifactStore;
|
||||
|
||||
export interface Artifact {
|
||||
name: string;
|
||||
revision: string | null;
|
||||
location: ArtifactLocation;
|
||||
}
|
||||
|
||||
export interface Credentials {
|
||||
accessKeyId: string;
|
||||
secretAccessKey: string;
|
||||
sessionToken?: string;
|
||||
}
|
||||
|
||||
export interface EncryptionKey {
|
||||
type: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface CodePipelineEvent {
|
||||
'CodePipeline.job': {
|
||||
id: string;
|
||||
accountId: string;
|
||||
data: {
|
||||
actionConfiguration: {
|
||||
configuration: {
|
||||
FunctionName: string;
|
||||
UserParameters: string;
|
||||
};
|
||||
};
|
||||
inputArtifacts: Artifact[];
|
||||
outputArtifacts: Artifact[];
|
||||
artifactCredentials: Credentials;
|
||||
encryptionKey?: EncryptionKey & { type: 'KMS' };
|
||||
continuationToken?: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
// Result type is weird: docs and samples say to return the mutated event, but it only requires an object
|
||||
// with a "response" field, the type of which is specific to the event.triggerType. Leave as any for now.
|
||||
export type CognitoUserPoolTriggerHandler = Handler<CognitoUserPoolTriggerEvent>;
|
||||
// TODO: Different event/handler types for each event trigger so we can type the result?
|
||||
|
||||
/**
|
||||
* Cognito User Pool event
|
||||
* http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html
|
||||
*/
|
||||
export interface CognitoUserPoolTriggerEvent {
|
||||
version: number;
|
||||
triggerSource:
|
||||
| 'PreSignUp_SignUp'
|
||||
| 'PreSignUp_ExternalProvider'
|
||||
| 'PostConfirmation_ConfirmSignUp'
|
||||
| 'PreAuthentication_Authentication'
|
||||
| 'PostAuthentication_Authentication'
|
||||
| 'CustomMessage_SignUp'
|
||||
| 'CustomMessage_AdminCreateUser'
|
||||
| 'CustomMessage_ResendCode'
|
||||
| 'CustomMessage_ForgotPassword'
|
||||
| 'CustomMessage_UpdateUserAttribute'
|
||||
| 'CustomMessage_VerifyUserAttribute'
|
||||
| 'CustomMessage_Authentication'
|
||||
| 'DefineAuthChallenge_Authentication'
|
||||
| 'CreateAuthChallenge_Authentication'
|
||||
| 'VerifyAuthChallengeResponse_Authentication'
|
||||
| 'PreSignUp_AdminCreateUser'
|
||||
| 'PostConfirmation_ConfirmForgotPassword'
|
||||
| 'TokenGeneration_HostedAuth'
|
||||
| 'TokenGeneration_Authentication'
|
||||
| 'TokenGeneration_NewPasswordChallenge'
|
||||
| 'TokenGeneration_AuthenticateDevice'
|
||||
| 'TokenGeneration_RefreshTokens'
|
||||
| 'UserMigration_Authentication'
|
||||
| 'UserMigration_ForgotPassword';
|
||||
region: string;
|
||||
userPoolId: string;
|
||||
userName?: string;
|
||||
callerContext: {
|
||||
awsSdkVersion: string;
|
||||
clientId: string;
|
||||
};
|
||||
request: {
|
||||
userAttributes: { [key: string]: string };
|
||||
validationData?: { [key: string]: string };
|
||||
codeParameter?: string;
|
||||
linkParameter?: string;
|
||||
usernameParameter?: string;
|
||||
newDeviceUsed?: boolean;
|
||||
session?: Array<{
|
||||
challengeName:
|
||||
| 'CUSTOM_CHALLENGE'
|
||||
| 'PASSWORD_VERIFIER'
|
||||
| 'SMS_MFA'
|
||||
| 'DEVICE_SRP_AUTH'
|
||||
| 'DEVICE_PASSWORD_VERIFIER'
|
||||
| 'ADMIN_NO_SRP_AUTH';
|
||||
challengeResult: boolean;
|
||||
challengeMetadata?: string;
|
||||
}>;
|
||||
challengeName?: string;
|
||||
privateChallengeParameters?: { [key: string]: string };
|
||||
challengeAnswer?: string;
|
||||
password?: string;
|
||||
};
|
||||
response: {
|
||||
autoConfirmUser?: boolean;
|
||||
autoVerifyPhone?: boolean;
|
||||
autoVerifyEmail?: boolean;
|
||||
smsMessage?: string;
|
||||
emailMessage?: string;
|
||||
emailSubject?: string;
|
||||
challengeName?: string;
|
||||
issueTokens?: boolean;
|
||||
failAuthentication?: boolean;
|
||||
publicChallengeParameters?: { [key: string]: string };
|
||||
privateChallengeParameters?: { [key: string]: string };
|
||||
challengeMetadata?: string;
|
||||
answerCorrect?: boolean;
|
||||
userAttributes?: { [key: string]: string };
|
||||
finalUserStatus?: 'CONFIRMED' | 'RESET_REQUIRED';
|
||||
messageAction?: 'SUPPRESS';
|
||||
desiredDeliveryMediums?: Array<'EMAIL' | 'SMS'>;
|
||||
forceAliasCreation?: boolean;
|
||||
claimsOverrideDetails?: {
|
||||
claimsToAddOrOverride?: { [key: string]: string };
|
||||
claimsToSuppress?: string[];
|
||||
groupOverrideDetails?: null | {
|
||||
groupsToOverride?: string[];
|
||||
iamRolesToOverride?: string[];
|
||||
preferredRole?: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
export type CognitoUserPoolEvent = CognitoUserPoolTriggerEvent;
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
export type DynamoDBStreamHandler = Handler<DynamoDBStreamEvent, void>;
|
||||
|
||||
// http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_streams_AttributeValue.html
|
||||
export interface AttributeValue {
|
||||
B?: string;
|
||||
BS?: string[];
|
||||
BOOL?: boolean;
|
||||
L?: AttributeValue[];
|
||||
M?: { [id: string]: AttributeValue };
|
||||
N?: string;
|
||||
NS?: string[];
|
||||
NULL?: boolean;
|
||||
S?: string;
|
||||
SS?: string[];
|
||||
}
|
||||
|
||||
// http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_streams_StreamRecord.html
|
||||
export interface StreamRecord {
|
||||
ApproximateCreationDateTime?: number;
|
||||
Keys?: { [key: string]: AttributeValue };
|
||||
NewImage?: { [key: string]: AttributeValue };
|
||||
OldImage?: { [key: string]: AttributeValue };
|
||||
SequenceNumber?: string;
|
||||
SizeBytes?: number;
|
||||
StreamViewType?: 'KEYS_ONLY' | 'NEW_IMAGE' | 'OLD_IMAGE' | 'NEW_AND_OLD_IMAGES';
|
||||
}
|
||||
|
||||
// http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_streams_Record.html
|
||||
export interface DynamoDBRecord {
|
||||
awsRegion?: string;
|
||||
dynamodb?: StreamRecord;
|
||||
eventID?: string;
|
||||
eventName?: 'INSERT' | 'MODIFY' | 'REMOVE';
|
||||
eventSource?: string;
|
||||
eventSourceARN?: string;
|
||||
eventVersion?: string;
|
||||
userIdentity?: any;
|
||||
}
|
||||
|
||||
// http://docs.aws.amazon.com/lambda/latest/dg/eventsources.html#eventsources-ddb-update
|
||||
export interface DynamoDBStreamEvent {
|
||||
Records: DynamoDBRecord[];
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Callback, Handler } from "../hander";
|
||||
|
||||
export type FirehoseTransformationHandler = Handler<FirehoseTransformationEvent, FirehoseTransformationResult>;
|
||||
export type FirehoseTransformationCallback = Callback<FirehoseTransformationResult>;
|
||||
|
||||
// Kinesis Data Firehose Event
|
||||
// https://docs.aws.amazon.com/lambda/latest/dg/eventsources.html#eventsources-kinesis-firehose
|
||||
// https://docs.aws.amazon.com/firehose/latest/dev/data-transformation.html
|
||||
// https://aws.amazon.com/blogs/compute/amazon-kinesis-firehose-data-transformation-with-aws-lambda/
|
||||
// Examples in the lambda blueprints
|
||||
export interface FirehoseTransformationEvent {
|
||||
invocationId: string;
|
||||
deliveryStreamArn: string;
|
||||
region: string;
|
||||
records: FirehoseTransformationEventRecord[];
|
||||
}
|
||||
|
||||
export interface FirehoseTransformationEventRecord {
|
||||
recordId: string;
|
||||
approximateArrivalTimestamp: number;
|
||||
/** Base64 encoded */
|
||||
data: string;
|
||||
kinesisRecordMetadata?: FirehoseRecordMetadata;
|
||||
}
|
||||
|
||||
export interface FirehoseRecordMetadata {
|
||||
shardId: string;
|
||||
partitionKey: string;
|
||||
approximateArrivalTimestamp: string;
|
||||
sequenceNumber: string;
|
||||
subsequenceNumber: string;
|
||||
}
|
||||
|
||||
export type FirehoseRecordTransformationStatus = 'Ok' | 'Dropped' | 'ProcessingFailed';
|
||||
|
||||
export interface FirehoseTransformationResultRecord {
|
||||
recordId: string;
|
||||
result: FirehoseRecordTransformationStatus;
|
||||
/** Encode in Base64 */
|
||||
data: string;
|
||||
}
|
||||
|
||||
export interface FirehoseTransformationResult {
|
||||
records: FirehoseTransformationResultRecord[];
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
export type KinesisStreamHandler = Handler<KinesisStreamEvent, void>;
|
||||
|
||||
// Kinesis Streams
|
||||
// https://docs.aws.amazon.com/lambda/latest/dg/eventsources.html#eventsources-kinesis-streams
|
||||
export interface KinesisStreamRecordPayload {
|
||||
approximateArrivalTimestamp: number;
|
||||
data: string;
|
||||
kinesisSchemaVersion: string;
|
||||
partitionKey: string;
|
||||
sequenceNumber: string;
|
||||
}
|
||||
|
||||
export interface KinesisStreamRecord {
|
||||
awsRegion: string;
|
||||
eventID: string;
|
||||
eventName: string;
|
||||
eventSource: string;
|
||||
eventSourceARN: string;
|
||||
eventVersion: string;
|
||||
invokeIdentityArn: string;
|
||||
kinesis: KinesisStreamRecordPayload;
|
||||
}
|
||||
|
||||
export interface KinesisStreamEvent {
|
||||
Records: KinesisStreamRecord[];
|
||||
}
|
||||
Vendored
+103
@@ -0,0 +1,103 @@
|
||||
import { Callback, Handler } from "../hander";
|
||||
|
||||
export type LexHandler = Handler<LexEvent, LexResult>;
|
||||
export type LexCallback = Callback<LexResult>;
|
||||
|
||||
// Lex
|
||||
// https://docs.aws.amazon.com/lambda/latest/dg/invoking-lambda-function.html#supported-event-source-lex
|
||||
export interface LexEvent {
|
||||
currentIntent: {
|
||||
name: string;
|
||||
slots: { [name: string]: string | null };
|
||||
slotDetails: LexSlotDetails;
|
||||
confirmationStatus: 'None' | 'Confirmed' | 'Denied';
|
||||
};
|
||||
bot: {
|
||||
name: string;
|
||||
alias: string;
|
||||
version: string;
|
||||
};
|
||||
userId: string;
|
||||
inputTranscript: string;
|
||||
invocationSource: 'DialogCodeHook' | 'FulfillmentCodeHook';
|
||||
outputDialogMode: 'Text' | 'Voice';
|
||||
messageVersion: '1.0';
|
||||
sessionAttributes: { [key: string]: string };
|
||||
requestAttributes: { [key: string]: string } | null;
|
||||
}
|
||||
|
||||
export interface LexSlotResolution {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface LexSlotDetails {
|
||||
[name: string]: {
|
||||
// The following line only works in TypeScript Version: 3.0, The array should have at least 1 and no more than 5 items
|
||||
// resolutions: [LexSlotResolution, LexSlotResolution?, LexSlotResolution?, LexSlotResolution?, LexSlotResolution?];
|
||||
resolutions: LexSlotResolution[];
|
||||
originalValue: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface LexGenericAttachment {
|
||||
title: string;
|
||||
subTitle: string;
|
||||
imageUrl: string;
|
||||
attachmentLinkUrl: string;
|
||||
buttons: Array<{
|
||||
text: string;
|
||||
value: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface LexDialogActionBase {
|
||||
type: 'Close' | 'ElicitIntent' | 'ElicitSlot' | 'ConfirmIntent';
|
||||
message?: {
|
||||
contentType: 'PlainText' | 'SSML' | 'CustomPayload';
|
||||
content: string;
|
||||
};
|
||||
responseCard?: {
|
||||
version: number;
|
||||
contentType: 'application/vnd.amazonaws.card.generic';
|
||||
genericAttachments: LexGenericAttachment[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface LexDialogActionClose extends LexDialogActionBase {
|
||||
type: 'Close';
|
||||
fulfillmentState: 'Fulfilled' | 'Failed';
|
||||
}
|
||||
|
||||
export interface LexDialogActionElicitIntent extends LexDialogActionBase {
|
||||
type: 'ElicitIntent';
|
||||
}
|
||||
|
||||
export interface LexDialogActionElicitSlot extends LexDialogActionBase {
|
||||
type: 'ElicitSlot';
|
||||
intentName: string;
|
||||
slots: { [name: string]: string | null };
|
||||
slotToElicit: string;
|
||||
}
|
||||
|
||||
export interface LexDialogActionConfirmIntent extends LexDialogActionBase {
|
||||
type: 'ConfirmIntent';
|
||||
intentName: string;
|
||||
slots: { [name: string]: string | null };
|
||||
}
|
||||
|
||||
export interface LexDialogActionDelegate {
|
||||
type: 'Delegate';
|
||||
slots: { [name: string]: string | null };
|
||||
}
|
||||
|
||||
export type LexDialogAction =
|
||||
| LexDialogActionClose
|
||||
| LexDialogActionElicitIntent
|
||||
| LexDialogActionElicitSlot
|
||||
| LexDialogActionConfirmIntent
|
||||
| LexDialogActionDelegate;
|
||||
|
||||
export interface LexResult {
|
||||
sessionAttributes?: { [key: string]: string };
|
||||
dialogAction: LexDialogAction;
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
import { Handler, Callback } from "../hander";
|
||||
|
||||
/**
|
||||
* S3 Batch Operations event
|
||||
* https://docs.aws.amazon.com/AmazonS3/latest/dev/batch-ops-invoke-lambda.html
|
||||
*/
|
||||
export type S3BatchHandler = Handler<S3BatchEvent, S3BatchResult>;
|
||||
export type S3BatchCallback = Callback<S3BatchResult>;
|
||||
|
||||
export interface S3BatchEvent {
|
||||
invocationSchemaVersion: string;
|
||||
invocationId: string;
|
||||
job: S3BatchEventJob;
|
||||
tasks: S3BatchEventTask[];
|
||||
}
|
||||
|
||||
export interface S3BatchEventJob {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface S3BatchEventTask {
|
||||
taskId: string;
|
||||
s3Key: string;
|
||||
s3VersionId: string | null;
|
||||
s3BucketArn: string;
|
||||
}
|
||||
|
||||
export interface S3BatchResult {
|
||||
invocationSchemaVersion: string;
|
||||
treatMissingKeysAs: S3BatchResultResultCode;
|
||||
invocationId: string;
|
||||
results: S3BatchResultResult[];
|
||||
}
|
||||
|
||||
export type S3BatchResultResultCode = 'Succeeded' | 'TemporaryFailure' | 'PermanentFailure';
|
||||
|
||||
export interface S3BatchResultResult {
|
||||
taskId: string;
|
||||
resultCode: S3BatchResultResultCode;
|
||||
resultString: string;
|
||||
}
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
export type S3Handler = Handler<S3Event, void>;
|
||||
|
||||
/**
|
||||
* S3Create event
|
||||
* https://docs.aws.amazon.com/AmazonS3/latest/dev/notification-content-structure.html
|
||||
*/
|
||||
|
||||
export interface S3EventRecordGlacierRestoreEventData {
|
||||
lifecycleRestorationExpiryTime: string;
|
||||
lifecycleRestoreStorageClass: string;
|
||||
}
|
||||
|
||||
export interface S3EventRecordGlacierEventData {
|
||||
restoreEventData: S3EventRecordGlacierRestoreEventData;
|
||||
}
|
||||
|
||||
export interface S3EventRecord {
|
||||
eventVersion: string;
|
||||
eventSource: string;
|
||||
awsRegion: string;
|
||||
eventTime: string;
|
||||
eventName: string;
|
||||
userIdentity: {
|
||||
principalId: string;
|
||||
};
|
||||
requestParameters: {
|
||||
sourceIPAddress: string;
|
||||
};
|
||||
responseElements: {
|
||||
'x-amz-request-id': string;
|
||||
'x-amz-id-2': string;
|
||||
};
|
||||
s3: {
|
||||
s3SchemaVersion: string;
|
||||
configurationId: string;
|
||||
bucket: {
|
||||
name: string;
|
||||
ownerIdentity: {
|
||||
principalId: string;
|
||||
};
|
||||
arn: string;
|
||||
};
|
||||
object: {
|
||||
key: string;
|
||||
size: number;
|
||||
eTag: string;
|
||||
versionId?: string;
|
||||
sequencer: string;
|
||||
};
|
||||
};
|
||||
glacierEventData?: S3EventRecordGlacierEventData;
|
||||
}
|
||||
|
||||
export interface S3Event {
|
||||
Records: S3EventRecord[];
|
||||
}
|
||||
|
||||
export type S3CreateEvent = S3Event; // old name
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
export type SNSHandler = Handler<SNSEvent, void>;
|
||||
|
||||
// SNS "event"
|
||||
export interface SNSMessageAttribute {
|
||||
Type: string;
|
||||
Value: string;
|
||||
}
|
||||
|
||||
export interface SNSMessageAttributes {
|
||||
[name: string]: SNSMessageAttribute;
|
||||
}
|
||||
|
||||
export interface SNSMessage {
|
||||
SignatureVersion: string;
|
||||
Timestamp: string;
|
||||
Signature: string;
|
||||
SigningCertUrl: string;
|
||||
MessageId: string;
|
||||
Message: string;
|
||||
MessageAttributes: SNSMessageAttributes;
|
||||
Type: string;
|
||||
UnsubscribeUrl: string;
|
||||
TopicArn: string;
|
||||
Subject: string;
|
||||
}
|
||||
|
||||
export interface SNSEventRecord {
|
||||
EventVersion: string;
|
||||
EventSubscriptionArn: string;
|
||||
EventSource: string;
|
||||
Sns: SNSMessage;
|
||||
}
|
||||
|
||||
export interface SNSEvent {
|
||||
Records: SNSEventRecord[];
|
||||
}
|
||||
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
import { Handler } from "../hander";
|
||||
|
||||
export type SQSHandler = Handler<SQSEvent, void>;
|
||||
|
||||
// SQS
|
||||
// https://docs.aws.amazon.com/lambda/latest/dg/invoking-lambda-function.html#supported-event-source-sqs
|
||||
export interface SQSRecord {
|
||||
messageId: string;
|
||||
receiptHandle: string;
|
||||
body: string;
|
||||
attributes: SQSRecordAttributes;
|
||||
messageAttributes: SQSMessageAttributes;
|
||||
md5OfBody: string;
|
||||
eventSource: string;
|
||||
eventSourceARN: string;
|
||||
awsRegion: string;
|
||||
}
|
||||
|
||||
export interface SQSEvent {
|
||||
Records: SQSRecord[];
|
||||
}
|
||||
|
||||
export interface SQSRecordAttributes {
|
||||
ApproximateReceiveCount: string;
|
||||
SentTimestamp: string;
|
||||
SenderId: string;
|
||||
ApproximateFirstReceiveTimestamp: string;
|
||||
}
|
||||
|
||||
export type SQSMessageAttributeDataType = 'String' | 'Number' | 'Binary' | string;
|
||||
|
||||
export interface SQSMessageAttribute {
|
||||
stringValue?: string;
|
||||
binaryValue?: string;
|
||||
stringListValues: never[]; // Not implemented. Reserved for future use.
|
||||
binaryListValues: never[]; // Not implemented. Reserved for future use.
|
||||
dataType: SQSMessageAttributeDataType;
|
||||
}
|
||||
|
||||
export interface SQSMessageAttributes {
|
||||
[name: string]: SQSMessageAttribute;
|
||||
}
|
||||
@@ -18,6 +18,19 @@
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"aws-lambda-tests.ts"
|
||||
"aws-lambda-tests.ts",
|
||||
"test/alb-tests.ts",
|
||||
"test/api-gateway-tests.ts",
|
||||
"test/cloudformation-tests.ts",
|
||||
"test/cloudfront-tests.ts",
|
||||
"test/cloudwatch-tests.ts",
|
||||
"test/codepipeline-tests.ts",
|
||||
"test/cognito-tests.ts",
|
||||
"test/dynamodb-tests.ts",
|
||||
"test/kinesis-tests.ts",
|
||||
"test/lex-tests.ts",
|
||||
"test/s3-tests.ts",
|
||||
"test/sns-tests.ts",
|
||||
"test/sqs-tests.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json",
|
||||
"rules": {
|
||||
// TODO
|
||||
"npm-naming": false,
|
||||
"dt-header": false
|
||||
// This is needed because there's an unrelated aws-lambda package on NPM,
|
||||
// and DTS is complaining that we're referring to a non-existing version.
|
||||
"npm-naming": false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user