@vyriy/stack 0.1.9

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vyriy contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # @vyriy/stack
2
+
3
+ AWS CDK stack helpers for Vyriy projects.
4
+
5
+ ## Purpose
6
+
7
+ This package keeps small, reusable CDK construction helpers close to the AWS primitives they wrap. The helpers are intentionally thin: they provide calm defaults for common Vyriy infrastructure while leaving the full CDK prop objects available to callers.
8
+
9
+ ## API
10
+
11
+ - `s3.createBucket(scope, id, props?)` creates a private S3 bucket with static-site-friendly defaults.
12
+ - `cf.createDefaultBehavior(bucket, options?)` creates a CloudFront S3 origin behavior that redirects viewers to HTTPS.
13
+ - `cf.createWebsiteRedirectBehavior(bucket, options?)` creates a CloudFront behavior for an S3 website redirect bucket.
14
+ - `cf.createCloudFrontFunction(scope, id, props)` creates a CloudFront Function from inline JavaScript source.
15
+ - `cf.createDistribution(scope, id, props)` creates a CloudFront distribution.
16
+ - `route53.getHostedZone(scope, id, props)` looks up an existing Route 53 hosted zone.
17
+ - `route53.createARecord(scope, id, props)` creates a Route 53 A record.
18
+ - `route53.createCloudFrontTarget(distribution)` creates a Route 53 alias target for CloudFront.
19
+ - `acm.createCertificate(scope, id, props)` creates an ACM certificate.
20
+ - `deployment.createBucketDeployment(scope, id, props)` deploys files to S3 with a `512` MB default memory limit.
21
+ - `deployment.createImmutableCacheControl(days?)` creates long-lived immutable cache-control headers.
22
+ - `deployment.Source` and `deployment.CacheControl` are re-exported from `aws-cdk-lib/aws-s3-deployment`.
23
+
24
+ ## Static Site Example
25
+
26
+ This example wires the package helpers into a static website stack:
27
+
28
+ - find an existing hosted zone
29
+ - create a private S3 bucket for `vyriy.dev`
30
+ - create a redirect S3 bucket for `www.vyriy.dev`
31
+ - create a DNS-validated ACM certificate
32
+ - create one CloudFront distribution for the main site
33
+ - create one CloudFront distribution for the `www` redirect
34
+ - create Route 53 alias records
35
+ - deploy local site files into the main bucket and invalidate CloudFront
36
+
37
+ CloudFront requires ACM certificates for custom aliases to be in `us-east-1`, so deploy this stack in `us-east-1` or split the certificate into a dedicated us-east-1 stack.
38
+
39
+ ```ts
40
+ import { CfnOutput, Stack, type StackProps } from 'aws-cdk-lib';
41
+ import type { Construct } from 'constructs';
42
+
43
+ import { stack } from '@vyriy/cdk';
44
+ import { acm, cf, deployment, route53, s3 } from '@vyriy/stack';
45
+ import { path } from '@vyriy/path';
46
+
47
+ stack(
48
+ class StaticSiteStack extends Stack {
49
+ constructor(scope: Construct, id: string, props?: StackProps) {
50
+ super(scope, id, props);
51
+
52
+ const domain = 'site.com';
53
+
54
+ const hostedZone = route53.getHostedZone(this, 'HostedZone', {
55
+ domainName: domain,
56
+ });
57
+
58
+ const bucket = s3.createBucket(this, 'Bucket', {
59
+ bucketName: domain,
60
+ });
61
+
62
+ const certificate = acm.createCertificate(this, 'Certificate', {
63
+ domainName: domain,
64
+ subjectAlternativeNames: [`*.${domain}`],
65
+ validation: acm.CertificateValidation.fromDns(hostedZone),
66
+ });
67
+
68
+ const distribution = cf.createDistribution(this, 'Distribution', {
69
+ certificate,
70
+ defaultBehavior: cf.createDefaultBehavior(bucket),
71
+ defaultRootObject: 'index.html',
72
+ domainNames: [domain],
73
+ errorResponses: [
74
+ {
75
+ httpStatus: 403,
76
+ responseHttpStatus: 404,
77
+ responsePagePath: '/404.html',
78
+ },
79
+ {
80
+ httpStatus: 404,
81
+ responseHttpStatus: 404,
82
+ responsePagePath: '/404.html',
83
+ },
84
+ ],
85
+ });
86
+
87
+ route53.createARecord(this, 'RootRecord', {
88
+ target: route53.createCloudFrontTarget(distribution),
89
+ zone: hostedZone,
90
+ });
91
+
92
+ deployment.createBucketDeployment(this, 'DeploySite', {
93
+ cacheControl: deployment.createImmutableCacheControl(),
94
+ destinationBucket: bucket,
95
+ distribution,
96
+ distributionPaths: ['/*'],
97
+ sources: [deployment.Source.asset(path('dist'))],
98
+ });
99
+ }
100
+ },
101
+ );
102
+ ```
@@ -0,0 +1,4 @@
1
+ import { Construct } from 'constructs';
2
+ import { Certificate, CertificateProps, CertificateValidation } from 'aws-cdk-lib/aws-certificatemanager';
3
+ export { CertificateValidation };
4
+ export declare const createCertificate: (scope: Construct, id: string, props: CertificateProps) => Certificate;
@@ -0,0 +1,3 @@
1
+ import { Certificate, CertificateValidation } from 'aws-cdk-lib/aws-certificatemanager';
2
+ export { CertificateValidation };
3
+ export const createCertificate = (scope, id, props) => new Certificate(scope, id, props);
@@ -0,0 +1,42 @@
1
+ import { Construct } from 'constructs';
2
+ import { AddBehaviorOptions, Distribution, DistributionProps, Function as CloudFrontFunction, FunctionEventType, FunctionProps, OriginProtocolPolicy, ViewerProtocolPolicy } from 'aws-cdk-lib/aws-cloudfront';
3
+ import { HttpOrigin } from 'aws-cdk-lib/aws-cloudfront-origins';
4
+ import { Bucket } from 'aws-cdk-lib/aws-s3';
5
+ export { FunctionEventType, OriginProtocolPolicy, ViewerProtocolPolicy };
6
+ export interface CreateCloudFrontFunctionProps extends Omit<FunctionProps, 'code'> {
7
+ readonly code: string;
8
+ }
9
+ export declare const createDistribution: (scope: Construct, id: string, props: DistributionProps) => Distribution;
10
+ export declare const createCloudFrontFunction: (scope: Construct, id: string, props: CreateCloudFrontFunctionProps) => CloudFrontFunction;
11
+ export declare const createDefaultBehavior: (bucket: Bucket, options?: AddBehaviorOptions) => {
12
+ allowedMethods?: import("aws-cdk-lib/aws-cloudfront").AllowedMethods;
13
+ cachedMethods?: import("aws-cdk-lib/aws-cloudfront").CachedMethods;
14
+ cachePolicy?: import("aws-cdk-lib/aws-cloudfront").ICachePolicyRef;
15
+ compress?: boolean;
16
+ originRequestPolicy?: import("aws-cdk-lib/aws-cloudfront").IOriginRequestPolicyRef;
17
+ realtimeLogConfig?: import("aws-cdk-lib/aws-cloudfront").IRealtimeLogConfigRef;
18
+ responseHeadersPolicy?: import("aws-cdk-lib/aws-cloudfront").IResponseHeadersPolicyRef;
19
+ smoothStreaming?: boolean;
20
+ viewerProtocolPolicy: ViewerProtocolPolicy;
21
+ functionAssociations?: import("aws-cdk-lib/aws-cloudfront").FunctionAssociation[];
22
+ edgeLambdas?: import("aws-cdk-lib/aws-cloudfront").EdgeLambda[];
23
+ trustedKeyGroups?: import("aws-cdk-lib/aws-cloudfront").IKeyGroupRef[];
24
+ enableGrpc?: boolean;
25
+ origin: import("aws-cdk-lib/aws-cloudfront").IOrigin;
26
+ };
27
+ export declare const createWebsiteRedirectBehavior: (bucket: Bucket, options?: AddBehaviorOptions) => {
28
+ allowedMethods?: import("aws-cdk-lib/aws-cloudfront").AllowedMethods;
29
+ cachedMethods?: import("aws-cdk-lib/aws-cloudfront").CachedMethods;
30
+ cachePolicy?: import("aws-cdk-lib/aws-cloudfront").ICachePolicyRef;
31
+ compress?: boolean;
32
+ originRequestPolicy?: import("aws-cdk-lib/aws-cloudfront").IOriginRequestPolicyRef;
33
+ realtimeLogConfig?: import("aws-cdk-lib/aws-cloudfront").IRealtimeLogConfigRef;
34
+ responseHeadersPolicy?: import("aws-cdk-lib/aws-cloudfront").IResponseHeadersPolicyRef;
35
+ smoothStreaming?: boolean;
36
+ viewerProtocolPolicy: ViewerProtocolPolicy;
37
+ functionAssociations?: import("aws-cdk-lib/aws-cloudfront").FunctionAssociation[];
38
+ edgeLambdas?: import("aws-cdk-lib/aws-cloudfront").EdgeLambda[];
39
+ trustedKeyGroups?: import("aws-cdk-lib/aws-cloudfront").IKeyGroupRef[];
40
+ enableGrpc?: boolean;
41
+ origin: HttpOrigin;
42
+ };
@@ -0,0 +1,20 @@
1
+ import { Distribution, Function as CloudFrontFunction, FunctionCode, FunctionEventType, OriginProtocolPolicy, ViewerProtocolPolicy, } from 'aws-cdk-lib/aws-cloudfront';
2
+ import { HttpOrigin, S3BucketOrigin } from 'aws-cdk-lib/aws-cloudfront-origins';
3
+ export { FunctionEventType, OriginProtocolPolicy, ViewerProtocolPolicy };
4
+ export const createDistribution = (scope, id, props) => new Distribution(scope, id, props);
5
+ export const createCloudFrontFunction = (scope, id, props) => new CloudFrontFunction(scope, id, {
6
+ ...props,
7
+ code: FunctionCode.fromInline(props.code),
8
+ });
9
+ export const createDefaultBehavior = (bucket, options = {}) => ({
10
+ origin: S3BucketOrigin.withOriginAccessControl(bucket),
11
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
12
+ ...options,
13
+ });
14
+ export const createWebsiteRedirectBehavior = (bucket, options = {}) => ({
15
+ origin: new HttpOrigin(bucket.bucketWebsiteDomainName, {
16
+ protocolPolicy: OriginProtocolPolicy.HTTP_ONLY,
17
+ }),
18
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
19
+ ...options,
20
+ });
@@ -0,0 +1,5 @@
1
+ import { Construct } from 'constructs';
2
+ import { BucketDeployment, BucketDeploymentProps, CacheControl, Source } from 'aws-cdk-lib/aws-s3-deployment';
3
+ export { Source, CacheControl };
4
+ export declare const createBucketDeployment: (scope: Construct, id: string, props: BucketDeploymentProps) => BucketDeployment;
5
+ export declare const createImmutableCacheControl: (days?: number) => CacheControl[];
@@ -0,0 +1,12 @@
1
+ import { Duration } from 'aws-cdk-lib';
2
+ import { BucketDeployment, CacheControl, Source } from 'aws-cdk-lib/aws-s3-deployment';
3
+ export { Source, CacheControl };
4
+ export const createBucketDeployment = (scope, id, props) => new BucketDeployment(scope, id, {
5
+ memoryLimit: 512,
6
+ ...props,
7
+ });
8
+ export const createImmutableCacheControl = (days = 365) => [
9
+ CacheControl.setPublic(),
10
+ CacheControl.maxAge(Duration.days(days)),
11
+ CacheControl.immutable(),
12
+ ];
package/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * as acm from './certificatemanager/index.js';
2
+ export * as cf from './cloudfront/index.js';
3
+ export * as deployment from './deployment/index.js';
4
+ export * as route53 from './route53/index.js';
5
+ export * as s3 from './s3/index.js';
package/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * as acm from './certificatemanager/index.js';
2
+ export * as cf from './cloudfront/index.js';
3
+ export * as deployment from './deployment/index.js';
4
+ export * as route53 from './route53/index.js';
5
+ export * as s3 from './s3/index.js';
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@vyriy/stack",
3
+ "version": "0.1.9",
4
+ "description": "AWS CDK stack helpers for Vyriy infrastructure",
5
+ "type": "module",
6
+ "main": "./index.js",
7
+ "dependencies": {
8
+ "aws-cdk-lib": "^2.253.1",
9
+ "constructs": "^10.6.0"
10
+ },
11
+ "license": "MIT",
12
+ "types": "./index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./index.d.ts",
16
+ "import": "./index.js",
17
+ "default": "./index.js"
18
+ },
19
+ "./certificatemanager/index": {
20
+ "types": "./certificatemanager/index.d.ts",
21
+ "import": "./certificatemanager/index.js",
22
+ "default": "./certificatemanager/index.js"
23
+ },
24
+ "./certificatemanager/index.js": {
25
+ "types": "./certificatemanager/index.d.ts",
26
+ "import": "./certificatemanager/index.js",
27
+ "default": "./certificatemanager/index.js"
28
+ },
29
+ "./cloudfront/index": {
30
+ "types": "./cloudfront/index.d.ts",
31
+ "import": "./cloudfront/index.js",
32
+ "default": "./cloudfront/index.js"
33
+ },
34
+ "./cloudfront/index.js": {
35
+ "types": "./cloudfront/index.d.ts",
36
+ "import": "./cloudfront/index.js",
37
+ "default": "./cloudfront/index.js"
38
+ },
39
+ "./deployment/index": {
40
+ "types": "./deployment/index.d.ts",
41
+ "import": "./deployment/index.js",
42
+ "default": "./deployment/index.js"
43
+ },
44
+ "./deployment/index.js": {
45
+ "types": "./deployment/index.d.ts",
46
+ "import": "./deployment/index.js",
47
+ "default": "./deployment/index.js"
48
+ },
49
+ "./index": {
50
+ "types": "./index.d.ts",
51
+ "import": "./index.js",
52
+ "default": "./index.js"
53
+ },
54
+ "./index.js": {
55
+ "types": "./index.d.ts",
56
+ "import": "./index.js",
57
+ "default": "./index.js"
58
+ },
59
+ "./route53/index": {
60
+ "types": "./route53/index.d.ts",
61
+ "import": "./route53/index.js",
62
+ "default": "./route53/index.js"
63
+ },
64
+ "./route53/index.js": {
65
+ "types": "./route53/index.d.ts",
66
+ "import": "./route53/index.js",
67
+ "default": "./route53/index.js"
68
+ },
69
+ "./s3/index": {
70
+ "types": "./s3/index.d.ts",
71
+ "import": "./s3/index.js",
72
+ "default": "./s3/index.js"
73
+ },
74
+ "./s3/index.js": {
75
+ "types": "./s3/index.d.ts",
76
+ "import": "./s3/index.js",
77
+ "default": "./s3/index.js"
78
+ }
79
+ }
80
+ }
@@ -0,0 +1,7 @@
1
+ import { Construct } from 'constructs';
2
+ import { Distribution } from 'aws-cdk-lib/aws-cloudfront';
3
+ import { HostedZoneProviderProps, ARecord, ARecordProps, RecordTarget } from 'aws-cdk-lib/aws-route53';
4
+ export { RecordTarget };
5
+ export declare const getHostedZone: (scope: Construct, id: string, props: HostedZoneProviderProps) => import("aws-cdk-lib/aws-route53").IHostedZone;
6
+ export declare const createARecord: (scope: Construct, id: string, props: ARecordProps) => ARecord;
7
+ export declare const createCloudFrontTarget: (distribution: Distribution) => RecordTarget;
@@ -0,0 +1,6 @@
1
+ import { HostedZone, ARecord, RecordTarget } from 'aws-cdk-lib/aws-route53';
2
+ import { CloudFrontTarget } from 'aws-cdk-lib/aws-route53-targets';
3
+ export { RecordTarget };
4
+ export const getHostedZone = (scope, id, props) => HostedZone.fromLookup(scope, id, props);
5
+ export const createARecord = (scope, id, props) => new ARecord(scope, id, props);
6
+ export const createCloudFrontTarget = (distribution) => RecordTarget.fromAlias(new CloudFrontTarget(distribution));
package/s3/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { Construct } from 'constructs';
2
+ import { Bucket, BucketProps, RedirectProtocol } from 'aws-cdk-lib/aws-s3';
3
+ export { RedirectProtocol };
4
+ export declare const createBucket: (scope: Construct, id: string, props?: BucketProps) => Bucket;
package/s3/index.js ADDED
@@ -0,0 +1,22 @@
1
+ import { RemovalPolicy } from 'aws-cdk-lib';
2
+ import { BlockPublicAccess, Bucket, HttpMethods, BucketEncryption, RedirectProtocol, } from 'aws-cdk-lib/aws-s3';
3
+ export { RedirectProtocol };
4
+ export const createBucket = (scope, id, props = {}) => {
5
+ const bucketProps = {
6
+ removalPolicy: RemovalPolicy.DESTROY,
7
+ autoDeleteObjects: true,
8
+ versioned: false,
9
+ publicReadAccess: false,
10
+ blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
11
+ cors: [
12
+ {
13
+ allowedMethods: [HttpMethods.GET, HttpMethods.HEAD],
14
+ allowedOrigins: ['*'],
15
+ allowedHeaders: ['*'],
16
+ },
17
+ ],
18
+ encryption: BucketEncryption.S3_MANAGED,
19
+ ...props,
20
+ };
21
+ return new Bucket(scope, id, bucketProps);
22
+ };