@slates-integrations/aws-lambda 0.2.0-rc.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -0
- package/docs/SPEC.md +91 -0
- package/logo.svg +1 -0
- package/package.json +21 -0
- package/slate.json +23 -0
- package/src/auth.ts +51 -0
- package/src/config.ts +8 -0
- package/src/index.ts +50 -0
- package/src/lib/aws-signer.ts +158 -0
- package/src/lib/client.ts +919 -0
- package/src/lib/errors.ts +101 -0
- package/src/lib/helpers.ts +15 -0
- package/src/spec.ts +13 -0
- package/src/tools/configure-async-invocation.ts +134 -0
- package/src/tools/create-function.ts +127 -0
- package/src/tools/delete-function.ts +41 -0
- package/src/tools/get-account-settings.ts +45 -0
- package/src/tools/get-function.ts +104 -0
- package/src/tools/index.ts +19 -0
- package/src/tools/invoke-function.ts +94 -0
- package/src/tools/list-functions.ts +88 -0
- package/src/tools/manage-alias.ts +159 -0
- package/src/tools/manage-concurrency.ts +141 -0
- package/src/tools/manage-durable-execution.ts +209 -0
- package/src/tools/manage-event-source-mapping.ts +193 -0
- package/src/tools/manage-function-url.ts +132 -0
- package/src/tools/manage-layer.ts +186 -0
- package/src/tools/manage-permission.ts +94 -0
- package/src/tools/manage-recursion-config.ts +63 -0
- package/src/tools/manage-runtime-management.ts +85 -0
- package/src/tools/manage-tags.ts +72 -0
- package/src/tools/publish-version.ts +83 -0
- package/src/tools/update-function.ts +156 -0
- package/src/triggers/function-changes.ts +113 -0
- package/src/triggers/inbound-webhook.ts +67 -0
- package/src/triggers/index.ts +2 -0
- package/tsconfig.json +23 -0
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# <img src="https://provider-logos.metorial-cdn.com/amazon.svg" height="20"> Aws Lambda
|
|
2
|
+
|
|
3
|
+
Create, update, configure, and delete serverless Lambda functions. Invoke functions synchronously or asynchronously. Manage function code deployment via ZIP archives or container images. Publish immutable function versions and create aliases with weighted traffic shifting for canary and blue/green deployments. Create and manage layers for shared code, dependencies, and runtimes. Configure event source mappings to poll events from SQS, Kinesis, DynamoDB Streams, Kafka, and Amazon MQ. Set up function URLs as dedicated HTTPS endpoints. Manage concurrency settings including reserved and provisioned concurrency. Configure asynchronous invocation retry behavior and destination routing. Manage resource-based permissions policies, tags, runtime update mode, recursive loop detection, and durable execution workflows.
|
|
4
|
+
|
|
5
|
+
## Tools
|
|
6
|
+
|
|
7
|
+
### Configure Async Invocation
|
|
8
|
+
|
|
9
|
+
List, get, set, update, or remove the asynchronous invocation configuration for a Lambda function. Controls retry behavior, maximum event age, and destination routing for successful or failed invocations (to SQS, SNS, Lambda, S3, or EventBridge).
|
|
10
|
+
|
|
11
|
+
### Create Function
|
|
12
|
+
|
|
13
|
+
Create a new Lambda function. Provide the function code via an S3 location, container image URI, or base64-encoded ZIP file. Requires a function name and an IAM execution role ARN at minimum.
|
|
14
|
+
|
|
15
|
+
### Delete Function
|
|
16
|
+
|
|
17
|
+
Delete a Lambda function. Optionally specify a **qualifier** to delete only a specific version (not \
|
|
18
|
+
|
|
19
|
+
### Get Account Settings
|
|
20
|
+
|
|
21
|
+
Retrieve Lambda account-level settings and limits for the configured region, including concurrent execution limits, code storage usage, and total code size.
|
|
22
|
+
|
|
23
|
+
### Get Function
|
|
24
|
+
|
|
25
|
+
Retrieve detailed information about a Lambda function including its configuration, code location, concurrency settings, and tags. Supports fetching a specific version or alias using the **qualifier** parameter.
|
|
26
|
+
|
|
27
|
+
### Invoke Function
|
|
28
|
+
|
|
29
|
+
Invoke a Lambda function synchronously or asynchronously. **Synchronous** (RequestResponse) returns the function's output. **Asynchronous** (Event) queues the event and returns immediately. Use **DryRun** to validate permissions without executing.
|
|
30
|
+
|
|
31
|
+
### List Functions
|
|
32
|
+
|
|
33
|
+
List Lambda functions in the configured AWS region. Returns function names, ARNs, runtimes, and key configuration. Use **maxItems** to control page size and **marker** for pagination.
|
|
34
|
+
|
|
35
|
+
### Manage Alias
|
|
36
|
+
|
|
37
|
+
Create, update, get, delete, or list aliases for a Lambda function. Aliases are named pointers to function versions, enabling canary and blue/green deployments via weighted traffic shifting.
|
|
38
|
+
|
|
39
|
+
### Manage Concurrency
|
|
40
|
+
|
|
41
|
+
Configure reserved and provisioned concurrency for a Lambda function. **Reserved concurrency** guarantees a set amount of concurrent executions. **Provisioned concurrency** keeps execution environments warm to eliminate cold starts.
|
|
42
|
+
|
|
43
|
+
### Manage Durable Execution
|
|
44
|
+
|
|
45
|
+
Inspect, list, stop, or send callbacks for Lambda durable executions. Durable executions are long-running, stateful workflows that can be checkpointed and resumed. Supports viewing execution history, state, and sending callback signals for human-in-the-loop patterns.
|
|
46
|
+
|
|
47
|
+
### Manage Event Source Mapping
|
|
48
|
+
|
|
49
|
+
Create, update, get, delete, or list event source mappings that connect Lambda to streaming/queue services (SQS, Kinesis, DynamoDB Streams, Kafka, Amazon MQ). Lambda automatically polls the source and invokes the function.
|
|
50
|
+
|
|
51
|
+
### Manage Function URL
|
|
52
|
+
|
|
53
|
+
Create, update, get, or delete a dedicated HTTPS endpoint (function URL) for a Lambda function. Function URLs provide public API access without needing API Gateway. Supports IAM authentication or open access, and configurable CORS.
|
|
54
|
+
|
|
55
|
+
### Manage Layer
|
|
56
|
+
|
|
57
|
+
Publish, get, delete, or list Lambda layers and their versions. Layers are reusable packages of libraries, dependencies, or custom runtimes that can be attached to functions.
|
|
58
|
+
|
|
59
|
+
### Manage Permission
|
|
60
|
+
|
|
61
|
+
Add, remove, or view resource-based policy statements on a Lambda function. These policies grant other AWS accounts or services (e.g., S3, API Gateway, EventBridge) permission to invoke the function.
|
|
62
|
+
|
|
63
|
+
### Manage Recursion Config
|
|
64
|
+
|
|
65
|
+
Get or set recursive loop detection for a Lambda function. Lambda defaults to terminating detected recursive invocation loops; only use Allow for intentional recursive designs with safeguards.
|
|
66
|
+
|
|
67
|
+
### Manage Runtime Management
|
|
68
|
+
|
|
69
|
+
Get or set the runtime update mode for a Lambda function version. Runtime management controls whether Lambda applies runtime patches automatically, on function updates, or pins a manual runtime version ARN.
|
|
70
|
+
|
|
71
|
+
### Manage Tags
|
|
72
|
+
|
|
73
|
+
List, add, or remove tags on a Lambda function. Tags are key-value pairs used for organization, cost allocation, and access control. Provide the full function ARN for tag operations.
|
|
74
|
+
|
|
75
|
+
### Publish Version
|
|
76
|
+
|
|
77
|
+
Publish an immutable version from the current \
|
|
78
|
+
|
|
79
|
+
### Update Function
|
|
80
|
+
|
|
81
|
+
Update a Lambda function's code and/or configuration. Provide **code** fields to update the deployment package, or **configuration** fields to modify settings like runtime, handler, memory, timeout, environment variables, layers, and VPC. Both can be updated in a single call.
|
|
82
|
+
|
|
83
|
+
## License
|
|
84
|
+
|
|
85
|
+
This integration is licensed under the [FSL-1.1](https://github.com/metorial/metorial-platform/blob/dev/LICENSE).
|
|
86
|
+
|
|
87
|
+
<div align="center">
|
|
88
|
+
<sub>Built with ❤️ by <a href="https://metorial.com">Metorial</a></sub>
|
|
89
|
+
</div>
|
package/docs/SPEC.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Slates Specification for AWS Lambda
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
AWS Lambda is a serverless compute service from Amazon Web Services that runs code in response to events without requiring server provisioning or management. It automatically scales execution and uses pay-per-use pricing. The Lambda API allows managing functions, layers, event source mappings, aliases, versions, concurrency settings, and invoking functions programmatically.
|
|
6
|
+
|
|
7
|
+
## Authentication
|
|
8
|
+
|
|
9
|
+
AWS Lambda uses **IAM-based authentication** exclusively. All API requests must be authenticated using AWS credentials.
|
|
10
|
+
|
|
11
|
+
**AWS Signature Version 4 (SigV4)**
|
|
12
|
+
|
|
13
|
+
AWS Signature Version 4 (SigV4) is the AWS signing protocol for adding authentication information to AWS API requests. Every request to the Lambda API must be signed using this protocol.
|
|
14
|
+
|
|
15
|
+
Required credentials:
|
|
16
|
+
|
|
17
|
+
- **AWS Access Key ID**: Identifies the IAM user or role making the request.
|
|
18
|
+
- **AWS Secret Access Key**: Used to compute the request signature.
|
|
19
|
+
- **AWS Session Token** (optional): Required when using temporary credentials from AWS STS (Security Token Service), assumed roles, or federated identities.
|
|
20
|
+
|
|
21
|
+
Signing requests involves creating a canonical request based on the request details, calculating a signature using your AWS credentials, and adding this signature to the request as an Authorization header.
|
|
22
|
+
|
|
23
|
+
Credentials can be obtained in several ways:
|
|
24
|
+
|
|
25
|
+
- **IAM User**: Long-term access key ID and secret access key created in the IAM console.
|
|
26
|
+
- **IAM Role (assumed via STS)**: Temporary credentials obtained via `sts:AssumeRole`, commonly used for cross-account access or applications running on AWS infrastructure (EC2, ECS, Lambda).
|
|
27
|
+
- **Federated Identity**: A federated identity is a user from your enterprise directory, web identity provider, or Directory Service that accesses AWS services using credentials from an identity source. Federated identities assume roles that provide temporary credentials.
|
|
28
|
+
|
|
29
|
+
The API endpoint follows the pattern: `https://lambda.{region}.amazonaws.com`. The region must also be specified as part of the signing process.
|
|
30
|
+
|
|
31
|
+
**Permissions**: Access to specific Lambda actions is controlled via IAM policies. You control access by creating policies and attaching them to AWS identities or resources. A policy defines permissions when associated with an identity or resource. Lambda actions are prefixed with `lambda:` (e.g., `lambda:InvokeFunction`, `lambda:CreateFunction`).
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
### Function Management
|
|
36
|
+
|
|
37
|
+
Create, update, configure, and delete Lambda functions. You can upload function code as a ZIP archive or a container image, set runtime and handler configurations, assign execution roles, configure environment variables, memory, timeout, and VPC networking. Environment variables modify application behavior without new code deployments. Versions safely test new features while maintaining stable production environments.
|
|
38
|
+
|
|
39
|
+
### Function Invocation
|
|
40
|
+
|
|
41
|
+
Invoke Lambda functions synchronously (RequestResponse) or asynchronously (Event). Synchronous invocation returns the function result in the response. Asynchronous invocation queues the event and returns immediately.
|
|
42
|
+
|
|
43
|
+
### Versions and Aliases
|
|
44
|
+
|
|
45
|
+
Publish immutable versions of functions and create aliases that point to specific versions. Aliases support weighted traffic shifting between two versions, enabling canary or blue/green deployment patterns.
|
|
46
|
+
|
|
47
|
+
### Layers
|
|
48
|
+
|
|
49
|
+
A Lambda layer is a .zip file archive that contains supplementary code or data. Layers usually contain library dependencies, a custom runtime, or configuration files. You can publish, version, and share layers across functions and AWS accounts. You can include up to five layers per function.
|
|
50
|
+
|
|
51
|
+
### Event Source Mappings
|
|
52
|
+
|
|
53
|
+
Connect Lambda functions to streaming or queue-based AWS services so Lambda automatically polls for and processes events. With event source mapping, Lambda actively fetches (or pulls) events from a queue or stream. You configure Lambda to check for events from a supported service, and Lambda handles the polling and invocation of your function. Supported sources include SQS, Kinesis, DynamoDB Streams, Apache Kafka, and Amazon MQ.
|
|
54
|
+
|
|
55
|
+
### Function URLs
|
|
56
|
+
|
|
57
|
+
Function URLs create public-facing APIs and endpoints without additional services. Each function URL provides a dedicated HTTPS endpoint. Auth type can be set to `AWS_IAM` (SigV4-signed requests) or `NONE` (open access). CORS can be configured on the URL.
|
|
58
|
+
|
|
59
|
+
### Concurrency and Scaling
|
|
60
|
+
|
|
61
|
+
Configure reserved concurrency to guarantee a function always has access to a set amount of concurrency. Provisioned concurrency keeps a specified number of execution environments initialized to reduce cold starts. Scaling configuration allows controlling how quickly functions scale up.
|
|
62
|
+
|
|
63
|
+
### Asynchronous Invocation Configuration
|
|
64
|
+
|
|
65
|
+
Configure how Lambda handles asynchronous invocations, including maximum retry attempts, maximum event age, and destination routing for successful or failed invocations (to SQS, SNS, Lambda, S3, or EventBridge).
|
|
66
|
+
|
|
67
|
+
### Runtime Management
|
|
68
|
+
|
|
69
|
+
Control whether Lambda applies runtime patches automatically, only when the function is updated, or through a pinned manual runtime version ARN.
|
|
70
|
+
|
|
71
|
+
### Recursive Loop Detection
|
|
72
|
+
|
|
73
|
+
Read and configure Lambda's recursive loop detection behavior. The default `Terminate` mode stops detected recursive invocation loops; `Allow` should be reserved for intentional recursive designs with guardrails.
|
|
74
|
+
|
|
75
|
+
### Permissions Management
|
|
76
|
+
|
|
77
|
+
Manage resource-based policies on functions and layers. Add or remove permission statements that grant other AWS accounts or services the ability to invoke functions or use layers.
|
|
78
|
+
|
|
79
|
+
### Tagging
|
|
80
|
+
|
|
81
|
+
Apply key-value tags to Lambda functions for organization, cost tracking, and access control purposes.
|
|
82
|
+
|
|
83
|
+
### Durable Executions
|
|
84
|
+
|
|
85
|
+
Manage long-running, stateful workflows via durable functions. You can checkpoint, inspect history and state, stop executions, and send callback signals for human-in-the-loop or asynchronous task patterns.
|
|
86
|
+
|
|
87
|
+
## Events
|
|
88
|
+
|
|
89
|
+
The provider does not support webhooks or event subscriptions via the Lambda API itself. Lambda functions are _consumers_ of events from other AWS services (S3, API Gateway, EventBridge, etc.), but the Lambda management API does not provide a webhook or subscription mechanism to notify external systems about changes to Lambda resources.
|
|
90
|
+
|
|
91
|
+
To monitor changes to Lambda resources (e.g., function creation, updates, deletions), you would use **AWS CloudTrail** combined with **Amazon EventBridge**, which can capture Lambda API calls as events and route them to targets. However, this is not a built-in feature of the Lambda API itself.
|
package/logo.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="62" height="62" fill="none"><rect width="62" height="62" rx="31" fill="#fff"/><use xlink:href="#B" fill="#f90"/><use xlink:href="#C" fill-rule="evenodd" fill="#000"/><use xlink:href="#B" fill="#f90"/><use xlink:href="#C" fill-rule="evenodd" fill="#000"/><defs ><path id="B" d="M47.451 45.221c-18.161 8.643-29.431 1.412-36.646-2.98-.447-.277-1.205.065-.547.821C12.661 45.975 20.538 53 30.82 53c10.289 0 16.41-5.614 17.176-6.593.761-.971.223-1.507-.545-1.186h0zm5.1-2.817c-.488-.635-2.965-.753-4.525-.562-1.562.186-3.906 1.14-3.702 1.714.105.215.318.118 1.391.022 1.076-.107 4.09-.488 4.718.333.631.827-.961 4.764-1.252 5.4-.281.635.107.799.635.376.52-.423 1.463-1.518 2.095-3.067.628-1.558 1.011-3.731.64-4.215z"/><path id="C" d="M35.24 27.585c0 2.268.057 4.159-1.089 6.173-.925 1.638-2.391 2.645-4.028 2.645-2.235 0-3.537-1.703-3.537-4.216 0-4.961 4.446-5.862 8.654-5.862v1.261zm5.87 14.188c-.385.344-.942.368-1.375.139-1.932-1.605-2.276-2.349-3.34-3.881-3.193 3.259-5.453 4.233-9.595 4.233-4.896 0-8.711-3.021-8.711-9.071 0-4.724 2.563-7.941 6.206-9.513 3.16-1.392 7.573-1.638 10.946-2.022v-.753c0-1.384.106-3.021-.704-4.216-.712-1.073-2.071-1.515-3.267-1.515-2.219 0-4.2 1.138-4.683 3.496-.098.524-.483 1.04-1.007 1.064l-5.649-.606c-.475-.107-.999-.491-.868-1.22C20.364 11.063 26.545 9 32.079 9c2.833 0 6.533.753 8.769 2.898 2.833 2.644 2.563 6.173 2.563 10.013v9.071c0 2.726 1.13 3.922 2.194 5.395.377.524.459 1.154-.016 1.547-1.187.991-3.299 2.833-4.462 3.864l-.016-.016"/></defs></svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@slates-integrations/aws-lambda",
|
|
3
|
+
"main": "src/index.ts",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
|
|
7
|
+
"typecheck": "tsc --noEmit"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@aws-sdk/client-lambda": "^3.1043.0",
|
|
11
|
+
"@lowerdeck/error": "^1.1.0",
|
|
12
|
+
"@slates/aws-sdk-http-handler": "1.0.0-rc.1",
|
|
13
|
+
"@types/node": "^20",
|
|
14
|
+
"slates": "1.0.0-rc.10",
|
|
15
|
+
"zod": "^4.2"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"typescript": "^5"
|
|
19
|
+
},
|
|
20
|
+
"version": "0.2.0-rc.6"
|
|
21
|
+
}
|
package/slate.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@amazon/aws-lambda",
|
|
3
|
+
"description": "Create, update, configure, and delete serverless Lambda functions. Invoke functions synchronously or asynchronously. Manage function code deployment via ZIP archives or container images. Publish immutable function versions and create aliases with weighted traffic shifting for canary and blue/green deployments. Create and manage layers for shared code, dependencies, and runtimes. Configure event source mappings to poll events from SQS, Kinesis, DynamoDB Streams, Kafka, and Amazon MQ. Set up function URLs as dedicated HTTPS endpoints. Manage concurrency settings including reserved and provisioned concurrency. Configure asynchronous invocation retry behavior and destination routing. Manage resource-based permissions policies, tags, runtime update mode, recursive loop detection, and durable execution workflows.",
|
|
4
|
+
"categories": [
|
|
5
|
+
"apis-and-http-requests",
|
|
6
|
+
"code-execution"
|
|
7
|
+
],
|
|
8
|
+
"skills": [
|
|
9
|
+
"create and manage functions",
|
|
10
|
+
"invoke functions",
|
|
11
|
+
"publish versions and aliases",
|
|
12
|
+
"manage layers",
|
|
13
|
+
"configure event source mappings",
|
|
14
|
+
"create function URLs",
|
|
15
|
+
"manage concurrency settings",
|
|
16
|
+
"configure async invocation",
|
|
17
|
+
"manage permissions policies",
|
|
18
|
+
"manage durable executions",
|
|
19
|
+
"manage runtime updates",
|
|
20
|
+
"manage recursive loop detection"
|
|
21
|
+
],
|
|
22
|
+
"logoUrl": "https://provider-logos.metorial-cdn.com/amazon.svg"
|
|
23
|
+
}
|
package/src/auth.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { SlateAuth } from 'slates';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
export let auth = SlateAuth.create()
|
|
5
|
+
.output(
|
|
6
|
+
z.object({
|
|
7
|
+
accessKeyId: z.string(),
|
|
8
|
+
secretAccessKey: z.string(),
|
|
9
|
+
sessionToken: z.string().optional()
|
|
10
|
+
})
|
|
11
|
+
)
|
|
12
|
+
.addCustomAuth({
|
|
13
|
+
type: 'auth.custom',
|
|
14
|
+
name: 'AWS IAM Access Keys',
|
|
15
|
+
key: 'aws_iam_credentials',
|
|
16
|
+
|
|
17
|
+
inputSchema: z.object({
|
|
18
|
+
accessKeyId: z.string().describe('AWS Access Key ID'),
|
|
19
|
+
secretAccessKey: z.string().describe('AWS Secret Access Key')
|
|
20
|
+
}),
|
|
21
|
+
|
|
22
|
+
getOutput: async ctx => {
|
|
23
|
+
return {
|
|
24
|
+
output: {
|
|
25
|
+
accessKeyId: ctx.input.accessKeyId,
|
|
26
|
+
secretAccessKey: ctx.input.secretAccessKey
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
.addCustomAuth({
|
|
32
|
+
type: 'auth.custom',
|
|
33
|
+
name: 'AWS Temporary Credentials (STS)',
|
|
34
|
+
key: 'aws_temporary_credentials',
|
|
35
|
+
|
|
36
|
+
inputSchema: z.object({
|
|
37
|
+
accessKeyId: z.string().describe('Temporary AWS Access Key ID'),
|
|
38
|
+
secretAccessKey: z.string().describe('Temporary AWS Secret Access Key'),
|
|
39
|
+
sessionToken: z.string().describe('AWS Session Token')
|
|
40
|
+
}),
|
|
41
|
+
|
|
42
|
+
getOutput: async ctx => {
|
|
43
|
+
return {
|
|
44
|
+
output: {
|
|
45
|
+
accessKeyId: ctx.input.accessKeyId,
|
|
46
|
+
secretAccessKey: ctx.input.secretAccessKey,
|
|
47
|
+
sessionToken: ctx.input.sessionToken
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
});
|
package/src/config.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Slate } from 'slates';
|
|
2
|
+
import { spec } from './spec';
|
|
3
|
+
import {
|
|
4
|
+
listFunctions,
|
|
5
|
+
getFunction,
|
|
6
|
+
createFunction,
|
|
7
|
+
updateFunction,
|
|
8
|
+
deleteFunction,
|
|
9
|
+
invokeFunction,
|
|
10
|
+
publishVersion,
|
|
11
|
+
manageAlias,
|
|
12
|
+
manageLayer,
|
|
13
|
+
manageEventSourceMapping,
|
|
14
|
+
manageFunctionUrl,
|
|
15
|
+
manageConcurrency,
|
|
16
|
+
managePermission,
|
|
17
|
+
manageTags,
|
|
18
|
+
configureAsyncInvocation,
|
|
19
|
+
manageDurableExecution,
|
|
20
|
+
getAccountSettings,
|
|
21
|
+
manageRuntimeManagement,
|
|
22
|
+
manageRecursionConfig
|
|
23
|
+
} from './tools/index';
|
|
24
|
+
import { functionChanges, inboundWebhook } from './triggers/index';
|
|
25
|
+
|
|
26
|
+
export let provider = Slate.create({
|
|
27
|
+
spec,
|
|
28
|
+
tools: [
|
|
29
|
+
listFunctions,
|
|
30
|
+
getFunction,
|
|
31
|
+
createFunction,
|
|
32
|
+
updateFunction,
|
|
33
|
+
deleteFunction,
|
|
34
|
+
invokeFunction,
|
|
35
|
+
publishVersion,
|
|
36
|
+
manageAlias,
|
|
37
|
+
manageLayer,
|
|
38
|
+
manageEventSourceMapping,
|
|
39
|
+
manageFunctionUrl,
|
|
40
|
+
manageConcurrency,
|
|
41
|
+
managePermission,
|
|
42
|
+
manageTags,
|
|
43
|
+
configureAsyncInvocation,
|
|
44
|
+
manageDurableExecution,
|
|
45
|
+
getAccountSettings,
|
|
46
|
+
manageRuntimeManagement,
|
|
47
|
+
manageRecursionConfig
|
|
48
|
+
],
|
|
49
|
+
triggers: [inboundWebhook, functionChanges]
|
|
50
|
+
});
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
|
|
3
|
+
export interface AwsCredentials {
|
|
4
|
+
accessKeyId: string;
|
|
5
|
+
secretAccessKey: string;
|
|
6
|
+
sessionToken?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface SignRequestParams {
|
|
10
|
+
method: string;
|
|
11
|
+
url: string;
|
|
12
|
+
headers: Record<string, string>;
|
|
13
|
+
body?: string;
|
|
14
|
+
region: string;
|
|
15
|
+
service: string;
|
|
16
|
+
credentials: AwsCredentials;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let hmacSha256 = (key: string | ArrayBuffer, data: string): ArrayBuffer => {
|
|
20
|
+
let keyBuffer: ArrayBuffer;
|
|
21
|
+
if (typeof key === 'string') {
|
|
22
|
+
keyBuffer = new TextEncoder().encode(key).buffer as ArrayBuffer;
|
|
23
|
+
} else {
|
|
24
|
+
keyBuffer = key;
|
|
25
|
+
}
|
|
26
|
+
let hmac = crypto.createHmac('sha256', new Uint8Array(keyBuffer));
|
|
27
|
+
hmac.update(data);
|
|
28
|
+
let digest = hmac.digest();
|
|
29
|
+
return digest.buffer.slice(
|
|
30
|
+
digest.byteOffset,
|
|
31
|
+
digest.byteOffset + digest.byteLength
|
|
32
|
+
) as ArrayBuffer;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
let sha256Hex = (data: string): string => {
|
|
36
|
+
return crypto.createHash('sha256').update(data).digest('hex');
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
let toHex = (buffer: ArrayBuffer): string => {
|
|
40
|
+
let bytes = new Uint8Array(buffer);
|
|
41
|
+
let hex = '';
|
|
42
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
43
|
+
hex += bytes[i]!.toString(16).padStart(2, '0');
|
|
44
|
+
}
|
|
45
|
+
return hex;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
let uriEncode = (str: string, encodeSlash: boolean = true): string => {
|
|
49
|
+
let encoded = '';
|
|
50
|
+
for (let i = 0; i < str.length; i++) {
|
|
51
|
+
let ch = str[i]!;
|
|
52
|
+
if (
|
|
53
|
+
(ch >= 'A' && ch <= 'Z') ||
|
|
54
|
+
(ch >= 'a' && ch <= 'z') ||
|
|
55
|
+
(ch >= '0' && ch <= '9') ||
|
|
56
|
+
ch === '-' ||
|
|
57
|
+
ch === '_' ||
|
|
58
|
+
ch === '.' ||
|
|
59
|
+
ch === '~'
|
|
60
|
+
) {
|
|
61
|
+
encoded += ch;
|
|
62
|
+
} else if (ch === '/' && !encodeSlash) {
|
|
63
|
+
encoded += ch;
|
|
64
|
+
} else {
|
|
65
|
+
let bytes = new TextEncoder().encode(ch);
|
|
66
|
+
for (let b of bytes) {
|
|
67
|
+
encoded += '%' + b.toString(16).toUpperCase().padStart(2, '0');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return encoded;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export let signRequest = (params: SignRequestParams): Record<string, string> => {
|
|
75
|
+
let { method, url, headers, body, region, service, credentials } = params;
|
|
76
|
+
|
|
77
|
+
let parsedUrl = new URL(url);
|
|
78
|
+
let now = new Date();
|
|
79
|
+
let dateStamp = now.toISOString().replace(/[-:]/g, '').slice(0, 8);
|
|
80
|
+
let amzDate = dateStamp + 'T' + now.toISOString().replace(/[-:]/g, '').slice(9, 15) + 'Z';
|
|
81
|
+
|
|
82
|
+
let signedHeaders: Record<string, string> = { ...headers };
|
|
83
|
+
signedHeaders['host'] = parsedUrl.host;
|
|
84
|
+
signedHeaders['x-amz-date'] = amzDate;
|
|
85
|
+
|
|
86
|
+
if (credentials.sessionToken) {
|
|
87
|
+
signedHeaders['x-amz-security-token'] = credentials.sessionToken;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let canonicalUri = uriEncode(decodeURIComponent(parsedUrl.pathname), false);
|
|
91
|
+
|
|
92
|
+
let queryParams: [string, string][] = [];
|
|
93
|
+
parsedUrl.searchParams.forEach((value, key) => {
|
|
94
|
+
queryParams.push([key, value]);
|
|
95
|
+
});
|
|
96
|
+
queryParams.sort((a, b) => {
|
|
97
|
+
if (a[0] < b[0]) return -1;
|
|
98
|
+
if (a[0] > b[0]) return 1;
|
|
99
|
+
return a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : 0;
|
|
100
|
+
});
|
|
101
|
+
let canonicalQueryString = queryParams
|
|
102
|
+
.map(([k, v]) => `${uriEncode(k)}=${uriEncode(v)}`)
|
|
103
|
+
.join('&');
|
|
104
|
+
|
|
105
|
+
let headerKeys = Object.keys(signedHeaders)
|
|
106
|
+
.map(k => k.toLowerCase())
|
|
107
|
+
.sort();
|
|
108
|
+
|
|
109
|
+
let canonicalHeaders = headerKeys
|
|
110
|
+
.map(k => {
|
|
111
|
+
let val =
|
|
112
|
+
signedHeaders[Object.keys(signedHeaders).find(h => h.toLowerCase() === k)!] || '';
|
|
113
|
+
return `${k}:${val.trim()}\n`;
|
|
114
|
+
})
|
|
115
|
+
.join('');
|
|
116
|
+
|
|
117
|
+
let signedHeadersList = headerKeys.join(';');
|
|
118
|
+
|
|
119
|
+
let payloadHash = sha256Hex(body || '');
|
|
120
|
+
|
|
121
|
+
let canonicalRequest = [
|
|
122
|
+
method.toUpperCase(),
|
|
123
|
+
canonicalUri,
|
|
124
|
+
canonicalQueryString,
|
|
125
|
+
canonicalHeaders,
|
|
126
|
+
signedHeadersList,
|
|
127
|
+
payloadHash
|
|
128
|
+
].join('\n');
|
|
129
|
+
|
|
130
|
+
let credentialScope = `${dateStamp}/${region}/${service}/aws4_request`;
|
|
131
|
+
|
|
132
|
+
let stringToSign = [
|
|
133
|
+
'AWS4-HMAC-SHA256',
|
|
134
|
+
amzDate,
|
|
135
|
+
credentialScope,
|
|
136
|
+
sha256Hex(canonicalRequest)
|
|
137
|
+
].join('\n');
|
|
138
|
+
|
|
139
|
+
let dateKey = hmacSha256('AWS4' + credentials.secretAccessKey, dateStamp);
|
|
140
|
+
let dateRegionKey = hmacSha256(dateKey, region);
|
|
141
|
+
let dateRegionServiceKey = hmacSha256(dateRegionKey, service);
|
|
142
|
+
let signingKey = hmacSha256(dateRegionServiceKey, 'aws4_request');
|
|
143
|
+
|
|
144
|
+
let signature = toHex(hmacSha256(signingKey, stringToSign));
|
|
145
|
+
|
|
146
|
+
let authorization = `AWS4-HMAC-SHA256 Credential=${credentials.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeadersList}, Signature=${signature}`;
|
|
147
|
+
|
|
148
|
+
let result: Record<string, string> = {
|
|
149
|
+
'x-amz-date': amzDate,
|
|
150
|
+
authorization: authorization
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
if (credentials.sessionToken) {
|
|
154
|
+
result['x-amz-security-token'] = credentials.sessionToken;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return result;
|
|
158
|
+
};
|