@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.
Files changed (37) hide show
  1. package/README.md +89 -0
  2. package/docs/SPEC.md +91 -0
  3. package/logo.svg +1 -0
  4. package/package.json +21 -0
  5. package/slate.json +23 -0
  6. package/src/auth.ts +51 -0
  7. package/src/config.ts +8 -0
  8. package/src/index.ts +50 -0
  9. package/src/lib/aws-signer.ts +158 -0
  10. package/src/lib/client.ts +919 -0
  11. package/src/lib/errors.ts +101 -0
  12. package/src/lib/helpers.ts +15 -0
  13. package/src/spec.ts +13 -0
  14. package/src/tools/configure-async-invocation.ts +134 -0
  15. package/src/tools/create-function.ts +127 -0
  16. package/src/tools/delete-function.ts +41 -0
  17. package/src/tools/get-account-settings.ts +45 -0
  18. package/src/tools/get-function.ts +104 -0
  19. package/src/tools/index.ts +19 -0
  20. package/src/tools/invoke-function.ts +94 -0
  21. package/src/tools/list-functions.ts +88 -0
  22. package/src/tools/manage-alias.ts +159 -0
  23. package/src/tools/manage-concurrency.ts +141 -0
  24. package/src/tools/manage-durable-execution.ts +209 -0
  25. package/src/tools/manage-event-source-mapping.ts +193 -0
  26. package/src/tools/manage-function-url.ts +132 -0
  27. package/src/tools/manage-layer.ts +186 -0
  28. package/src/tools/manage-permission.ts +94 -0
  29. package/src/tools/manage-recursion-config.ts +63 -0
  30. package/src/tools/manage-runtime-management.ts +85 -0
  31. package/src/tools/manage-tags.ts +72 -0
  32. package/src/tools/publish-version.ts +83 -0
  33. package/src/tools/update-function.ts +156 -0
  34. package/src/triggers/function-changes.ts +113 -0
  35. package/src/triggers/inbound-webhook.ts +67 -0
  36. package/src/triggers/index.ts +2 -0
  37. package/tsconfig.json +23 -0
@@ -0,0 +1,101 @@
1
+ import { ServiceError, badRequestError } from '@lowerdeck/error';
2
+
3
+ type ErrorResponse = {
4
+ status?: number;
5
+ statusText?: string;
6
+ data?: unknown;
7
+ };
8
+
9
+ let isRecord = (value: unknown): value is Record<string, unknown> =>
10
+ typeof value === 'object' && value !== null;
11
+
12
+ let pushString = (messages: string[], value: unknown) => {
13
+ if (typeof value === 'string' && value.trim() && !messages.includes(value.trim())) {
14
+ messages.push(value.trim());
15
+ }
16
+ };
17
+
18
+ let extractLambdaMessage = (error: unknown) => {
19
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
20
+ let data = response?.data;
21
+ let messages: string[] = [];
22
+
23
+ if (isRecord(data)) {
24
+ for (let key of [
25
+ 'message',
26
+ 'Message',
27
+ 'error',
28
+ 'Error',
29
+ 'code',
30
+ 'Code',
31
+ '__type',
32
+ 'Type'
33
+ ]) {
34
+ pushString(messages, data[key]);
35
+ }
36
+ } else {
37
+ pushString(messages, data);
38
+ }
39
+
40
+ if (messages.length > 0) {
41
+ return [...new Set(messages)].join(' - ');
42
+ }
43
+
44
+ if (error instanceof Error && error.message) {
45
+ return error.message;
46
+ }
47
+
48
+ return 'Unknown error';
49
+ };
50
+
51
+ let extractLambdaStatus = (error: unknown) => {
52
+ if (!isRecord(error)) return undefined;
53
+
54
+ let response = error.response as ErrorResponse | undefined;
55
+ let metadata = isRecord(error.$metadata) ? error.$metadata : undefined;
56
+ let status =
57
+ response?.status ?? metadata?.httpStatusCode ?? error.statusCode ?? error.status;
58
+ return typeof status === 'number' || typeof status === 'string' ? status : undefined;
59
+ };
60
+
61
+ let extractLambdaCode = (error: unknown) => {
62
+ if (!isRecord(error)) return undefined;
63
+
64
+ if (typeof error.Code === 'string') return error.Code;
65
+ if (typeof error.code === 'string' && !error.code.startsWith('upstream.')) {
66
+ return error.code;
67
+ }
68
+ if (typeof error.name === 'string' && error.name !== 'Error') return error.name;
69
+ return undefined;
70
+ };
71
+
72
+ export let lambdaServiceError = (message: string) =>
73
+ new ServiceError(badRequestError({ message }));
74
+
75
+ export let lambdaApiError = (error: unknown, operation = 'request') => {
76
+ if (error instanceof ServiceError) {
77
+ return error;
78
+ }
79
+
80
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
81
+ let status = extractLambdaStatus(error);
82
+ let code = extractLambdaCode(error);
83
+ let statusLabel =
84
+ status !== undefined
85
+ ? `HTTP ${status}${response?.statusText ? ` ${response.statusText}` : ''}: `
86
+ : '';
87
+ let codeLabel = code ? `${code} - ` : '';
88
+ let serviceError = lambdaServiceError(
89
+ `AWS Lambda API ${operation} failed: ${statusLabel}${codeLabel}${extractLambdaMessage(error)}`
90
+ );
91
+
92
+ serviceError.data.reason = 'aws_lambda_api_error';
93
+ serviceError.data.upstreamStatus = status;
94
+ serviceError.data.upstreamCode = code;
95
+
96
+ if (error instanceof Error) {
97
+ serviceError.setParent(error);
98
+ }
99
+
100
+ return serviceError;
101
+ };
@@ -0,0 +1,15 @@
1
+ import { LambdaClient } from './client';
2
+
3
+ export let createClient = (
4
+ config: { region: string },
5
+ auth: { accessKeyId: string; secretAccessKey: string; sessionToken?: string }
6
+ ): LambdaClient => {
7
+ return new LambdaClient({
8
+ region: config.region,
9
+ credentials: {
10
+ accessKeyId: auth.accessKeyId,
11
+ secretAccessKey: auth.secretAccessKey,
12
+ sessionToken: auth.sessionToken
13
+ }
14
+ });
15
+ };
package/src/spec.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { SlateSpecification } from 'slates';
2
+ import { auth } from './auth';
3
+ import { config } from './config';
4
+
5
+ export let spec = SlateSpecification.create({
6
+ key: 'aws-lambda',
7
+ name: 'AWS Lambda',
8
+ description:
9
+ 'Serverless compute service for running code in response to events without managing servers.',
10
+ metadata: {},
11
+ config,
12
+ auth
13
+ });
@@ -0,0 +1,134 @@
1
+ import { SlateTool } from 'slates';
2
+ import { createClient } from '../lib/helpers';
3
+ import { spec } from '../spec';
4
+ import { z } from 'zod';
5
+
6
+ export let configureAsyncInvocation = SlateTool.create(spec, {
7
+ name: 'Configure Async Invocation',
8
+ key: 'configure_async_invocation',
9
+ description: `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
+ instructions: [
11
+ 'Use **action** "set" to replace the full config, "update" to patch only supplied fields, "get" to view one qualifier, "list" to view all configs, or "delete" to remove.',
12
+ 'Destinations route invocation results to other AWS services for further processing.'
13
+ ]
14
+ })
15
+ .input(
16
+ z.object({
17
+ action: z
18
+ .enum(['list', 'get', 'set', 'update', 'delete'])
19
+ .describe('Operation to perform'),
20
+ functionName: z.string().describe('Function name or ARN'),
21
+ qualifier: z.string().optional().describe('Version or alias'),
22
+ marker: z.string().optional().describe('Pagination token for list'),
23
+ maxItems: z.number().optional().describe('Maximum configs to return for list (1-50)'),
24
+ maximumRetryAttempts: z.number().optional().describe('Max retry attempts (0-2)'),
25
+ maximumEventAgeInSeconds: z
26
+ .number()
27
+ .optional()
28
+ .describe('Max event age before discard (60-21600)'),
29
+ onSuccessDestinationArn: z
30
+ .string()
31
+ .optional()
32
+ .describe('Destination ARN for successful invocations'),
33
+ onFailureDestinationArn: z
34
+ .string()
35
+ .optional()
36
+ .describe('Destination ARN for failed invocations')
37
+ })
38
+ )
39
+ .output(
40
+ z.object({
41
+ functionArn: z.string().optional().describe('Function ARN'),
42
+ maximumRetryAttempts: z.number().optional().describe('Max retry attempts'),
43
+ maximumEventAgeInSeconds: z.number().optional().describe('Max event age in seconds'),
44
+ onSuccessDestination: z.string().optional().describe('Success destination ARN'),
45
+ onFailureDestination: z.string().optional().describe('Failure destination ARN'),
46
+ lastModified: z.string().optional().describe('Last modified timestamp'),
47
+ configs: z
48
+ .array(
49
+ z.object({
50
+ functionArn: z.string().optional(),
51
+ maximumRetryAttempts: z.number().optional(),
52
+ maximumEventAgeInSeconds: z.number().optional(),
53
+ onSuccessDestination: z.string().optional(),
54
+ onFailureDestination: z.string().optional(),
55
+ lastModified: z.string().optional()
56
+ })
57
+ )
58
+ .optional()
59
+ .describe('Async invocation configs returned by list'),
60
+ nextMarker: z.string().optional().describe('Pagination token for the next page'),
61
+ deleted: z.boolean().optional()
62
+ })
63
+ )
64
+ .handleInvocation(async ctx => {
65
+ let client = createClient(ctx.config, ctx.auth);
66
+ let { action, functionName, qualifier } = ctx.input;
67
+
68
+ let mapConfig = (result: any) => ({
69
+ functionArn: result.FunctionArn,
70
+ maximumRetryAttempts: result.MaximumRetryAttempts,
71
+ maximumEventAgeInSeconds: result.MaximumEventAgeInSeconds,
72
+ onSuccessDestination: result.DestinationConfig?.OnSuccess?.Destination,
73
+ onFailureDestination: result.DestinationConfig?.OnFailure?.Destination,
74
+ lastModified: result.LastModified ? String(result.LastModified) : undefined
75
+ });
76
+
77
+ if (action === 'list') {
78
+ let result = await client.listFunctionEventInvokeConfigs(
79
+ functionName,
80
+ ctx.input.marker,
81
+ ctx.input.maxItems
82
+ );
83
+ let configs = (result.FunctionEventInvokeConfigs || []).map(mapConfig);
84
+ return {
85
+ output: {
86
+ configs,
87
+ nextMarker: result.NextMarker
88
+ },
89
+ message: `Found **${configs.length}** async invocation config(s) for **${functionName}**.`
90
+ };
91
+ }
92
+
93
+ if (action === 'get') {
94
+ let result = await client.getFunctionEventInvokeConfig(functionName, qualifier);
95
+ return {
96
+ output: mapConfig(result),
97
+ message: `Async config for **${functionName}**: retries=${result.MaximumRetryAttempts}, maxAge=${result.MaximumEventAgeInSeconds}s.`
98
+ };
99
+ }
100
+
101
+ if (action === 'delete') {
102
+ await client.deleteFunctionEventInvokeConfig(functionName, qualifier);
103
+ return {
104
+ output: { deleted: true },
105
+ message: `Removed async invocation config from **${functionName}**.`
106
+ };
107
+ }
108
+
109
+ let params: Record<string, any> = {};
110
+ if (ctx.input.maximumRetryAttempts !== undefined)
111
+ params['MaximumRetryAttempts'] = ctx.input.maximumRetryAttempts;
112
+ if (ctx.input.maximumEventAgeInSeconds !== undefined)
113
+ params['MaximumEventAgeInSeconds'] = ctx.input.maximumEventAgeInSeconds;
114
+
115
+ let destConfig: Record<string, any> = {};
116
+ if (ctx.input.onSuccessDestinationArn)
117
+ destConfig['OnSuccess'] = { Destination: ctx.input.onSuccessDestinationArn };
118
+ if (ctx.input.onFailureDestinationArn)
119
+ destConfig['OnFailure'] = { Destination: ctx.input.onFailureDestinationArn };
120
+ if (Object.keys(destConfig).length > 0) params['DestinationConfig'] = destConfig;
121
+
122
+ let result =
123
+ action === 'update'
124
+ ? await client.updateFunctionEventInvokeConfig(functionName, params, qualifier)
125
+ : await client.putFunctionEventInvokeConfig(functionName, params, qualifier);
126
+ return {
127
+ output: mapConfig(result),
128
+ message:
129
+ action === 'update'
130
+ ? `Patched async invocation config for **${functionName}**.`
131
+ : `Updated async invocation config for **${functionName}**.`
132
+ };
133
+ })
134
+ .build();
@@ -0,0 +1,127 @@
1
+ import { SlateTool } from 'slates';
2
+ import { createClient } from '../lib/helpers';
3
+ import { spec } from '../spec';
4
+ import { z } from 'zod';
5
+
6
+ export let createFunction = SlateTool.create(spec, {
7
+ name: 'Create Function',
8
+ key: 'create_function',
9
+ description: `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.`,
10
+ instructions: [
11
+ 'For ZIP deployments, specify runtime and handler. For container images, set packageType to "Image".',
12
+ 'The role must be an IAM role ARN that Lambda can assume (e.g., arn:aws:iam::123456789012:role/my-role).'
13
+ ]
14
+ })
15
+ .input(
16
+ z.object({
17
+ functionName: z.string().describe('Name for the function (1-64 characters)'),
18
+ role: z.string().describe('IAM execution role ARN'),
19
+ code: z
20
+ .object({
21
+ s3Bucket: z.string().optional().describe('S3 bucket containing the code package'),
22
+ s3Key: z.string().optional().describe('S3 object key for the code package'),
23
+ s3ObjectVersion: z.string().optional().describe('S3 object version'),
24
+ imageUri: z.string().optional().describe('Container image URI from ECR'),
25
+ zipFile: z.string().optional().describe('Base64-encoded ZIP file content')
26
+ })
27
+ .describe('Function code source'),
28
+ runtime: z
29
+ .string()
30
+ .optional()
31
+ .describe('Runtime (e.g., nodejs22.x, python3.13, java21)'),
32
+ handler: z.string().optional().describe('Handler function (e.g., index.handler)'),
33
+ description: z.string().optional().describe('Function description'),
34
+ timeout: z
35
+ .number()
36
+ .optional()
37
+ .describe('Execution timeout in seconds (1-900, default 3)'),
38
+ memorySize: z.number().optional().describe('Memory in MB (128-10240, default 128)'),
39
+ packageType: z.enum(['Zip', 'Image']).optional().describe('Deployment package type'),
40
+ architectures: z
41
+ .array(z.enum(['x86_64', 'arm64']))
42
+ .optional()
43
+ .describe('Instruction set architecture'),
44
+ environment: z
45
+ .record(z.string(), z.string())
46
+ .optional()
47
+ .describe('Environment variables as key-value pairs'),
48
+ layers: z.array(z.string()).optional().describe('Layer ARNs to attach (up to 5)'),
49
+ publish: z.boolean().optional().describe('Publish a version after creation'),
50
+ ephemeralStorageSize: z
51
+ .number()
52
+ .optional()
53
+ .describe('Ephemeral /tmp storage in MB (512-10240)'),
54
+ tags: z
55
+ .record(z.string(), z.string())
56
+ .optional()
57
+ .describe('Resource tags as key-value pairs'),
58
+ tracingMode: z.enum(['Active', 'PassThrough']).optional().describe('X-Ray tracing mode'),
59
+ vpcSubnetIds: z.array(z.string()).optional().describe('VPC subnet IDs'),
60
+ vpcSecurityGroupIds: z.array(z.string()).optional().describe('VPC security group IDs')
61
+ })
62
+ )
63
+ .output(
64
+ z.object({
65
+ functionName: z.string().describe('Name of the created function'),
66
+ functionArn: z.string().describe('ARN of the created function'),
67
+ runtime: z.string().optional().describe('Runtime environment'),
68
+ state: z.string().optional().describe('Current state'),
69
+ version: z.string().optional().describe('Published version'),
70
+ codeSize: z.number().optional().describe('Code package size in bytes'),
71
+ lastModified: z.string().optional().describe('Last modified timestamp')
72
+ })
73
+ )
74
+ .handleInvocation(async ctx => {
75
+ let client = createClient(ctx.config, ctx.auth);
76
+
77
+ let codeObj: Record<string, any> = {};
78
+ if (ctx.input.code.s3Bucket) codeObj['S3Bucket'] = ctx.input.code.s3Bucket;
79
+ if (ctx.input.code.s3Key) codeObj['S3Key'] = ctx.input.code.s3Key;
80
+ if (ctx.input.code.s3ObjectVersion)
81
+ codeObj['S3ObjectVersion'] = ctx.input.code.s3ObjectVersion;
82
+ if (ctx.input.code.imageUri) codeObj['ImageUri'] = ctx.input.code.imageUri;
83
+ if (ctx.input.code.zipFile) codeObj['ZipFile'] = ctx.input.code.zipFile;
84
+
85
+ let params: Record<string, any> = {
86
+ FunctionName: ctx.input.functionName,
87
+ Role: ctx.input.role,
88
+ Code: codeObj
89
+ };
90
+
91
+ if (ctx.input.runtime) params['Runtime'] = ctx.input.runtime;
92
+ if (ctx.input.handler) params['Handler'] = ctx.input.handler;
93
+ if (ctx.input.description) params['Description'] = ctx.input.description;
94
+ if (ctx.input.timeout) params['Timeout'] = ctx.input.timeout;
95
+ if (ctx.input.memorySize) params['MemorySize'] = ctx.input.memorySize;
96
+ if (ctx.input.packageType) params['PackageType'] = ctx.input.packageType;
97
+ if (ctx.input.architectures) params['Architectures'] = ctx.input.architectures;
98
+ if (ctx.input.environment) params['Environment'] = { Variables: ctx.input.environment };
99
+ if (ctx.input.layers) params['Layers'] = ctx.input.layers;
100
+ if (ctx.input.publish !== undefined) params['Publish'] = ctx.input.publish;
101
+ if (ctx.input.ephemeralStorageSize)
102
+ params['EphemeralStorage'] = { Size: ctx.input.ephemeralStorageSize };
103
+ if (ctx.input.tags) params['Tags'] = ctx.input.tags;
104
+ if (ctx.input.tracingMode) params['TracingConfig'] = { Mode: ctx.input.tracingMode };
105
+ if (ctx.input.vpcSubnetIds || ctx.input.vpcSecurityGroupIds) {
106
+ params['VpcConfig'] = {
107
+ SubnetIds: ctx.input.vpcSubnetIds || [],
108
+ SecurityGroupIds: ctx.input.vpcSecurityGroupIds || []
109
+ };
110
+ }
111
+
112
+ let result = await client.createFunction(params);
113
+
114
+ return {
115
+ output: {
116
+ functionName: result.FunctionName,
117
+ functionArn: result.FunctionArn,
118
+ runtime: result.Runtime,
119
+ state: result.State,
120
+ version: result.Version,
121
+ codeSize: result.CodeSize,
122
+ lastModified: result.LastModified
123
+ },
124
+ message: `Created function **${result.FunctionName}** (${result.FunctionArn}).`
125
+ };
126
+ })
127
+ .build();
@@ -0,0 +1,41 @@
1
+ import { SlateTool } from 'slates';
2
+ import { createClient } from '../lib/helpers';
3
+ import { spec } from '../spec';
4
+ import { z } from 'zod';
5
+
6
+ export let deleteFunction = SlateTool.create(spec, {
7
+ name: 'Delete Function',
8
+ key: 'delete_function',
9
+ description: `Delete a Lambda function. Optionally specify a **qualifier** to delete only a specific version (not \`$LATEST\`). Without a qualifier, the entire function including all versions and aliases is deleted.`,
10
+ tags: {
11
+ destructive: true
12
+ }
13
+ })
14
+ .input(
15
+ z.object({
16
+ functionName: z.string().describe('Function name or ARN'),
17
+ qualifier: z
18
+ .string()
19
+ .optional()
20
+ .describe('Version number to delete (cannot delete $LATEST)')
21
+ })
22
+ )
23
+ .output(
24
+ z.object({
25
+ deleted: z.boolean().describe('Whether the deletion was successful')
26
+ })
27
+ )
28
+ .handleInvocation(async ctx => {
29
+ let client = createClient(ctx.config, ctx.auth);
30
+ await client.deleteFunction(ctx.input.functionName, ctx.input.qualifier);
31
+
32
+ let msg = ctx.input.qualifier
33
+ ? `Deleted version **${ctx.input.qualifier}** of function **${ctx.input.functionName}**.`
34
+ : `Deleted function **${ctx.input.functionName}** and all its versions/aliases.`;
35
+
36
+ return {
37
+ output: { deleted: true },
38
+ message: msg
39
+ };
40
+ })
41
+ .build();
@@ -0,0 +1,45 @@
1
+ import { SlateTool } from 'slates';
2
+ import { createClient } from '../lib/helpers';
3
+ import { spec } from '../spec';
4
+ import { z } from 'zod';
5
+
6
+ export let getAccountSettings = SlateTool.create(spec, {
7
+ name: 'Get Account Settings',
8
+ key: 'get_account_settings',
9
+ description: `Retrieve Lambda account-level settings and limits for the configured region, including concurrent execution limits, code storage usage, and total code size.`,
10
+ tags: {
11
+ readOnly: true
12
+ }
13
+ })
14
+ .input(z.object({}))
15
+ .output(
16
+ z.object({
17
+ totalCodeSize: z.number().optional().describe('Total code storage used in bytes'),
18
+ codeSizeUnzipped: z.number().optional().describe('Maximum unzipped deployment size'),
19
+ codeSizeZipped: z.number().optional().describe('Maximum zipped deployment size'),
20
+ concurrentExecutions: z.number().optional().describe('Concurrent execution limit'),
21
+ unreservedConcurrentExecutions: z
22
+ .number()
23
+ .optional()
24
+ .describe('Unreserved concurrent executions available')
25
+ })
26
+ )
27
+ .handleInvocation(async ctx => {
28
+ let client = createClient(ctx.config, ctx.auth);
29
+ let result = await client.getAccountSettings();
30
+
31
+ let usage = result.AccountUsage || {};
32
+ let limits = result.AccountLimit || {};
33
+
34
+ return {
35
+ output: {
36
+ totalCodeSize: usage.TotalCodeSize,
37
+ codeSizeUnzipped: limits.CodeSizeUnzipped,
38
+ codeSizeZipped: limits.CodeSizeZipped,
39
+ concurrentExecutions: limits.ConcurrentExecutions,
40
+ unreservedConcurrentExecutions: limits.UnreservedConcurrentExecutions
41
+ },
42
+ message: `Account limits: **${limits.ConcurrentExecutions}** concurrent executions, **${limits.UnreservedConcurrentExecutions}** unreserved. Code storage: **${(usage.TotalCodeSize / (1024 * 1024 * 1024)).toFixed(2)} GB** used.`
43
+ };
44
+ })
45
+ .build();
@@ -0,0 +1,104 @@
1
+ import { SlateTool } from 'slates';
2
+ import { createClient } from '../lib/helpers';
3
+ import { spec } from '../spec';
4
+ import { z } from 'zod';
5
+
6
+ export let getFunction = SlateTool.create(spec, {
7
+ name: 'Get Function',
8
+ key: 'get_function',
9
+ description: `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.`,
10
+ tags: {
11
+ readOnly: true
12
+ }
13
+ })
14
+ .input(
15
+ z.object({
16
+ functionName: z.string().describe('Function name, ARN, or partial ARN'),
17
+ qualifier: z.string().optional().describe('Version number or alias name')
18
+ })
19
+ )
20
+ .output(
21
+ z.object({
22
+ functionName: z.string().optional().describe('Name of the function'),
23
+ functionArn: z.string().optional().describe('ARN of the function'),
24
+ runtime: z.string().optional().describe('Runtime environment'),
25
+ role: z.string().optional().describe('Execution role ARN'),
26
+ handler: z.string().optional().describe('Function handler'),
27
+ codeSize: z.number().optional().describe('Size of the deployment package in bytes'),
28
+ codeSha256: z.string().optional().describe('SHA256 hash of the deployment package'),
29
+ description: z.string().optional().describe('Function description'),
30
+ timeout: z.number().optional().describe('Execution timeout in seconds'),
31
+ memorySize: z.number().optional().describe('Memory allocated in MB'),
32
+ lastModified: z.string().optional().describe('Last modified timestamp'),
33
+ version: z.string().optional().describe('Function version'),
34
+ state: z.string().optional().describe('Current state'),
35
+ stateReason: z.string().optional().describe('Reason for current state'),
36
+ lastUpdateStatus: z.string().optional().describe('Status of the last update'),
37
+ lastUpdateStatusReason: z
38
+ .string()
39
+ .optional()
40
+ .describe('Reason for the last update status'),
41
+ packageType: z.string().optional().describe('Package type (Zip or Image)'),
42
+ architectures: z.array(z.string()).optional().describe('Instruction set architectures'),
43
+ environment: z
44
+ .record(z.string(), z.string())
45
+ .optional()
46
+ .describe('Environment variables'),
47
+ layers: z
48
+ .array(
49
+ z.object({
50
+ arn: z.string().optional(),
51
+ codeSize: z.number().optional()
52
+ })
53
+ )
54
+ .optional()
55
+ .describe('Attached layers'),
56
+ codeLocation: z.string().optional().describe('Pre-signed URL to download the code'),
57
+ reservedConcurrency: z.number().optional().describe('Reserved concurrent executions'),
58
+ tags: z.record(z.string(), z.string()).optional().describe('Resource tags'),
59
+ ephemeralStorageSize: z.number().optional().describe('Ephemeral storage size in MB'),
60
+ loggingFormat: z.string().optional().describe('Log format (Text or JSON)')
61
+ })
62
+ )
63
+ .handleInvocation(async ctx => {
64
+ let client = createClient(ctx.config, ctx.auth);
65
+ let result = await client.getFunction(ctx.input.functionName, ctx.input.qualifier);
66
+
67
+ let config = result.Configuration || {};
68
+ let layers = (config.Layers || []).map((l: any) => ({
69
+ arn: l.Arn,
70
+ codeSize: l.CodeSize
71
+ }));
72
+
73
+ return {
74
+ output: {
75
+ functionName: config.FunctionName,
76
+ functionArn: config.FunctionArn,
77
+ runtime: config.Runtime,
78
+ role: config.Role,
79
+ handler: config.Handler,
80
+ codeSize: config.CodeSize,
81
+ codeSha256: config.CodeSha256,
82
+ description: config.Description,
83
+ timeout: config.Timeout,
84
+ memorySize: config.MemorySize,
85
+ lastModified: config.LastModified,
86
+ version: config.Version,
87
+ state: config.State,
88
+ stateReason: config.StateReason,
89
+ lastUpdateStatus: config.LastUpdateStatus,
90
+ lastUpdateStatusReason: config.LastUpdateStatusReason,
91
+ packageType: config.PackageType,
92
+ architectures: config.Architectures,
93
+ environment: config.Environment?.Variables,
94
+ layers,
95
+ codeLocation: result.Code?.Location,
96
+ reservedConcurrency: result.Concurrency?.ReservedConcurrentExecutions,
97
+ tags: result.Tags,
98
+ ephemeralStorageSize: config.EphemeralStorage?.Size,
99
+ loggingFormat: config.LoggingConfig?.LogFormat
100
+ },
101
+ message: `Retrieved function **${config.FunctionName}** (${config.Runtime || config.PackageType}, ${config.State || 'Active'}).`
102
+ };
103
+ })
104
+ .build();
@@ -0,0 +1,19 @@
1
+ export { listFunctions } from './list-functions';
2
+ export { getFunction } from './get-function';
3
+ export { createFunction } from './create-function';
4
+ export { updateFunction } from './update-function';
5
+ export { deleteFunction } from './delete-function';
6
+ export { invokeFunction } from './invoke-function';
7
+ export { publishVersion } from './publish-version';
8
+ export { manageAlias } from './manage-alias';
9
+ export { manageLayer } from './manage-layer';
10
+ export { manageEventSourceMapping } from './manage-event-source-mapping';
11
+ export { manageFunctionUrl } from './manage-function-url';
12
+ export { manageConcurrency } from './manage-concurrency';
13
+ export { managePermission } from './manage-permission';
14
+ export { manageTags } from './manage-tags';
15
+ export { configureAsyncInvocation } from './configure-async-invocation';
16
+ export { manageDurableExecution } from './manage-durable-execution';
17
+ export { getAccountSettings } from './get-account-settings';
18
+ export { manageRuntimeManagement } from './manage-runtime-management';
19
+ export { manageRecursionConfig } from './manage-recursion-config';