@codedrifters/constructs 0.0.61 → 0.0.63

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 (2) hide show
  1. package/README.md +3 -453
  2. package/package.json +6 -3
package/README.md CHANGED
@@ -1,457 +1,7 @@
1
1
  # @codedrifters/constructs
2
2
 
3
- A collection of reusable AWS CDK constructs frequently used in CodeDrifters projects. This package provides pre-configured, secure, and production-ready constructs for common AWS infrastructure patterns.
3
+ A collection of reusable AWS CDK constructs for common infrastructure patterns. Pre-configured, secure, and production-ready building blocks for static hosting (`StaticHosting`, `StaticContent`), S3 (`PrivateBucket`), and more.
4
4
 
5
- ## Table of Contents
5
+ **Documentation:** See the [@codedrifters/constructs docs](../../../docs/src/content/docs/packages/@codedrifters/constructs/index.md) in the monorepo's Starlight site.
6
6
 
7
- - [What are AWS CDK Constructs?](#what-are-aws-cdk-constructs)
8
- - [Installation](#installation)
9
- - [Constructs](#constructs)
10
- - [S3 Constructs](#s3-constructs)
11
- - [PrivateBucket](#privatebucket)
12
- - [Static Hosting Constructs](#static-hosting-constructs)
13
- - [StaticHosting](#statichosting)
14
- - [StaticContent](#staticcontent)
15
- - [Complete Example](#complete-example)
16
- - [API Reference](#api-reference)
17
- - [Further Documentation](#further-documentation)
18
-
19
- ## What are AWS CDK Constructs?
20
-
21
- AWS CDK (Cloud Development Kit) constructs are reusable cloud components that encapsulate AWS resources and their configuration. Think of them as building blocks that combine multiple AWS services into higher-level abstractions.
22
-
23
- For example, instead of manually configuring an S3 bucket, CloudFront distribution, Route53 records, and SSL certificates separately, a construct can combine all of these into a single "StaticHosting" construct that you can use with just a few lines of code.
24
-
25
- **Key Benefits:**
26
- - **Reusability**: Write once, use everywhere
27
- - **Consistency**: Enforce best practices and security defaults
28
- - **Simplicity**: Complex infrastructure becomes simple API calls
29
- - **Type Safety**: Full TypeScript support with IntelliSense
30
-
31
- For more information about AWS CDK constructs, see the [AWS CDK Developer Guide](https://docs.aws.amazon.com/cdk/v2/guide/home.html).
32
-
33
- ## Installation
34
-
35
- Add the package to your CDK project using Configulator/Projen configuration. This ensures consistent dependency management across your project.
36
-
37
- > **Note:** Always configure dependencies through Projen configuration files, never by manually running `npm install`, `pnpm add`, or `yarn add`. Manual installation will create conflicts with Projen-managed files.
38
-
39
- ### In a Monorepo (Recommended)
40
-
41
- If you're using `@codedrifters/configulator` in a monorepo, add the package as a dependency in your sub-project configuration:
42
-
43
- ```typescript
44
- import { TypeScriptProject } from '@codedrifters/configulator';
45
- import { MonorepoProject } from '@codedrifters/configulator';
46
-
47
- const myCdkProject = new TypeScriptProject({
48
- name: 'my-cdk-project',
49
- packageName: '@myorg/my-cdk-project',
50
- outdir: 'packages/my-cdk-project',
51
- parent: root, // Your MonorepoProject instance
52
-
53
- deps: [
54
- '@codedrifters/constructs',
55
- ],
56
-
57
- devDeps: [
58
- 'aws-cdk-lib@catalog:', // Catalog versions are pre-configured
59
- 'constructs@catalog:',
60
- ],
61
- });
62
- ```
63
-
64
- ### In a Standalone CDK Project
65
-
66
- If you're using AWS CDK directly (not via Configulator), add the package to your `deps` array:
67
-
68
- ```typescript
69
- import { awscdk } from 'projen';
70
-
71
- const project = new awscdk.AwsCdkTypeScriptApp({
72
- name: 'my-cdk-app',
73
-
74
- deps: [
75
- '@codedrifters/constructs',
76
- ],
77
-
78
- devDeps: [
79
- 'aws-cdk-lib',
80
- 'constructs',
81
- ],
82
- });
83
- ```
84
-
85
- ### After Adding to Configuration
86
-
87
- After updating your projenrc configuration file, run:
88
-
89
- ```bash
90
- npx projen
91
- ```
92
-
93
- This will update your `package.json` and install the dependencies.
94
-
95
- ### Peer Dependencies
96
-
97
- This package requires the following peer dependencies:
98
-
99
- - `aws-cdk-lib` - AWS CDK construct library
100
- - `constructs` - Core constructs library
101
-
102
- These should be added as dev dependencies in your project configuration. If you're using `@codedrifters/configulator`, the catalog versions (`@catalog:`) are automatically configured in the root `MonorepoProject`.
103
-
104
- ## Constructs
105
-
106
- ### S3 Constructs
107
-
108
- #### PrivateBucket
109
-
110
- A secure S3 bucket with sensible security defaults. This construct extends AWS CDK's `Bucket` construct with security best practices applied by default.
111
-
112
- **Security Defaults:**
113
- - Public access is blocked (`BlockPublicAccess.BLOCK_ALL`)
114
- - SSL/TLS is enforced for all requests
115
- - Bucket owner enforced object ownership
116
- - Configurable removal policy (defaults to `RETAIN`)
117
-
118
- **Basic Usage:**
119
-
120
- ```typescript
121
- import { PrivateBucket } from '@codedrifters/constructs';
122
- import { Stack } from 'aws-cdk-lib';
123
- import { Construct } from 'constructs';
124
-
125
- const stack = new Stack(app, 'MyStack');
126
-
127
- // Create a private bucket with default security settings
128
- const bucket = new PrivateBucket(stack, 'MyPrivateBucket');
129
- ```
130
-
131
- **With Custom Properties:**
132
-
133
- ```typescript
134
- import { RemovalPolicy } from 'aws-cdk-lib';
135
- import { PrivateBucket } from '@codedrifters/constructs';
136
-
137
- const bucket = new PrivateBucket(stack, 'MyPrivateBucket', {
138
- removalPolicy: RemovalPolicy.DESTROY,
139
- autoDeleteObjects: true,
140
- versioned: true,
141
- });
142
- ```
143
-
144
- **Note:** The security settings (public access blocked, SSL enforced, etc.) cannot be overridden - they are always applied to ensure bucket security.
145
-
146
- ### Static Hosting Constructs
147
-
148
- #### StaticHosting
149
-
150
- A complete static website hosting solution that creates and configures:
151
-
152
- - **S3 Bucket**: Private bucket for storing static files (using `PrivateBucket`)
153
- - **CloudFront Distribution**: Global CDN for fast content delivery
154
- - **SSL Certificate**: Wildcard certificate via AWS Certificate Manager
155
- - **Route53 Records**: DNS entries for the domain and wildcard subdomains
156
- - **Lambda@Edge Function**: Viewer request handler for path rewriting
157
- - **SSM Parameters**: Stores bucket ARN, distribution domain, and distribution ID for later use
158
-
159
- **Features:**
160
- - Automatic wildcard SSL certificate generation
161
- - Support for custom domains with automatic DNS configuration
162
- - Lambda@Edge function for intelligent path rewriting
163
- - Conservative caching policy (60s default TTL)
164
- - Stores configuration in SSM Parameter Store for use by `StaticContent`
165
-
166
- **Basic Usage (CloudFront Domain Only):**
167
-
168
- ```typescript
169
- import { StaticHosting } from '@codedrifters/constructs';
170
- import { Stack } from 'aws-cdk-lib';
171
-
172
- const hostingStack = new Stack(app, 'HostingStack', { env });
173
-
174
- const hosting = new StaticHosting(hostingStack, 'static-hosting', {
175
- description: 'My static website',
176
- });
177
- ```
178
-
179
- **With Custom Domain:**
180
-
181
- ```typescript
182
- import { StaticHosting } from '@codedrifters/constructs';
183
- import { Stack, RemovalPolicy } from 'aws-cdk-lib';
184
-
185
- const hostingStack = new Stack(app, 'HostingStack', { env });
186
-
187
- const hosting = new StaticHosting(hostingStack, 'static-hosting', {
188
- description: 'My static website',
189
- staticDomainProps: {
190
- baseDomain: 'example.com',
191
- hostedZoneAttributes: {
192
- hostedZoneId: 'Z1234567890ABC',
193
- zoneName: 'example.com',
194
- },
195
- },
196
- privateBucketProps: {
197
- removalPolicy: RemovalPolicy.DESTROY,
198
- autoDeleteObjects: true,
199
- },
200
- });
201
- ```
202
-
203
- **Properties:**
204
-
205
- | Property | Type | Default | Description |
206
- |----------|------|---------|-------------|
207
- | `description` | `string` | `undefined` | Short description for traceability |
208
- | `staticDomainProps` | `StaticDomainProps` | `undefined` | Domain configuration (optional) |
209
- | `bucketArnParamName` | `string` | `"/STATIC_WEBSITE/BUCKET_ARN"` | SSM parameter name for bucket ARN |
210
- | `distributionDomainParamName` | `string` | `"/STATIC_WEBSITE/DISTRIBUTION_DOMAIN"` | SSM parameter name for distribution domain |
211
- | `distributionIDParamName` | `string` | `"/STATIC_WEBSITE/DISTRIBUTION_ID"` | SSM parameter name for distribution ID |
212
- | `privateBucketProps` | `PrivateBucketProps` | `undefined` | Props to pass to the S3 bucket |
213
-
214
- **StaticDomainProps:**
215
-
216
- | Property | Type | Description |
217
- |----------|------|-------------|
218
- | `baseDomain` | `string` | The base domain (e.g., `example.com`) |
219
- | `hostedZoneAttributes` | `HostedZoneAttributes` | Hosted zone ID and zone name |
220
-
221
- **Outputs:**
222
-
223
- The construct exposes:
224
- - `fullDomain: string` - The full domain name (custom domain if provided, otherwise CloudFront domain)
225
-
226
- **SSM Parameters Created:**
227
-
228
- The construct automatically creates SSM parameters that can be referenced by `StaticContent`:
229
- - Bucket ARN (default: `/STATIC_WEBSITE/BUCKET_ARN`)
230
- - CloudFront Distribution Domain (default: `/STATIC_WEBSITE/DISTRIBUTION_DOMAIN`)
231
- - CloudFront Distribution ID (default: `/STATIC_WEBSITE/DISTRIBUTION_ID`)
232
-
233
- #### StaticContent
234
-
235
- Deploys static content from a local directory to an S3 bucket. This construct is designed to work with `StaticHosting` and supports branch-based deployment paths for PR and feature branch previews.
236
-
237
- **Features:**
238
- - Deploys files from a local directory to S3
239
- - Supports branch-based path prefixes (e.g., `feature-123.example.com/`)
240
- - Automatically retrieves bucket ARN from SSM Parameter Store
241
- - Configurable destination directory within the bucket
242
-
243
- **How Branch-Based Deployment Works:**
244
-
245
- The construct uses the current git branch name to create unique deployment paths. This allows multiple branches to deploy to the same bucket without conflicts:
246
-
247
- ```
248
- S3 Bucket Structure:
249
- ├── example.com/ → Production/main branch
250
- ├── feature-123.example.com/ → Feature branch
251
- ├── pr-456.example.com/ → Pull request
252
- └── stage.example.com/ → Staging branch
253
- ```
254
-
255
- **Basic Usage:**
256
-
257
- ```typescript
258
- import { StaticContent, StaticHosting } from '@codedrifters/constructs';
259
- import { Stack } from 'aws-cdk-lib';
260
-
261
- // First, create the hosting infrastructure
262
- const hostingStack = new Stack(app, 'HostingStack', { env });
263
- const hosting = new StaticHosting(hostingStack, 'static-hosting', {
264
- staticDomainProps: {
265
- baseDomain: 'example.com',
266
- hostedZoneAttributes: {
267
- hostedZoneId: 'Z1234567890ABC',
268
- zoneName: 'example.com',
269
- },
270
- },
271
- });
272
-
273
- // Then, deploy content in a separate stack
274
- const contentStack = new Stack(app, 'ContentStack', { env });
275
- contentStack.node.addDependency(hostingStack);
276
-
277
- new StaticContent(contentStack, 'static-content', {
278
- contentSourceDirectory: 'dist', // Local directory with built files
279
- contentDestinationDirectory: '/', // Deploy to root of bucket path
280
- fullDomain: hosting.fullDomain, // Use domain from StaticHosting
281
- });
282
- ```
283
-
284
- **With Custom Subdomain:**
285
-
286
- ```typescript
287
- new StaticContent(contentStack, 'static-content', {
288
- contentSourceDirectory: 'dist',
289
- contentDestinationDirectory: '/',
290
- fullDomain: hosting.fullDomain,
291
- subDomain: 'staging', // Override git branch detection
292
- bucketArnParamName: '/STATIC_WEBSITE/BUCKET_ARN', // Custom param name
293
- });
294
- ```
295
-
296
- **Properties:**
297
-
298
- | Property | Type | Default | Description |
299
- |----------|------|---------|-------------|
300
- | `contentSourceDirectory` | `string` | **Required** | Absolute path to directory containing files to deploy |
301
- | `contentDestinationDirectory` | `string` | **Required** | Directory within bucket to place content (should start with `/`) |
302
- | `fullDomain` | `string` | **Required** | Full domain name (from `StaticHosting.fullDomain`) |
303
- | `subDomain` | `string` | Git branch name | Subdomain prefix (defaults to current git branch) |
304
- | `bucketArnParamName` | `string` | `"/STATIC_WEBSITE/BUCKET_ARN"` | SSM parameter name for bucket ARN |
305
-
306
- **Path Construction:**
307
-
308
- The construct creates a unique path prefix using: `{subDomain}.{fullDomain}`
309
-
310
- For example:
311
- - Branch: `feature-123`, Domain: `example.com` → Path: `feature-123.example.com/`
312
- - Branch: `main`, Domain: `example.com` → Path: `main.example.com/` (or just `example.com/` if subdomain is empty)
313
-
314
- ## Complete Example
315
-
316
- Here's a complete example showing how to use `StaticHosting` and `StaticContent` together:
317
-
318
- ```typescript
319
- import { StaticContent, StaticHosting } from '@codedrifters/constructs';
320
- import { App, RemovalPolicy, Stack } from 'aws-cdk-lib';
321
-
322
- const app = new App();
323
-
324
- const env = {
325
- account: '123456789012',
326
- region: 'us-east-1',
327
- };
328
-
329
- const baseDomain = 'example.com';
330
-
331
- /*******************************************************************************
332
- *
333
- * Step 1: Create the hosting infrastructure
334
- *
335
- * This creates the S3 bucket, CloudFront distribution, SSL certificate,
336
- * and DNS records.
337
- *
338
- ******************************************************************************/
339
-
340
- const hostingStack = new Stack(
341
- app,
342
- `static-hosting-dev-${env.account}-${env.region}`,
343
- { env }
344
- );
345
-
346
- const hosting = new StaticHosting(hostingStack, 'static-hosting', {
347
- description: 'My static website',
348
- privateBucketProps: {
349
- removalPolicy: RemovalPolicy.DESTROY,
350
- autoDeleteObjects: true,
351
- },
352
- staticDomainProps: {
353
- baseDomain,
354
- hostedZoneAttributes: {
355
- hostedZoneId: 'Z1234567890ABC',
356
- zoneName: baseDomain,
357
- },
358
- },
359
- });
360
-
361
- /*******************************************************************************
362
- *
363
- * Step 2: Deploy static content
364
- *
365
- * This deploys files from a local directory to the S3 bucket created above.
366
- * The content stack must depend on the hosting stack to ensure the bucket
367
- * exists before deployment.
368
- *
369
- ******************************************************************************/
370
-
371
- const contentStack = new Stack(
372
- app,
373
- `static-content-dev-${env.account}-${env.region}`,
374
- { env }
375
- );
376
-
377
- // Ensure hosting stack is created first
378
- contentStack.node.addDependency(hostingStack);
379
-
380
- new StaticContent(contentStack, 'static-content', {
381
- contentSourceDirectory: 'src/website', // Path to your built website files
382
- contentDestinationDirectory: '/', // Deploy to root
383
- fullDomain: hosting.fullDomain, // Use the domain from StaticHosting
384
- });
385
-
386
- app.synth();
387
- ```
388
-
389
- **Deployment Flow:**
390
-
391
- 1. Deploy the hosting stack first: `cdk deploy static-hosting-dev-*`
392
- 2. This creates the S3 bucket, CloudFront distribution, SSL certificate, and DNS records
393
- 3. Deploy the content stack: `cdk deploy static-content-dev-*`
394
- 4. This uploads your static files to the S3 bucket
395
- 5. Your website is now live at your domain!
396
-
397
- **Branch-Based Deployments:**
398
-
399
- When deploying from different git branches, the `StaticContent` construct automatically uses the branch name as a subdomain prefix. This allows you to have:
400
- - `main` branch → `example.com`
401
- - `feature-123` branch → `feature-123.example.com`
402
- - `pr-456` branch → `pr-456.example.com`
403
-
404
- All using the same S3 bucket and CloudFront distribution!
405
-
406
- ## API Reference
407
-
408
- ### Exports
409
-
410
- The package exports the following:
411
-
412
- **Constructs:**
413
- - `PrivateBucket` - Secure S3 bucket
414
- - `StaticHosting` - Complete static hosting solution
415
- - `StaticContent` - Static content deployment
416
-
417
- ### Type Definitions
418
-
419
- **PrivateBucketProps**
420
- - Extends `BucketProps` from `aws-cdk-lib/aws-s3`
421
- - All standard S3 bucket properties are supported
422
- - Security settings are enforced and cannot be overridden
423
-
424
- **StaticHostingProps**
425
- - Extends `StackProps` from `aws-cdk-lib`
426
- - See [StaticHosting](#statichosting) section for full property list
427
-
428
- **StaticContentProps**
429
- - See [StaticContent](#staticcontent) section for full property list
430
-
431
- **StaticDomainProps**
432
- - `baseDomain: string` - Base domain name
433
- - `hostedZoneAttributes: HostedZoneAttributes` - Route53 hosted zone attributes
434
-
435
- ## Further Documentation
436
-
437
- ### AWS CDK Resources
438
-
439
- - [AWS CDK Developer Guide](https://docs.aws.amazon.com/cdk/v2/guide/home.html) - Comprehensive guide to AWS CDK
440
- - [AWS CDK API Reference](https://docs.aws.amazon.com/cdk/api/v2/) - Complete API documentation
441
- - [AWS CDK Construct Library](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html) - All available constructs
442
-
443
- ### AWS Service Documentation
444
-
445
- - [Amazon S3 Documentation](https://docs.aws.amazon.com/s3/) - S3 service documentation
446
- - [Amazon CloudFront Documentation](https://docs.aws.amazon.com/cloudfront/) - CloudFront CDN documentation
447
- - [AWS Certificate Manager](https://docs.aws.amazon.com/acm/) - SSL/TLS certificate management
448
- - [Amazon Route53](https://docs.aws.amazon.com/route53/) - DNS service documentation
449
-
450
- ### Package Information
451
-
452
- - [NPM Package](https://www.npmjs.com/package/@codedrifters/constructs) - View on NPM
453
- - [GitHub Repository](https://github.com/codedrifters/packages) - Source code
454
-
455
- ---
456
-
457
- **Note:** This package is designed for use with AWS CDK v2. Make sure you're using compatible versions of `aws-cdk-lib` and `constructs`.
7
+ **NPM:** [@codedrifters/constructs](https://www.npmjs.com/package/@codedrifters/constructs)
package/package.json CHANGED
@@ -10,6 +10,7 @@
10
10
  "organization": true
11
11
  },
12
12
  "devDependencies": {
13
+ "@microsoft/api-extractor": "7.58.7",
13
14
  "@types/node": "25.6.0",
14
15
  "@typescript-eslint/eslint-plugin": "^8",
15
16
  "@typescript-eslint/parser": "^8",
@@ -21,9 +22,11 @@
21
22
  "eslint-config-prettier": "^10.1.8",
22
23
  "eslint-import-resolver-typescript": "^4.4.4",
23
24
  "eslint-plugin-import": "^2.32.0",
25
+ "eslint-plugin-jsdoc": "^62.9.0",
24
26
  "eslint-plugin-prettier": "^5.5.5",
27
+ "eslint-plugin-tsdoc": "^0.5.2",
25
28
  "prettier": "^3.8.3",
26
- "rollup": "^4.60.1",
29
+ "rollup": "^4.60.2",
27
30
  "rollup-plugin-dts": "^6.4.1",
28
31
  "tsup": "^8.5.1",
29
32
  "typescript": "^5.9.3",
@@ -42,13 +45,13 @@
42
45
  "devEngines": {
43
46
  "packageManager": {
44
47
  "name": "pnpm",
45
- "version": "10.33.0",
48
+ "version": "10.33.1",
46
49
  "onFail": "ignore"
47
50
  }
48
51
  },
49
52
  "main": "lib/index.js",
50
53
  "license": "MIT",
51
- "version": "0.0.61",
54
+ "version": "0.0.63",
52
55
  "types": "lib/index.d.ts",
53
56
  "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"pnpm exec projen\".",
54
57
  "scripts": {