diff --git a/s3-lambda-textract-bedrock-durable-cdk-ts/.gitignore b/s3-lambda-textract-bedrock-durable-cdk-ts/.gitignore new file mode 100644 index 000000000..ab01f2d2a --- /dev/null +++ b/s3-lambda-textract-bedrock-durable-cdk-ts/.gitignore @@ -0,0 +1,14 @@ +!jest.config.js +*.d.ts +node_modules +package-lock.json + +# CDK asset staging directory +.cdk.staging +cdk.out + +# Parcel default cache directory +.parcel-cache + +# Mac files +.DS_Store diff --git a/s3-lambda-textract-bedrock-durable-cdk-ts/README.md b/s3-lambda-textract-bedrock-durable-cdk-ts/README.md new file mode 100644 index 000000000..4eb691e1c --- /dev/null +++ b/s3-lambda-textract-bedrock-durable-cdk-ts/README.md @@ -0,0 +1,163 @@ +# Durable Document Processing with Amazon S3, AWS Lambda, Amazon Textract, and Amazon Bedrock + +This pattern demonstrates a durable document processing pipeline. When a document is uploaded to Amazon S3, a durable AWS Lambda function extracts text using Amazon Textract's asynchronous API, summarizes the content with Amazon Bedrock (Amazon Nova Lite), and stores the results in Amazon DynamoDB. The durable function uses checkpointing and `waitForCondition` to reliably poll for the Textract job completion without wasting compute, and automatically resumes from the last checkpoint if interrupted. + +Learn more about this pattern at Serverless Land Patterns: [https://serverlessland.com/patterns/s3-lambda-textract-bedrock-durable-cdk-ts](https://serverlessland.com/patterns/s3-lambda-textract-bedrock-durable-cdk-ts) + +Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. + +## Requirements + +* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. +* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured +* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +* [Node.js and npm](https://nodejs.org/) installed +* [AWS CDK](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html) installed +* [Amazon Bedrock model access](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html) enabled for Amazon Nova Lite in your AWS region + +## Important: Bedrock Inference Profile Region Prefix + +The Lambda handler uses a cross-region inference profile ID to invoke Amazon Nova Lite. The profile ID is region-specific: + +| Region | Inference Profile ID | +|--------|---------------------| +| US regions (us-east-1, us-west-2, etc.) | `us.amazon.nova-lite-v1:0` | +| EU regions (eu-central-1, eu-west-1, etc.) | `eu.amazon.nova-lite-v1:0` | +| AP regions (ap-southeast-1, ap-northeast-1, etc.) | `ap.amazon.nova-lite-v1:0` | + +The default in this pattern is `eu.amazon.nova-lite-v1:0`. If deploying to a different region, update the `modelId` in `lambda/processor.js` and the inference profile ARN in `lib/pattern-stack.ts`. + +## Deployment Instructions + +1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository: + + ```bash + git clone https://github.com/aws-samples/serverless-patterns + ``` + +2. Change directory to the pattern directory: + + ```bash + cd s3-lambda-textract-bedrock-durable-cdk-ts + ``` + +3. Install dependencies: + + ```bash + npm install + ``` + +4. Deploy the CDK stack to your default AWS account and region: + + ```bash + cdk deploy + ``` + +5. Note the outputs from the CDK deployment process. These contain the resource names which are used for testing. + +## Deployment Outputs + +After deployment, CDK will display the following outputs. Save these values for testing: + +| Output Key | Description | Usage | +|------------|-------------|-------| +| `DocumentBucketName` | Amazon S3 bucket for document uploads | Upload documents here to trigger processing | +| `ResultsTableName` | Amazon DynamoDB table for processing results | Query this table to see extracted text and summaries | +| `ProcessorFunctionName` | Durable AWS Lambda function name | Use for monitoring and log inspection | +| `ProcessorFunctionArn` | Durable AWS Lambda function ARN | Reference for invocation and permissions | + +## How it works + +![Architecture Diagram](s3-lambda-textract-bedrock-durable-cdk-ts.png) + +This pattern creates a durable AWS Lambda function that implements a multi-step document processing pipeline with automatic checkpointing and resilient polling. + +Architecture flow: +1. A document (PDF, PNG, or JPG) is uploaded to the Amazon S3 document bucket +2. Amazon S3 sends an event notification that triggers the durable AWS Lambda function +3. The function starts an asynchronous Amazon Textract text detection job (Step 1: `start-textract`) +4. The function polls for Textract job completion using `waitForCondition` with exponential backoff (Step 2: `wait-textract-complete`) — the function suspends between polls without consuming compute +5. Once Textract completes, the function extracts text from the response blocks (Step 3: `extract-text`) +6. The extracted text is sent to Amazon Bedrock (Amazon Nova Lite) for summarization (Step 4: `bedrock-summarize`) +7. The summary and metadata are stored in Amazon DynamoDB (Step 5: `store-results`) + +Each step is checkpointed by the durable execution runtime. If the function is interrupted at any point (timeout, transient error), it resumes from the last completed step rather than starting over. + +Example use cases: +- **Invoices**: Extract line items, amounts, and vendor details automatically +- **Contracts**: Identify key clauses, obligations, and renewal dates +- **Insurance documents**: Digitize forms and extract policy information +- **Compliance reports**: Flag non-compliant sections or missing fields + +## Testing + +### Upload a Test Document + +1. Get the S3 bucket name from the stack outputs: + + ```bash + BUCKET_NAME=$(aws cloudformation describe-stacks \ + --stack-name S3LambdaTextractBedrockDurableStack \ + --query 'Stacks[0].Outputs[?OutputKey==`DocumentBucketName`].OutputValue' \ + --output text) + ``` + +2. Upload a PDF, PNG, or JPG document: + + ```bash + aws s3 cp your-document.pdf s3://$BUCKET_NAME/ + ``` + +3. The durable Lambda function is triggered automatically. You can monitor progress in CloudWatch Logs: + + ```bash + FUNCTION_NAME=$(aws cloudformation describe-stacks \ + --stack-name S3LambdaTextractBedrockDurableStack \ + --query 'Stacks[0].Outputs[?OutputKey==`ProcessorFunctionName`].OutputValue' \ + --output text) + + aws logs tail /aws/lambda/doc-processor-durable --follow + ``` + +### Check Processing Results + +1. Get the DynamoDB table name: + + ```bash + TABLE_NAME=$(aws cloudformation describe-stacks \ + --stack-name S3LambdaTextractBedrockDurableStack \ + --query 'Stacks[0].Outputs[?OutputKey==`ResultsTableName`].OutputValue' \ + --output text) + ``` + +2. Scan the table for results (allow 1-2 minutes for processing to complete): + + ```bash + aws dynamodb scan --table-name $TABLE_NAME + ``` + +3. Query a specific document result: + + ```bash + aws dynamodb get-item \ + --table-name $TABLE_NAME \ + --key '{"documentKey": {"S": "your-document.pdf"}}' + ``` + +The result includes the Textract job ID, extracted text length, Bedrock-generated summary, and processing timestamp. + +## Cleanup + +1. Empty the S3 bucket and delete the stack: + + ```bash + cdk destroy + ``` + +2. Confirm the deletion when prompted. + +--- + +Copyright 2026 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: MIT-0 diff --git a/s3-lambda-textract-bedrock-durable-cdk-ts/cdk.json b/s3-lambda-textract-bedrock-durable-cdk-ts/cdk.json new file mode 100644 index 000000000..68ffb5d90 --- /dev/null +++ b/s3-lambda-textract-bedrock-durable-cdk-ts/cdk.json @@ -0,0 +1,22 @@ +{ + "app": "npx ts-node --prefer-ts-exts bin/s3-lambda-textract-bedrock-durable-cdk-ts.ts", + "watch": { + "include": ["**"], + "exclude": [ + "README.md", + "cdk*.json", + "**/*.d.ts", + "**/*.js", + "tsconfig.json", + "package*.json", + "yarn.lock", + "node_modules", + "cdk.out" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": ["aws", "aws-cn"] + } +} diff --git a/s3-lambda-textract-bedrock-durable-cdk-ts/example-pattern.json b/s3-lambda-textract-bedrock-durable-cdk-ts/example-pattern.json new file mode 100644 index 000000000..bda888659 --- /dev/null +++ b/s3-lambda-textract-bedrock-durable-cdk-ts/example-pattern.json @@ -0,0 +1,132 @@ +{ + "title": "Amazon S3 to AWS Lambda (Durable) to Amazon Textract and Bedrock", + "description": "Extract text from documents with Amazon Textract and summarize with Amazon Bedrock using a durable AWS Lambda function.", + "language": "TypeScript", + "level": "300", + "framework": "AWS CDK", + "services": { + "from": { + "serviceName": "Amazon S3", + "serviceURL": "/s3/" + }, + "to": { + "serviceName": "AWS Lambda", + "serviceURL": "/lambda/" + } + }, + "patternArch": { + "icon1": { + "x": 10, + "y": 50, + "service": "s3", + "label": "Amazon S3" + }, + "icon2": { + "x": 35, + "y": 50, + "service": "lambda", + "label": "AWS Lambda (Durable)" + }, + "icon3": { + "x": 60, + "y": 30, + "service": "textract", + "label": "Amazon Textract" + }, + "icon4": { + "x": 60, + "y": 70, + "service": "bedrock", + "label": "Amazon Bedrock" + }, + "icon5": { + "x": 85, + "y": 50, + "service": "dynamodb", + "label": "Amazon DynamoDB" + }, + "line1": { + "from": "icon1", + "to": "icon2" + }, + "line2": { + "from": "icon2", + "to": "icon3" + }, + "line3": { + "from": "icon2", + "to": "icon4" + }, + "line4": { + "from": "icon2", + "to": "icon5" + } + }, + "patternType": "Serverless", + "introBox": { + "headline": "How it works", + "text": [ + "This pattern demonstrates a durable document processing pipeline using AWS Lambda durable functions.", + "When a document (PDF, PNG, or JPG) is uploaded to Amazon S3, it triggers a durable Lambda function.", + "The function starts an asynchronous Amazon Textract text detection job and polls for completion using waitForCondition with exponential backoff.", + "Once text extraction completes, the extracted text is sent to Amazon Bedrock (Amazon Nova Lite) for summarization.", + "Results including the summary are stored in Amazon DynamoDB.", + "Durable functions provide automatic checkpointing, so if the function is interrupted during the long-running Textract polling, it resumes from the last checkpoint without re-executing completed steps.", + "Example use cases: invoice processing, contract analysis, insurance document intake, and compliance review." + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/s3-lambda-textract-bedrock-durable-cdk-ts", + "templateURL": "serverless-patterns/s3-lambda-textract-bedrock-durable-cdk-ts", + "projectFolder": "s3-lambda-textract-bedrock-durable-cdk-ts", + "templateFile": "lib/pattern-stack.ts" + } + }, + "resources": { + "bullets": [ + { + "text": "AWS Lambda Durable Functions Documentation", + "link": "https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html" + }, + { + "text": "Amazon Textract Asynchronous Operations", + "link": "https://docs.aws.amazon.com/textract/latest/dg/async.html" + }, + { + "text": "Amazon Bedrock Amazon Nova Models", + "link": "https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-nova.html" + }, + { + "text": "AWS Lambda Durable Execution SDK for JavaScript", + "link": "https://github.com/aws/aws-durable-execution-sdk-js" + } + ] + }, + "deploy": { + "text": [ + "Clone the repository: git clone https://github.com/aws-samples/serverless-patterns", + "Change directory: cd s3-lambda-textract-bedrock-durable-cdk-ts", + "Install dependencies: npm install", + "Deploy the CDK stack: cdk deploy" + ] + }, + "testing": { + "text": [ + "Get the S3 bucket name: BUCKET_NAME=$(aws cloudformation describe-stacks --stack-name S3LambdaTextractBedrockDurableStack --query 'Stacks[0].Outputs[?OutputKey==`DocumentBucketName`].OutputValue' --output text)", + "Upload a test document: aws s3 cp test-document.pdf s3://$BUCKET_NAME/", + "Check DynamoDB for results: TABLE_NAME=$(aws cloudformation describe-stacks --stack-name S3LambdaTextractBedrockDurableStack --query 'Stacks[0].Outputs[?OutputKey==`ResultsTableName`].OutputValue' --output text) && aws dynamodb scan --table-name $TABLE_NAME" + ] + }, + "cleanup": { + "text": ["Delete the stack: cdk destroy"] + }, + "authors": [ + { + "name": "Marco Jahn", + "image": "https://sessionize.com/image/e99b-400o400o2-pqR4BacUSzHrq4fgZ4wwEQ.png", + "bio": "Senior Solutions Architect, Amazon Web Services", + "linkedin": "marcojahn" + } + ] +} diff --git a/s3-lambda-textract-bedrock-durable-cdk-ts/lambda/processor.js b/s3-lambda-textract-bedrock-durable-cdk-ts/lambda/processor.js new file mode 100644 index 000000000..2fa99894d --- /dev/null +++ b/s3-lambda-textract-bedrock-durable-cdk-ts/lambda/processor.js @@ -0,0 +1,143 @@ +const { withDurableExecution, createWaitStrategy } = require('@aws/durable-execution-sdk-js'); +const { TextractClient, StartDocumentTextDetectionCommand, GetDocumentTextDetectionCommand } = require('@aws-sdk/client-textract'); +const { BedrockRuntimeClient, InvokeModelCommand } = require('@aws-sdk/client-bedrock-runtime'); +const { DynamoDBClient, PutItemCommand } = require('@aws-sdk/client-dynamodb'); + +const textractClient = new TextractClient(); +const bedrockClient = new BedrockRuntimeClient(); +const dynamoClient = new DynamoDBClient(); + +const RESULTS_TABLE_NAME = process.env.RESULTS_TABLE_NAME; + +/** + * Durable document processing pipeline: + * 1. Start Amazon Textract async job + * 2. Poll for Textract job completion (using waitForCondition) + * 3. Retrieve extracted text + * 4. Summarize with Amazon Bedrock (Claude 3 Haiku) + * 5. Store results in Amazon DynamoDB + */ +exports.handler = withDurableExecution(async (event, context) => { + // Parse S3 event — get bucket and key from the first record + const s3Record = event.Records[0].s3; + const bucket = s3Record.bucket.name; + const key = decodeURIComponent(s3Record.object.key.replace(/\+/g, ' ')); + + context.logger.info(`Processing document: s3://${bucket}/${key}`); + + // Step 1: Start Textract async text detection + const jobId = await context.step('start-textract', async () => { + const response = await textractClient.send(new StartDocumentTextDetectionCommand({ + DocumentLocation: { + S3Object: { Bucket: bucket, Name: key }, + }, + })); + return response.JobId; + }); + + context.logger.info(`Textract job started: ${jobId}`); + + // Step 2: Poll for Textract job completion using waitForCondition + const textractResult = await context.waitForCondition( + 'wait-textract-complete', + async (state) => { + const response = await textractClient.send(new GetDocumentTextDetectionCommand({ + JobId: state.jobId, + })); + return { + jobId: state.jobId, + status: response.JobStatus, + blockCount: (response.Blocks || []).length, + }; + }, + { + initialState: { jobId, status: 'IN_PROGRESS', blockCount: 0 }, + waitStrategy: createWaitStrategy({ + maxAttempts: 60, + initialDelaySeconds: 3, + maxDelaySeconds: 30, + backoffRate: 1.5, + shouldContinuePolling: (result) => + result.status === 'IN_PROGRESS', + }), + timeout: { minutes: 30 }, + } + ); + + if (textractResult.status !== 'SUCCEEDED') { + throw new Error(`Textract job failed with status: ${textractResult.status}`); + } + + // Step 3: Retrieve full Textract results and extract text + const extractedText = await context.step('extract-text', async () => { + const response = await textractClient.send(new GetDocumentTextDetectionCommand({ + JobId: jobId, + })); + const lines = (response.Blocks || []) + .filter((block) => block.BlockType === 'LINE') + .map((block) => block.Text); + return lines.join('\n'); + }); + + context.logger.info(`Extracted ${extractedText.length} characters of text`); + + // Step 4: Summarize extracted text with Amazon Bedrock (Amazon Nova Lite) + const summary = await context.step('bedrock-summarize', async () => { + // Truncate text to fit within model context window + const truncatedText = extractedText.substring(0, 15000); + + const response = await bedrockClient.send(new InvokeModelCommand({ + modelId: 'eu.amazon.nova-lite-v1:0', + contentType: 'application/json', + accept: 'application/json', + body: JSON.stringify({ + schemaVersion: 'messages-v1', + messages: [ + { + role: 'user', + content: [ + { + text: `Summarize the following document text. Provide a concise summary, key topics, and any important entities (names, dates, amounts) found.\n\nDocument text:\n${truncatedText}`, + }, + ], + }, + ], + inferenceConfig: { + max_new_tokens: 1024, + }, + }), + })); + + const result = JSON.parse(new TextDecoder().decode(response.body)); + return result.output.message.content[0].text; + }); + + context.logger.info('Bedrock summarization complete'); + + // Step 5: Store results in DynamoDB + await context.step('store-results', async () => { + await dynamoClient.send(new PutItemCommand({ + TableName: RESULTS_TABLE_NAME, + Item: { + documentKey: { S: key }, + bucket: { S: bucket }, + textractJobId: { S: jobId }, + extractedTextLength: { N: String(extractedText.length) }, + summary: { S: summary }, + processedAt: { S: new Date().toISOString() }, + }, + })); + }); + + context.logger.info(`Results stored for document: ${key}`); + + return { + statusCode: 200, + body: { + document: `s3://${bucket}/${key}`, + textractJobId: jobId, + extractedCharacters: extractedText.length, + summary, + }, + }; +}); diff --git a/s3-lambda-textract-bedrock-durable-cdk-ts/lib/pattern-stack.ts b/s3-lambda-textract-bedrock-durable-cdk-ts/lib/pattern-stack.ts new file mode 100644 index 000000000..d51a54606 --- /dev/null +++ b/s3-lambda-textract-bedrock-durable-cdk-ts/lib/pattern-stack.ts @@ -0,0 +1,142 @@ +import * as cdk from 'aws-cdk-lib'; +import * as lambda from 'aws-cdk-lib/aws-lambda'; +import * as s3 from 'aws-cdk-lib/aws-s3'; +import * as s3n from 'aws-cdk-lib/aws-s3-notifications'; +import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; +import * as iam from 'aws-cdk-lib/aws-iam'; +import * as logs from 'aws-cdk-lib/aws-logs'; +import { Construct } from 'constructs'; +import * as path from 'path'; + +export class PatternStack extends cdk.Stack { + constructor(scope: Construct, id: string, props?: cdk.StackProps) { + super(scope, id, props); + + // S3 bucket for document uploads + const documentBucket = new s3.Bucket(this, 'DocumentBucket', { + removalPolicy: cdk.RemovalPolicy.DESTROY, + autoDeleteObjects: true, + encryption: s3.BucketEncryption.S3_MANAGED, + }); + + // DynamoDB table for processing results + const resultsTable = new dynamodb.Table(this, 'ResultsTable', { + partitionKey: { name: 'documentKey', type: dynamodb.AttributeType.STRING }, + removalPolicy: cdk.RemovalPolicy.DESTROY, + billingMode: dynamodb.BillingMode.PAY_PER_REQUEST, + }); + + // CloudWatch Log Group for the durable function + const logGroup = new logs.LogGroup(this, 'ProcessorLogGroup', { + logGroupName: `/aws/lambda/doc-processor-durable`, + retention: logs.RetentionDays.ONE_WEEK, + removalPolicy: cdk.RemovalPolicy.DESTROY, + }); + + // Durable Lambda function for document processing + const processorFunction = new lambda.Function(this, 'ProcessorFunction', { + runtime: lambda.Runtime.NODEJS_24_X, + handler: 'processor.handler', + code: lambda.Code.fromAsset(path.join(__dirname, '../lambda')), + timeout: cdk.Duration.minutes(15), + memorySize: 512, + logGroup, + environment: { + RESULTS_TABLE_NAME: resultsTable.tableName, + DOCUMENT_BUCKET_NAME: documentBucket.bucketName, + BEDROCK_MODEL_ID: 'us.amazon.nova-lite-v1:0', + }, + }); + + // Enable durable execution via L1 escape hatch + const cfnFunction = processorFunction.node.defaultChild as cdk.CfnResource; + cfnFunction.addPropertyOverride('DurableConfig', { + ExecutionTimeout: 3600, // 1 hour max execution time + RetentionPeriodInDays: 3, // Keep execution state for 3 days + }); + + // Grant the durable execution managed policy + processorFunction.role?.addManagedPolicy( + iam.ManagedPolicy.fromAwsManagedPolicyName( + 'service-role/AWSLambdaBasicDurableExecutionRolePolicy' + ) + ); + + // Grant S3 read access for Textract and the Lambda function + documentBucket.grantRead(processorFunction); + + // Grant DynamoDB write access + resultsTable.grantWriteData(processorFunction); + + // Grant Amazon Textract permissions + // Textract does not support resource-level permissions — wildcard is required. + // Actions are scoped to only the two operations needed by this handler. + // See: https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazontextract.html + processorFunction.addToRolePolicy(new iam.PolicyStatement({ + actions: [ + 'textract:StartDocumentTextDetection', + 'textract:GetDocumentTextDetection', + ], + resources: ['*'], + })); + + // Grant Amazon Bedrock invoke model permission + // Cross-region inference profiles route to any region in the geo area, + // so we allow the foundation model in all regions via wildcard + processorFunction.addToRolePolicy(new iam.PolicyStatement({ + actions: ['bedrock:InvokeModel'], + resources: [ + `arn:aws:bedrock:*::foundation-model/amazon.nova-lite-v1:0`, + `arn:aws:bedrock:${this.region}:${this.account}:inference-profile/eu.amazon.nova-lite-v1:0`, + ], + })); + + // Create a version and alias for durable function invocation + // Durable functions require qualified ARNs (version or alias) + const version = processorFunction.currentVersion; + const alias = new lambda.Alias(this, 'ProcessorAlias', { + aliasName: 'live', + version, + }); + + // S3 event notification triggers the durable Lambda alias on object creation + documentBucket.addEventNotification( + s3.EventType.OBJECT_CREATED, + new s3n.LambdaDestination(alias), + { suffix: '.pdf' } + ); + + documentBucket.addEventNotification( + s3.EventType.OBJECT_CREATED, + new s3n.LambdaDestination(alias), + { suffix: '.png' } + ); + + documentBucket.addEventNotification( + s3.EventType.OBJECT_CREATED, + new s3n.LambdaDestination(alias), + { suffix: '.jpg' } + ); + + // Outputs + new cdk.CfnOutput(this, 'DocumentBucketName', { + value: documentBucket.bucketName, + description: 'S3 bucket for document uploads', + }); + + new cdk.CfnOutput(this, 'ResultsTableName', { + value: resultsTable.tableName, + description: 'DynamoDB table for processing results', + }); + + new cdk.CfnOutput(this, 'ProcessorFunctionName', { + value: processorFunction.functionName, + description: 'Durable Lambda function name', + }); + + new cdk.CfnOutput(this, 'ProcessorFunctionArn', { + value: processorFunction.functionArn, + description: 'Durable Lambda function ARN', + }); + } +} diff --git a/s3-lambda-textract-bedrock-durable-cdk-ts/package.json b/s3-lambda-textract-bedrock-durable-cdk-ts/package.json new file mode 100644 index 000000000..46bc9b752 --- /dev/null +++ b/s3-lambda-textract-bedrock-durable-cdk-ts/package.json @@ -0,0 +1,22 @@ +{ + "name": "s3-lambda-textract-bedrock-durable-cdk-ts", + "version": "0.1.0", + "bin": { + "s3-lambda-textract-bedrock-durable-cdk-ts": "bin/s3-lambda-textract-bedrock-durable-cdk-ts.js" + }, + "scripts": { + "build": "tsc", + "watch": "tsc -w", + "cdk": "cdk" + }, + "devDependencies": { + "@types/node": "22.7.9", + "aws-cdk": "2.1110.0", + "ts-node": "^10.9.2", + "typescript": "~5.6.3" + }, + "dependencies": { + "aws-cdk-lib": "2.242.0", + "constructs": "^10.0.0" + } +} diff --git a/s3-lambda-textract-bedrock-durable-cdk-ts/s3-lambda-textract-bedrock-durable-cdk-ts.png b/s3-lambda-textract-bedrock-durable-cdk-ts/s3-lambda-textract-bedrock-durable-cdk-ts.png new file mode 100644 index 000000000..7182b5202 Binary files /dev/null and b/s3-lambda-textract-bedrock-durable-cdk-ts/s3-lambda-textract-bedrock-durable-cdk-ts.png differ diff --git a/s3-lambda-textract-bedrock-durable-cdk-ts/tsconfig.json b/s3-lambda-textract-bedrock-durable-cdk-ts/tsconfig.json new file mode 100644 index 000000000..507608a99 --- /dev/null +++ b/s3-lambda-textract-bedrock-durable-cdk-ts/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "lib": ["es2020"], + "declaration": true, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": false, + "inlineSourceMap": true, + "inlineSources": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "typeRoots": ["./node_modules/@types"] + }, + "exclude": ["node_modules", "cdk.out"] +}