npm package: @fnd-platform/constructs
Description: Reusable CDK constructs for Lambda and API Gateway in fnd-platform
Latest version: 1.0.0-alpha.8

# @fnd-platform/constructs

Reusable AWS CDK constructs for Lambda, API Gateway, DynamoDB, and S3 in fnd-platform applications. Provides production-ready infrastructure patterns with sensible defaults.

## Installation

```bash
npm install @fnd-platform/constructs
# or
pnpm add @fnd-platform/constructs
```

## Quick Start

```typescript
import * as cdk from 'aws-cdk-lib';
import {
  FndLambdaFunction,
  FndApiGateway,
  FndDynamoDBTable,
  FndApiStack,
} from '@fnd-platform/constructs';

const app = new cdk.App();

class MyApiStack extends FndApiStack {
  constructor(scope: cdk.App, id: string, props: cdk.StackProps) {
    super(scope, id, props);

    // Create DynamoDB table
    const table = new FndDynamoDBTable(this, 'Table', {
      appName: 'my-app',
      stage: 'dev',
    });

    // Create Lambda function
    const handler = new FndLambdaFunction(this, 'Handler', {
      appName: 'my-app',
      stage: 'dev',
      entry: 'src/handlers/content.ts',
      environment: {
        TABLE_NAME: table.table.tableName,
      },
    });

    // Grant permissions
    table.table.grantReadWriteData(handler.function);

    // Create API Gateway
    const api = new FndApiGateway(this, 'Api', {
      appName: 'my-app',
      stage: 'dev',
    });

    // Add routes
    api.addRoute({
      path: '/content',
      method: 'GET',
      handler: handler.function,
    });
  }
}
```

## Constructs

### FndLambdaFunction

Creates a Lambda function with production-ready defaults.

```typescript
import { FndLambdaFunction } from '@fnd-platform/constructs';

const handler = new FndLambdaFunction(this, 'Handler', {
  appName: 'my-app',
  stage: 'dev',
  entry: 'src/handlers/content.ts',
  handler: 'handler',
  memorySize: 256,
  timeout: cdk.Duration.seconds(30),
  environment: {
    TABLE_NAME: 'my-table',
  },
});

// Access the underlying Lambda function
handler.function;
```

**Props:**

| Prop          | Type                     | Default      | Description           |
| ------------- | ------------------------ | ------------ | --------------------- |
| `appName`     | `string`                 | **required** | Application name      |
| `stage`       | `Stage`                  | **required** | Deployment stage      |
| `entry`       | `string`                 | **required** | Path to handler file  |
| `handler`     | `string`                 | `'handler'`  | Export name           |
| `memorySize`  | `number`                 | `256`        | Memory in MB          |
| `timeout`     | `Duration`               | `30 seconds` | Function timeout      |
| `environment` | `Record<string, string>` | `{}`         | Environment variables |

### FndApiGateway

Creates an API Gateway REST API with CORS and sensible defaults.

```typescript
import { FndApiGateway } from '@fnd-platform/constructs';

const api = new FndApiGateway(this, 'Api', {
  appName: 'my-app',
  stage: 'dev',
  cors: true,
  throttling: {
    rateLimit: 1000,
    burstLimit: 500,
  },
});

// Add routes
api.addRoute({
  path: '/content',
  method: 'GET',
  handler: listHandler.function,
});

api.addRoute({
  path: '/content/{id}',
  method: 'GET',
  handler: getHandler.function,
});

api.addRoute({
  path: '/content',
  method: 'POST',
  handler: createHandler.function,
  authorizer: cognitoAuthorizer,
});

// Access API URL
api.api.url;
```

**Props:**

| Prop         | Type      | Default      | Description          |
| ------------ | --------- | ------------ | -------------------- |
| `appName`    | `string`  | **required** | Application name     |
| `stage`      | `Stage`   | **required** | Deployment stage     |
| `cors`       | `boolean` | `true`       | Enable CORS          |
| `throttling` | `object`  | -            | Rate limiting config |

### FndDynamoDBTable

Creates a DynamoDB table with single-table design and GSIs.

```typescript
import { FndDynamoDBTable } from '@fnd-platform/constructs';

const table = new FndDynamoDBTable(this, 'Table', {
  appName: 'my-app',
  stage: 'dev',
  stream: 'NEW_AND_OLD_IMAGES',
  pointInTimeRecovery: true,
});

// Access the underlying table
table.table;
table.tableName;
```

**Props:**

| Prop                  | Type             | Default         | Description             |
| --------------------- | ---------------- | --------------- | ----------------------- |
| `appName`             | `string`         | **required**    | Application name        |
| `stage`               | `Stage`          | **required**    | Deployment stage        |
| `stream`              | `StreamViewType` | -               | DynamoDB Streams config |
| `pointInTimeRecovery` | `boolean`        | `true` for prod | Enable PITR             |

**Table Structure:**

- Primary Key: `pk` (partition key), `sk` (sort key)
- GSI1: `GSI1PK`, `GSI1SK`
- GSI2: `GSI2PK`, `GSI2SK`

### FndMediaBucket

Creates an S3 bucket for media storage with CloudFront distribution.

```typescript
import { FndMediaBucket } from '@fnd-platform/constructs';

const mediaBucket = new FndMediaBucket(this, 'Media', {
  appName: 'my-app',
  stage: 'dev',
  cors: true,
});

// Access bucket and distribution
mediaBucket.bucket;
mediaBucket.distribution;
```

### FndApiStack

Base stack class with common utilities.

```typescript
import { FndApiStack } from '@fnd-platform/constructs';

class MyStack extends FndApiStack {
  constructor(scope: cdk.App, id: string, props: FndApiStackProps) {
    super(scope, id, props);

    // Use inherited stage and appName
    console.log(this.stage); // 'dev' | 'staging' | 'prod'
    console.log(this.appName); // 'my-app'
  }
}
```

## Utilities

### Resource Naming

```typescript
import { resourceName, validateStage, isValidStage } from '@fnd-platform/constructs';

// Generate consistent resource names
const name = resourceName('my-app', 'dev', 'table');
// Returns: 'my-app-dev-table'

// Validate stage
validateStage('dev'); // OK
validateStage('test'); // Throws error

// Check if valid stage
isValidStage('dev'); // true
isValidStage('test'); // false
```

## API Reference

See the [full API documentation](../../docs/api/modules/constructs_src.html) for detailed type definitions and examples.

### Constructs

```typescript
import {
  FndLambdaFunction,
  FndApiGateway,
  FndDynamoDBTable,
  FndApiStack,
  FndMediaBucket,
} from '@fnd-platform/constructs';
```

### Utilities

```typescript
import { resourceName, validateStage, isValidStage, VALID_STAGES } from '@fnd-platform/constructs';
```

### Types

```typescript
import type {
  FndLambdaFunctionProps,
  FndApiGatewayProps,
  ApiRoute,
  HttpMethod,
  FndDynamoDBTableProps,
  StreamViewType,
  FndApiStackProps,
  FndMediaBucketProps,
  Stage,
} from '@fnd-platform/constructs';

// Stage = 'dev' | 'staging' | 'prod'
// HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS'
// StreamViewType = 'NEW_IMAGE' | 'OLD_IMAGE' | 'NEW_AND_OLD_IMAGES' | 'KEYS_ONLY'
```

## Requirements

- Node.js 20+
- AWS CDK v2
- AWS CLI configured with credentials

## Related

- [@fnd-platform/api](../api/README.md) - API handlers
- [@fnd-platform/dynamodb](../dynamodb/README.md) - DynamoDB utilities
- [@fnd-platform/cognito-auth](../cognito-auth/README.md) - Cognito construct
- [@fnd-platform/pipeline](../pipeline/README.md) - CI/CD pipeline

## License

MIT