website

#astro#js#html#css

git clone https://git.pyrossh.dev/website

木 Personal website of pyrossh. Built with astrojs, shiki, vite.


95c5c12 — pyrossh 2026-05-14T11:25:15+05:30
use cloudflare

Generated files not shown: bun.lock, package-lock.json

.alchemy/prd/git-redirector-prd.json DELETED
@@ -1,49 +0,0 @@
1
- {
2
- "kind": "AWS::CloudFront::Function",
3
- "id": "git-redirector-prd",
4
- "fqn": "prd/git-redirector-prd",
5
- "seq": 4,
6
- "data": {},
7
- "status": "updated",
8
- "output": {
9
- "Symbol(alchemy::ResourceKind)": "AWS::CloudFront::Function",
10
- "Symbol(alchemy::ResourceID)": "git-redirector-prd",
11
- "Symbol(alchemy::ResourceFQN)": "prd/git-redirector-prd",
12
- "Symbol(alchemy::ResourceScope)": {
13
- "@scope": null
14
- },
15
- "Symbol(alchemy::ResourceSeq)": 4,
16
- "typeName": "AWS::CloudFront::Function",
17
- "desiredState": {
18
- "Name": "git_redirector_prd",
19
- "FunctionConfig": {
20
- "Comment": "Git redirector function",
21
- "Runtime": "cloudfront-js-2.0"
22
- },
23
- "FunctionCode": "function handler(event) {\n const request = event.request;\n const uri = request.uri;\n request.uri = \"/\" + request.uri.replace(\"/repos/\", \"\");\n return request;\n }",
24
- "AutoPublish": true
25
- },
26
- "id": "arn:aws:cloudfront::122129753516:function/git_redirector_prd",
27
- "createdAt": 1763310845171,
28
- "FunctionConfig": {
29
- "Comment": "Git redirector function",
30
- "Runtime": "cloudfront-js-2.0"
31
- },
32
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/git_redirector_prd",
33
- "FunctionMetadata": {
34
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/git_redirector_prd"
35
- },
36
- "FunctionCode": "function handler(event) {\n const request = event.request;\n const uri = request.uri;\n request.uri = \"/\" + request.uri.replace(\"/repos/\", \"\");\n return request;\n }",
37
- "Stage": "LIVE",
38
- "Name": "git_redirector_prd"
39
- },
40
- "props": {
41
- "Name": "git_redirector_prd",
42
- "FunctionConfig": {
43
- "Comment": "Git redirector function",
44
- "Runtime": "cloudfront-js-2.0"
45
- },
46
- "FunctionCode": "function handler(event) {\n const request = event.request;\n const uri = request.uri;\n request.uri = \"/\" + request.uri.replace(\"/repos/\", \"\");\n return request;\n }",
47
- "AutoPublish": true
48
- }
49
- }
.alchemy/prd/hosted-zone-prd.json DELETED
@@ -1,74 +0,0 @@
1
- {
2
- "kind": "AWS::Route53::HostedZone",
3
- "id": "hosted-zone-prd",
4
- "fqn": "prd/hosted-zone-prd",
5
- "seq": 0,
6
- "data": {},
7
- "status": "created",
8
- "output": {
9
- "Symbol(alchemy::ResourceKind)": "AWS::Route53::HostedZone",
10
- "Symbol(alchemy::ResourceID)": "hosted-zone-prd",
11
- "Symbol(alchemy::ResourceFQN)": "prd/hosted-zone-prd",
12
- "Symbol(alchemy::ResourceScope)": {
13
- "@scope": null
14
- },
15
- "Symbol(alchemy::ResourceSeq)": 0,
16
- "typeName": "AWS::Route53::HostedZone",
17
- "desiredState": {
18
- "Name": "pyrossh.dev",
19
- "HostedZoneTags": [
20
- {
21
- "Key": "Stage",
22
- "Value": "prd"
23
- },
24
- {
25
- "Key": "ProvisionedBy",
26
- "Value": "Alchemy"
27
- }
28
- ],
29
- "HostedZoneConfig": {
30
- "Comment": "ProvisionedBy Alchemy - prd"
31
- }
32
- },
33
- "id": "Z06277131L62Y66EGXAWH",
34
- "createdAt": 1763311272564,
35
- "HostedZoneTags": [
36
- {
37
- "Value": "Alchemy",
38
- "Key": "ProvisionedBy"
39
- },
40
- {
41
- "Value": "prd",
42
- "Key": "Stage"
43
- }
44
- ],
45
- "VPCs": [],
46
- "HostedZoneConfig": {
47
- "Comment": "ProvisionedBy Alchemy - prd"
48
- },
49
- "Id": "Z06277131L62Y66EGXAWH",
50
- "NameServers": [
51
- "ns-1447.awsdns-52.org",
52
- "ns-1888.awsdns-44.co.uk",
53
- "ns-482.awsdns-60.com",
54
- "ns-1020.awsdns-63.net"
55
- ],
56
- "Name": "pyrossh.dev."
57
- },
58
- "props": {
59
- "Name": "pyrossh.dev",
60
- "HostedZoneTags": [
61
- {
62
- "Key": "Stage",
63
- "Value": "prd"
64
- },
65
- {
66
- "Key": "ProvisionedBy",
67
- "Value": "Alchemy"
68
- }
69
- ],
70
- "HostedZoneConfig": {
71
- "Comment": "ProvisionedBy Alchemy - prd"
72
- }
73
- }
74
- }
.alchemy/prd/html-redirector-prd.json DELETED
@@ -1,49 +0,0 @@
1
- {
2
- "kind": "AWS::CloudFront::Function",
3
- "id": "html-redirector-prd",
4
- "fqn": "prd/html-redirector-prd",
5
- "seq": 3,
6
- "data": {},
7
- "status": "updated",
8
- "output": {
9
- "Symbol(alchemy::ResourceKind)": "AWS::CloudFront::Function",
10
- "Symbol(alchemy::ResourceID)": "html-redirector-prd",
11
- "Symbol(alchemy::ResourceFQN)": "prd/html-redirector-prd",
12
- "Symbol(alchemy::ResourceScope)": {
13
- "@scope": null
14
- },
15
- "Symbol(alchemy::ResourceSeq)": 3,
16
- "typeName": "AWS::CloudFront::Function",
17
- "desiredState": {
18
- "Name": "html_redirector_prd",
19
- "FunctionConfig": {
20
- "Comment": "HTML redirector function",
21
- "Runtime": "cloudfront-js-2.0"
22
- },
23
- "FunctionCode": "function handler(event) {\n const request = event.request;\n const uri = request.uri;\n\n if (uri.endsWith('/')) {\n request.uri += 'index.html';\n } else if (!uri.startsWith('/_astro')) {\n request.uri += '/index.html';\n }\n return request;\n }",
24
- "AutoPublish": true
25
- },
26
- "id": "arn:aws:cloudfront::122129753516:function/html_redirector_prd",
27
- "createdAt": 1763310835436,
28
- "FunctionConfig": {
29
- "Comment": "HTML redirector function",
30
- "Runtime": "cloudfront-js-2.0"
31
- },
32
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/html_redirector_prd",
33
- "FunctionMetadata": {
34
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/html_redirector_prd"
35
- },
36
- "FunctionCode": "function handler(event) {\n const request = event.request;\n const uri = request.uri;\n\n if (uri.endsWith('/')) {\n request.uri += 'index.html';\n } else if (!uri.startsWith('/_astro')) {\n request.uri += '/index.html';\n }\n return request;\n }",
37
- "Stage": "LIVE",
38
- "Name": "html_redirector_prd"
39
- },
40
- "props": {
41
- "Name": "html_redirector_prd",
42
- "FunctionConfig": {
43
- "Comment": "HTML redirector function",
44
- "Runtime": "cloudfront-js-2.0"
45
- },
46
- "FunctionCode": "function handler(event) {\n const request = event.request;\n const uri = request.uri;\n\n if (uri.endsWith('/')) {\n request.uri += 'index.html';\n } else if (!uri.startsWith('/_astro')) {\n request.uri += '/index.html';\n }\n return request;\n }",
47
- "AutoPublish": true
48
- }
49
- }
.alchemy/prd/repos-bucket-policy-prd.json DELETED
@@ -1,90 +0,0 @@
1
- {
2
- "kind": "AWS::S3::BucketPolicy",
3
- "id": "repos-bucket-policy-prd",
4
- "fqn": "prd/repos-bucket-policy-prd",
5
- "seq": 8,
6
- "data": {},
7
- "status": "created",
8
- "output": {
9
- "Symbol(alchemy::ResourceKind)": "AWS::S3::BucketPolicy",
10
- "Symbol(alchemy::ResourceID)": "repos-bucket-policy-prd",
11
- "Symbol(alchemy::ResourceFQN)": "prd/repos-bucket-policy-prd",
12
- "Symbol(alchemy::ResourceScope)": {
13
- "@scope": null
14
- },
15
- "Symbol(alchemy::ResourceSeq)": 8,
16
- "typeName": "AWS::S3::BucketPolicy",
17
- "desiredState": {
18
- "Bucket": "pyrossh-repos-prd",
19
- "PolicyDocument": {
20
- "Version": "2012-10-17",
21
- "Statement": [
22
- {
23
- "Principal": {
24
- "Service": "cloudfront.amazonaws.com"
25
- },
26
- "Action": "s3:GetObject",
27
- "Resource": [
28
- "arn:aws:s3:::pyrossh-repos-prd",
29
- "arn:aws:s3:::pyrossh-repos-prd/*"
30
- ],
31
- "Effect": "Allow",
32
- "Condition": {
33
- "StringEquals": {
34
- "AWS:SourceArn": "arn:aws:cloudfront::122129753516:distribution/E2IM0M1RNCBSHJ"
35
- }
36
- }
37
- }
38
- ]
39
- }
40
- },
41
- "id": "pyrossh-repos-prd",
42
- "createdAt": 1763311899012,
43
- "Bucket": "pyrossh-repos-prd",
44
- "PolicyDocument": {
45
- "Version": "2012-10-17",
46
- "Statement": [
47
- {
48
- "Condition": {
49
- "StringEquals": {
50
- "AWS:SourceArn": "arn:aws:cloudfront::122129753516:distribution/E2IM0M1RNCBSHJ"
51
- }
52
- },
53
- "Action": "s3:GetObject",
54
- "Resource": [
55
- "arn:aws:s3:::pyrossh-repos-prd",
56
- "arn:aws:s3:::pyrossh-repos-prd/*"
57
- ],
58
- "Effect": "Allow",
59
- "Principal": {
60
- "Service": "cloudfront.amazonaws.com"
61
- }
62
- }
63
- ]
64
- }
65
- },
66
- "props": {
67
- "Bucket": "pyrossh-repos-prd",
68
- "PolicyDocument": {
69
- "Version": "2012-10-17",
70
- "Statement": [
71
- {
72
- "Principal": {
73
- "Service": "cloudfront.amazonaws.com"
74
- },
75
- "Action": "s3:GetObject",
76
- "Resource": [
77
- "arn:aws:s3:::pyrossh-repos-prd",
78
- "arn:aws:s3:::pyrossh-repos-prd/*"
79
- ],
80
- "Effect": "Allow",
81
- "Condition": {
82
- "StringEquals": {
83
- "AWS:SourceArn": "arn:aws:cloudfront::122129753516:distribution/E2IM0M1RNCBSHJ"
84
- }
85
- }
86
- }
87
- ]
88
- }
89
- }
90
- }
.alchemy/prd/repos-bucket-prd.json CHANGED
@@ -1,97 +1,36 @@
1
1
  {
2
- "kind": "AWS::S3::Bucket",
2
+ "kind": "cloudflare::R2Bucket",
3
3
  "id": "repos-bucket-prd",
4
4
  "fqn": "prd/repos-bucket-prd",
5
5
  "seq": 1,
6
6
  "data": {},
7
- "status": "created",
7
+ "status": "updated",
8
8
  "output": {
9
- "Symbol(alchemy::ResourceKind)": "AWS::S3::Bucket",
9
+ "Symbol(alchemy::ResourceKind)": "cloudflare::R2Bucket",
10
10
  "Symbol(alchemy::ResourceID)": "repos-bucket-prd",
11
11
  "Symbol(alchemy::ResourceFQN)": "prd/repos-bucket-prd",
12
12
  "Symbol(alchemy::ResourceScope)": {
13
13
  "@scope": null
14
14
  },
15
15
  "Symbol(alchemy::ResourceSeq)": 1,
16
- "typeName": "AWS::S3::Bucket",
17
- "desiredState": {
18
- "BucketName": "pyrossh-repos-prd",
16
+ "name": "pyrossh-repos-prd",
19
- "PublicAccessBlockConfiguration": {
20
- "BlockPublicAcls": true,
21
- "BlockPublicPolicy": true,
22
- "IgnorePublicAcls": true,
23
- "RestrictPublicBuckets": true
24
- },
25
- "Tags": [
26
- {
27
- "Key": "Stage",
28
- "Value": "prd"
17
+ "location": "APAC",
29
- },
30
- {
31
- "Key": "ProvisionedBy",
18
+ "creationDate": {
32
- "Value": "Alchemy"
19
+ "@date": "2026-05-10T11:54:34.872Z"
33
- }
34
- ]
35
20
  },
21
+ "jurisdiction": "default",
22
+ "type": "r2_bucket",
23
+ "accountId": "dfdb8ca4e419990852eb214c5b50bd5e",
24
+ "dev": {
36
- "id": "pyrossh-repos-prd",
25
+ "id": "pyrossh-repos-prd",
37
- "createdAt": 1763310539197,
26
+ "remote": false,
38
- "PublicAccessBlockConfiguration": {
39
- "RestrictPublicBuckets": true,
40
- "BlockPublicPolicy": true,
41
- "BlockPublicAcls": true,
42
- "IgnorePublicAcls": true
27
+ "isDeployed": true
43
- },
44
- "BucketName": "pyrossh-repos-prd",
45
- "RegionalDomainName": "pyrossh-repos-prd.s3.ap-south-1.amazonaws.com",
46
- "OwnershipControls": {
47
- "Rules": [
48
- {
49
- "ObjectOwnership": "BucketOwnerEnforced"
50
- }
28
+ }
51
- ]
52
- },
53
- "DomainName": "pyrossh-repos-prd.s3.amazonaws.com",
54
- "BucketEncryption": {
55
- "ServerSideEncryptionConfiguration": [
56
- {
57
- "BucketKeyEnabled": false,
58
- "ServerSideEncryptionByDefault": {
59
- "SSEAlgorithm": "AES256"
60
- }
61
- }
62
- ]
63
- },
64
- "WebsiteURL": "http://pyrossh-repos-prd.s3-website.ap-south-1.amazonaws.com",
65
- "DualStackDomainName": "pyrossh-repos-prd.s3.dualstack.ap-south-1.amazonaws.com",
66
- "Arn": "arn:aws:s3:::pyrossh-repos-prd",
67
- "Tags": [
68
- {
69
- "Value": "Alchemy",
70
- "Key": "ProvisionedBy"
71
- },
72
- {
73
- "Value": "prd",
74
- "Key": "Stage"
75
- }
76
- ]
77
29
  },
78
30
  "props": {
79
- "BucketName": "pyrossh-repos-prd",
31
+ "name": "pyrossh-repos-prd",
80
- "PublicAccessBlockConfiguration": {
81
- "BlockPublicAcls": true,
82
- "BlockPublicPolicy": true,
83
- "IgnorePublicAcls": true,
84
- "RestrictPublicBuckets": true
85
- },
86
- "Tags": [
32
+ "dev": {
87
- {
88
- "Key": "Stage",
89
- "Value": "prd"
33
+ "force": false
90
- },
91
- {
92
- "Key": "ProvisionedBy",
93
- "Value": "Alchemy"
94
- }
34
+ }
95
- ]
96
35
  }
97
36
  }
.alchemy/prd/rewrite-rules-prd.json ADDED
@@ -0,0 +1,163 @@
1
+ {
2
+ "kind": "cloudflare::Ruleset",
3
+ "id": "rewrite-rules-prd",
4
+ "fqn": "prd/rewrite-rules-prd",
5
+ "seq": 3,
6
+ "data": {},
7
+ "status": "updated",
8
+ "output": {
9
+ "Symbol(alchemy::ResourceKind)": "cloudflare::Ruleset",
10
+ "Symbol(alchemy::ResourceID)": "rewrite-rules-prd",
11
+ "Symbol(alchemy::ResourceFQN)": "prd/rewrite-rules-prd",
12
+ "Symbol(alchemy::ResourceScope)": {
13
+ "@scope": null
14
+ },
15
+ "Symbol(alchemy::ResourceSeq)": 3,
16
+ "id": "9aedcf431d7f4e66b68d6091436fa05c",
17
+ "zoneId": "e95a5d8957b75859c814579deebfce33",
18
+ "phase": "http_request_transform",
19
+ "name": "default",
20
+ "rules": [
21
+ {
22
+ "action": "rewrite",
23
+ "action_parameters": {
24
+ "uri": {
25
+ "path": {
26
+ "expression": "concat(http.request.uri.path, \"index.html\")"
27
+ }
28
+ }
29
+ },
30
+ "description": "Rewrite trailing slash to index.html",
31
+ "enabled": true,
32
+ "expression": "(ends_with(http.request.uri.path, \"/\") and http.host eq \"pyrossh.dev\")",
33
+ "id": "1271eccefbe54f8e9c06b1ad88833710",
34
+ "last_updated": "2026-05-13T14:35:31.641241Z",
35
+ "ref": "1271eccefbe54f8e9c06b1ad88833710",
36
+ "version": "1"
37
+ },
38
+ {
39
+ "action": "rewrite",
40
+ "action_parameters": {
41
+ "uri": {
42
+ "path": {
43
+ "expression": "concat(http.request.uri.path, \"/index.html\")"
44
+ }
45
+ }
46
+ },
47
+ "description": "Rewrite non-file paths to path/index.html",
48
+ "enabled": true,
49
+ "expression": "(not ends_with(http.request.uri.path, \"/\") and not http.request.uri.path contains \".\" and http.host eq \"pyrossh.dev\")",
50
+ "id": "43bfba781cd5484e8ae2eb287dde1acf",
51
+ "last_updated": "2026-05-14T05:52:14.862326Z",
52
+ "ref": "43bfba781cd5484e8ae2eb287dde1acf",
53
+ "version": "1"
54
+ },
55
+ {
56
+ "action": "rewrite",
57
+ "action_parameters": {
58
+ "uri": {
59
+ "path": {
60
+ "expression": "concat(http.request.uri.path, \"/index.html\")"
61
+ }
62
+ }
63
+ },
64
+ "description": "Rewrite /files/ paths with extension to append /index.html",
65
+ "enabled": true,
66
+ "expression": "(http.request.uri.path contains \"/files/\" and http.request.uri.path contains \".\" and not ends_with(http.request.uri.path, \"/\") and http.host eq \"pyrossh.dev\")",
67
+ "id": "e7e715d4b8c64e339a3bb2544ba33f4e",
68
+ "last_updated": "2026-05-14T05:53:27.98801Z",
69
+ "ref": "e7e715d4b8c64e339a3bb2544ba33f4e",
70
+ "version": "1"
71
+ }
72
+ ],
73
+ "lastUpdated": "2026-05-14T05:53:27.98801Z",
74
+ "version": "9"
75
+ },
76
+ "props": {
77
+ "zone": {
78
+ "Symbol(alchemy::ResourceKind)": "cloudflare::Zone",
79
+ "Symbol(alchemy::ResourceID)": "zone-prd",
80
+ "Symbol(alchemy::ResourceFQN)": "prd/zone-prd",
81
+ "Symbol(alchemy::ResourceScope)": {
82
+ "@scope": null
83
+ },
84
+ "Symbol(alchemy::ResourceSeq)": 0,
85
+ "id": "e95a5d8957b75859c814579deebfce33",
86
+ "name": "pyrossh.dev",
87
+ "type": "full",
88
+ "status": "pending",
89
+ "paused": false,
90
+ "accountId": "dfdb8ca4e419990852eb214c5b50bd5e",
91
+ "nameservers": [
92
+ "glen.ns.cloudflare.com",
93
+ "riya.ns.cloudflare.com"
94
+ ],
95
+ "originalNameservers": [
96
+ "ns-1020.awsdns-63.net",
97
+ "ns-1447.awsdns-52.org",
98
+ "ns-1888.awsdns-44.co.uk",
99
+ "ns-482.awsdns-60.com"
100
+ ],
101
+ "createdAt": 1778414069223,
102
+ "modifiedAt": 1778414069223,
103
+ "activatedAt": null,
104
+ "settings": {
105
+ "ssl": "strict",
106
+ "alwaysUseHttps": "on",
107
+ "automaticHttpsRewrites": "on",
108
+ "tls13": "on",
109
+ "earlyHints": "off",
110
+ "emailObfuscation": "on",
111
+ "browserCacheTtl": 14400,
112
+ "developmentMode": "off",
113
+ "http2": "on",
114
+ "http3": "on",
115
+ "ipv6": "on",
116
+ "websockets": "on",
117
+ "zeroRtt": "off",
118
+ "brotli": "on",
119
+ "hotlinkProtection": "off",
120
+ "minTlsVersion": "1.2"
121
+ }
122
+ },
123
+ "phase": "http_request_transform",
124
+ "rules": [
125
+ {
126
+ "description": "Rewrite trailing slash to index.html",
127
+ "expression": "(ends_with(http.request.uri.path, \"/\") and http.host eq \"pyrossh.dev\")",
128
+ "action": "rewrite",
129
+ "action_parameters": {
130
+ "uri": {
131
+ "path": {
132
+ "expression": "concat(http.request.uri.path, \"index.html\")"
133
+ }
134
+ }
135
+ }
136
+ },
137
+ {
138
+ "description": "Rewrite non-file paths to path/index.html",
139
+ "expression": "(not ends_with(http.request.uri.path, \"/\") and not http.request.uri.path contains \".\" and http.host eq \"pyrossh.dev\")",
140
+ "action": "rewrite",
141
+ "action_parameters": {
142
+ "uri": {
143
+ "path": {
144
+ "expression": "concat(http.request.uri.path, \"/index.html\")"
145
+ }
146
+ }
147
+ }
148
+ },
149
+ {
150
+ "description": "Rewrite /files/ paths with extension to append /index.html",
151
+ "expression": "(http.request.uri.path contains \"/files/\" and http.request.uri.path contains \".\" and not ends_with(http.request.uri.path, \"/\") and http.host eq \"pyrossh.dev\")",
152
+ "action": "rewrite",
153
+ "action_parameters": {
154
+ "uri": {
155
+ "path": {
156
+ "expression": "concat(http.request.uri.path, \"/index.html\")"
157
+ }
158
+ }
159
+ }
160
+ }
161
+ ]
162
+ }
163
+ }
.alchemy/prd/s3-distribution-prd.json DELETED
@@ -1,665 +0,0 @@
1
- {
2
- "kind": "AWS::CloudFront::Distribution",
3
- "id": "s3-distribution-prd",
4
- "fqn": "prd/s3-distribution-prd",
5
- "seq": 6,
6
- "data": {},
7
- "status": "updated",
8
- "output": {
9
- "Symbol(alchemy::ResourceKind)": "AWS::CloudFront::Distribution",
10
- "Symbol(alchemy::ResourceID)": "s3-distribution-prd",
11
- "Symbol(alchemy::ResourceFQN)": "prd/s3-distribution-prd",
12
- "Symbol(alchemy::ResourceScope)": {
13
- "@scope": null
14
- },
15
- "Symbol(alchemy::ResourceSeq)": 6,
16
- "typeName": "AWS::CloudFront::Distribution",
17
- "desiredState": {
18
- "Tags": [
19
- {
20
- "Key": "Stage",
21
- "Value": "prd"
22
- },
23
- {
24
- "Key": "ProvisionedBy",
25
- "Value": "Alchemy"
26
- }
27
- ],
28
- "DistributionConfig": {
29
- "Origins": [
30
- {
31
- "DomainName": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com",
32
- "Id": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com",
33
- "OriginAccessControlId": "E92NHWMY2XEI1",
34
- "S3OriginConfig": {
35
- "OriginAccessIdentity": ""
36
- }
37
- },
38
- {
39
- "DomainName": "pyrossh-repos-prd.s3.ap-south-1.amazonaws.com",
40
- "Id": "pyrossh-repos-prd.s3.ap-south-1.amazonaws.com",
41
- "OriginAccessControlId": "E92NHWMY2XEI1",
42
- "S3OriginConfig": {
43
- "OriginAccessIdentity": ""
44
- }
45
- }
46
- ],
47
- "Enabled": true,
48
- "IPV6Enabled": true,
49
- "Aliases": [
50
- "pyrossh.dev"
51
- ],
52
- "DefaultRootObject": "index.html",
53
- "CustomErrorResponses": [
54
- {
55
- "ErrorCode": 400,
56
- "ResponseCode": 400,
57
- "ResponsePagePath": "/404.html"
58
- },
59
- {
60
- "ErrorCode": 403,
61
- "ResponseCode": 403,
62
- "ResponsePagePath": "/404.html"
63
- },
64
- {
65
- "ErrorCode": 404,
66
- "ResponseCode": 404,
67
- "ResponsePagePath": "/404.html"
68
- },
69
- {
70
- "ErrorCode": 405,
71
- "ResponseCode": 405,
72
- "ResponsePagePath": "/404.html"
73
- },
74
- {
75
- "ErrorCode": 414,
76
- "ResponseCode": 414,
77
- "ResponsePagePath": "/404.html"
78
- },
79
- {
80
- "ErrorCode": 416,
81
- "ResponseCode": 416,
82
- "ResponsePagePath": "/404.html"
83
- },
84
- {
85
- "ErrorCode": 500,
86
- "ResponseCode": 500,
87
- "ResponsePagePath": "/500.html"
88
- },
89
- {
90
- "ErrorCode": 501,
91
- "ResponseCode": 501,
92
- "ResponsePagePath": "/500.html"
93
- },
94
- {
95
- "ErrorCode": 502,
96
- "ResponseCode": 502,
97
- "ResponsePagePath": "/500.html"
98
- },
99
- {
100
- "ErrorCode": 503,
101
- "ResponseCode": 503,
102
- "ResponsePagePath": "/500.html"
103
- },
104
- {
105
- "ErrorCode": 504,
106
- "ResponseCode": 504,
107
- "ResponsePagePath": "/500.html"
108
- }
109
- ],
110
- "CacheBehaviors": [
111
- {
112
- "PathPattern": "/repos/*.git/*",
113
- "AllowedMethods": [
114
- "GET",
115
- "HEAD"
116
- ],
117
- "CachedMethods": [
118
- "GET",
119
- "HEAD"
120
- ],
121
- "TargetOriginId": "pyrossh-repos-prd.s3.ap-south-1.amazonaws.com",
122
- "ForwardedValues": {
123
- "QueryString": false,
124
- "Cookies": {
125
- "Forward": "none"
126
- }
127
- },
128
- "MinTTL": 0,
129
- "DefaultTTL": 86400,
130
- "MaxTTL": 31536000,
131
- "Compress": true,
132
- "ViewerProtocolPolicy": "redirect-to-https",
133
- "FunctionAssociations": [
134
- {
135
- "EventType": "viewer-request",
136
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/git_redirector_prd"
137
- }
138
- ]
139
- },
140
- {
141
- "PathPattern": "/*",
142
- "AllowedMethods": [
143
- "GET",
144
- "HEAD"
145
- ],
146
- "CachedMethods": [
147
- "GET",
148
- "HEAD"
149
- ],
150
- "TargetOriginId": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com",
151
- "ForwardedValues": {
152
- "QueryString": true,
153
- "Cookies": {
154
- "Forward": "none"
155
- }
156
- },
157
- "ViewerProtocolPolicy": "redirect-to-https",
158
- "MinTTL": 0,
159
- "DefaultTTL": 3600,
160
- "MaxTTL": 86400,
161
- "FunctionAssociations": [
162
- {
163
- "EventType": "viewer-request",
164
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/html_redirector_prd"
165
- }
166
- ]
167
- }
168
- ],
169
- "DefaultCacheBehavior": {
170
- "AllowedMethods": [
171
- "GET",
172
- "HEAD"
173
- ],
174
- "CachedMethods": [
175
- "GET",
176
- "HEAD"
177
- ],
178
- "TargetOriginId": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com",
179
- "ForwardedValues": {
180
- "QueryString": true,
181
- "Cookies": {
182
- "Forward": "none"
183
- }
184
- },
185
- "ViewerProtocolPolicy": "redirect-to-https",
186
- "MinTTL": 0,
187
- "DefaultTTL": 3600,
188
- "MaxTTL": 86400,
189
- "FunctionAssociations": [
190
- {
191
- "EventType": "viewer-request",
192
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/html_redirector_prd"
193
- }
194
- ]
195
- },
196
- "PriceClass": "PriceClass_All",
197
- "Restrictions": {
198
- "GeoRestriction": {
199
- "RestrictionType": "none"
200
- }
201
- },
202
- "ViewerCertificate": {
203
- "MinimumProtocolVersion": "TLSv1.2_2021",
204
- "CloudFrontDefaultCertificate": false,
205
- "SslSupportMethod": "sni-only",
206
- "AcmCertificateArn": "arn:aws:acm:us-east-1:122129753516:certificate/d04cd0a5-623c-4d18-a9d1-f0d8df3e999d"
207
- },
208
- "Comment": "ProvisionedBy Alchemy - prd"
209
- }
210
- },
211
- "id": "E2IM0M1RNCBSHJ",
212
- "createdAt": 1764175362829,
213
- "DistributionConfig": {
214
- "Logging": {
215
- "IncludeCookies": false,
216
- "Bucket": "",
217
- "Prefix": ""
218
- },
219
- "Comment": "ProvisionedBy Alchemy - prd",
220
- "DefaultRootObject": "index.html",
221
- "Origins": [
222
- {
223
- "ConnectionTimeout": 10,
224
- "OriginAccessControlId": "E92NHWMY2XEI1",
225
- "ConnectionAttempts": 3,
226
- "OriginCustomHeaders": [],
227
- "DomainName": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com",
228
- "OriginShield": {
229
- "Enabled": false
230
- },
231
- "S3OriginConfig": {
232
- "OriginReadTimeout": 30,
233
- "OriginAccessIdentity": ""
234
- },
235
- "OriginPath": "",
236
- "Id": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com"
237
- },
238
- {
239
- "ConnectionTimeout": 10,
240
- "OriginAccessControlId": "E92NHWMY2XEI1",
241
- "ConnectionAttempts": 3,
242
- "OriginCustomHeaders": [],
243
- "DomainName": "pyrossh-repos-prd.s3.ap-south-1.amazonaws.com",
244
- "OriginShield": {
245
- "Enabled": false
246
- },
247
- "S3OriginConfig": {
248
- "OriginReadTimeout": 30,
249
- "OriginAccessIdentity": ""
250
- },
251
- "OriginPath": "",
252
- "Id": "pyrossh-repos-prd.s3.ap-south-1.amazonaws.com"
253
- }
254
- ],
255
- "ViewerCertificate": {
256
- "SslSupportMethod": "sni-only",
257
- "MinimumProtocolVersion": "TLSv1.2_2021",
258
- "CloudFrontDefaultCertificate": false,
259
- "AcmCertificateArn": "arn:aws:acm:us-east-1:122129753516:certificate/d04cd0a5-623c-4d18-a9d1-f0d8df3e999d"
260
- },
261
- "PriceClass": "PriceClass_All",
262
- "DefaultCacheBehavior": {
263
- "Compress": false,
264
- "FunctionAssociations": [
265
- {
266
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/html_redirector_prd",
267
- "EventType": "viewer-request"
268
- }
269
- ],
270
- "LambdaFunctionAssociations": [],
271
- "TargetOriginId": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com",
272
- "ViewerProtocolPolicy": "redirect-to-https",
273
- "GrpcConfig": {
274
- "Enabled": false
275
- },
276
- "TrustedSigners": [],
277
- "DefaultTTL": 3600,
278
- "FieldLevelEncryptionId": "",
279
- "TrustedKeyGroups": [],
280
- "AllowedMethods": [
281
- "HEAD",
282
- "GET"
283
- ],
284
- "CachedMethods": [
285
- "HEAD",
286
- "GET"
287
- ],
288
- "SmoothStreaming": false,
289
- "ForwardedValues": {
290
- "Cookies": {
291
- "Forward": "none"
292
- },
293
- "Headers": [],
294
- "QueryString": true,
295
- "QueryStringCacheKeys": []
296
- },
297
- "MinTTL": 0,
298
- "MaxTTL": 86400
299
- },
300
- "Staging": false,
301
- "CustomErrorResponses": [
302
- {
303
- "ResponseCode": 400,
304
- "ErrorCachingMinTTL": 300,
305
- "ErrorCode": 400,
306
- "ResponsePagePath": "/404.html"
307
- },
308
- {
309
- "ResponseCode": 403,
310
- "ErrorCachingMinTTL": 300,
311
- "ErrorCode": 403,
312
- "ResponsePagePath": "/404.html"
313
- },
314
- {
315
- "ResponseCode": 404,
316
- "ErrorCachingMinTTL": 300,
317
- "ErrorCode": 404,
318
- "ResponsePagePath": "/404.html"
319
- },
320
- {
321
- "ResponseCode": 405,
322
- "ErrorCachingMinTTL": 300,
323
- "ErrorCode": 405,
324
- "ResponsePagePath": "/404.html"
325
- },
326
- {
327
- "ResponseCode": 414,
328
- "ErrorCachingMinTTL": 300,
329
- "ErrorCode": 414,
330
- "ResponsePagePath": "/404.html"
331
- },
332
- {
333
- "ResponseCode": 416,
334
- "ErrorCachingMinTTL": 300,
335
- "ErrorCode": 416,
336
- "ResponsePagePath": "/404.html"
337
- },
338
- {
339
- "ResponseCode": 500,
340
- "ErrorCachingMinTTL": 300,
341
- "ErrorCode": 500,
342
- "ResponsePagePath": "/500.html"
343
- },
344
- {
345
- "ResponseCode": 501,
346
- "ErrorCachingMinTTL": 300,
347
- "ErrorCode": 501,
348
- "ResponsePagePath": "/500.html"
349
- },
350
- {
351
- "ResponseCode": 502,
352
- "ErrorCachingMinTTL": 300,
353
- "ErrorCode": 502,
354
- "ResponsePagePath": "/500.html"
355
- },
356
- {
357
- "ResponseCode": 503,
358
- "ErrorCachingMinTTL": 300,
359
- "ErrorCode": 503,
360
- "ResponsePagePath": "/500.html"
361
- },
362
- {
363
- "ResponseCode": 504,
364
- "ErrorCachingMinTTL": 300,
365
- "ErrorCode": 504,
366
- "ResponsePagePath": "/500.html"
367
- }
368
- ],
369
- "ContinuousDeploymentPolicyId": "",
370
- "OriginGroups": {
371
- "Quantity": 0,
372
- "Items": []
373
- },
374
- "Enabled": true,
375
- "Aliases": [
376
- "pyrossh.dev"
377
- ],
378
- "IPV6Enabled": true,
379
- "WebACLId": "",
380
- "HttpVersion": "http1.1",
381
- "Restrictions": {
382
- "GeoRestriction": {
383
- "Locations": [],
384
- "RestrictionType": "none"
385
- }
386
- },
387
- "CacheBehaviors": [
388
- {
389
- "Compress": true,
390
- "FunctionAssociations": [
391
- {
392
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/git_redirector_prd",
393
- "EventType": "viewer-request"
394
- }
395
- ],
396
- "LambdaFunctionAssociations": [],
397
- "TargetOriginId": "pyrossh-repos-prd.s3.ap-south-1.amazonaws.com",
398
- "ViewerProtocolPolicy": "redirect-to-https",
399
- "GrpcConfig": {
400
- "Enabled": false
401
- },
402
- "TrustedSigners": [],
403
- "DefaultTTL": 86400,
404
- "FieldLevelEncryptionId": "",
405
- "TrustedKeyGroups": [],
406
- "AllowedMethods": [
407
- "HEAD",
408
- "GET"
409
- ],
410
- "PathPattern": "/repos/*.git/*",
411
- "CachedMethods": [
412
- "HEAD",
413
- "GET"
414
- ],
415
- "SmoothStreaming": false,
416
- "ForwardedValues": {
417
- "Cookies": {
418
- "Forward": "none"
419
- },
420
- "Headers": [],
421
- "QueryString": false,
422
- "QueryStringCacheKeys": []
423
- },
424
- "MinTTL": 0,
425
- "MaxTTL": 31536000
426
- },
427
- {
428
- "Compress": false,
429
- "FunctionAssociations": [
430
- {
431
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/html_redirector_prd",
432
- "EventType": "viewer-request"
433
- }
434
- ],
435
- "LambdaFunctionAssociations": [],
436
- "TargetOriginId": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com",
437
- "ViewerProtocolPolicy": "redirect-to-https",
438
- "GrpcConfig": {
439
- "Enabled": false
440
- },
441
- "TrustedSigners": [],
442
- "DefaultTTL": 3600,
443
- "FieldLevelEncryptionId": "",
444
- "TrustedKeyGroups": [],
445
- "AllowedMethods": [
446
- "HEAD",
447
- "GET"
448
- ],
449
- "PathPattern": "/*",
450
- "CachedMethods": [
451
- "HEAD",
452
- "GET"
453
- ],
454
- "SmoothStreaming": false,
455
- "ForwardedValues": {
456
- "Cookies": {
457
- "Forward": "none"
458
- },
459
- "Headers": [],
460
- "QueryString": true,
461
- "QueryStringCacheKeys": []
462
- },
463
- "MinTTL": 0,
464
- "MaxTTL": 86400
465
- }
466
- ]
467
- },
468
- "DomainName": "dydxeqxbrvlcu.cloudfront.net",
469
- "Id": "E2IM0M1RNCBSHJ"
470
- },
471
- "props": {
472
- "Tags": [
473
- {
474
- "Key": "Stage",
475
- "Value": "prd"
476
- },
477
- {
478
- "Key": "ProvisionedBy",
479
- "Value": "Alchemy"
480
- }
481
- ],
482
- "DistributionConfig": {
483
- "Origins": [
484
- {
485
- "DomainName": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com",
486
- "Id": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com",
487
- "OriginAccessControlId": "E92NHWMY2XEI1",
488
- "S3OriginConfig": {
489
- "OriginAccessIdentity": ""
490
- }
491
- },
492
- {
493
- "DomainName": "pyrossh-repos-prd.s3.ap-south-1.amazonaws.com",
494
- "Id": "pyrossh-repos-prd.s3.ap-south-1.amazonaws.com",
495
- "OriginAccessControlId": "E92NHWMY2XEI1",
496
- "S3OriginConfig": {
497
- "OriginAccessIdentity": ""
498
- }
499
- }
500
- ],
501
- "Enabled": true,
502
- "IPV6Enabled": true,
503
- "Aliases": [
504
- "pyrossh.dev"
505
- ],
506
- "DefaultRootObject": "index.html",
507
- "CustomErrorResponses": [
508
- {
509
- "ErrorCode": 400,
510
- "ResponseCode": 400,
511
- "ResponsePagePath": "/404.html"
512
- },
513
- {
514
- "ErrorCode": 403,
515
- "ResponseCode": 403,
516
- "ResponsePagePath": "/404.html"
517
- },
518
- {
519
- "ErrorCode": 404,
520
- "ResponseCode": 404,
521
- "ResponsePagePath": "/404.html"
522
- },
523
- {
524
- "ErrorCode": 405,
525
- "ResponseCode": 405,
526
- "ResponsePagePath": "/404.html"
527
- },
528
- {
529
- "ErrorCode": 414,
530
- "ResponseCode": 414,
531
- "ResponsePagePath": "/404.html"
532
- },
533
- {
534
- "ErrorCode": 416,
535
- "ResponseCode": 416,
536
- "ResponsePagePath": "/404.html"
537
- },
538
- {
539
- "ErrorCode": 500,
540
- "ResponseCode": 500,
541
- "ResponsePagePath": "/500.html"
542
- },
543
- {
544
- "ErrorCode": 501,
545
- "ResponseCode": 501,
546
- "ResponsePagePath": "/500.html"
547
- },
548
- {
549
- "ErrorCode": 502,
550
- "ResponseCode": 502,
551
- "ResponsePagePath": "/500.html"
552
- },
553
- {
554
- "ErrorCode": 503,
555
- "ResponseCode": 503,
556
- "ResponsePagePath": "/500.html"
557
- },
558
- {
559
- "ErrorCode": 504,
560
- "ResponseCode": 504,
561
- "ResponsePagePath": "/500.html"
562
- }
563
- ],
564
- "CacheBehaviors": [
565
- {
566
- "PathPattern": "/repos/*.git/*",
567
- "AllowedMethods": [
568
- "GET",
569
- "HEAD"
570
- ],
571
- "CachedMethods": [
572
- "GET",
573
- "HEAD"
574
- ],
575
- "TargetOriginId": "pyrossh-repos-prd.s3.ap-south-1.amazonaws.com",
576
- "ForwardedValues": {
577
- "QueryString": false,
578
- "Cookies": {
579
- "Forward": "none"
580
- }
581
- },
582
- "MinTTL": 0,
583
- "DefaultTTL": 86400,
584
- "MaxTTL": 31536000,
585
- "Compress": true,
586
- "ViewerProtocolPolicy": "redirect-to-https",
587
- "FunctionAssociations": [
588
- {
589
- "EventType": "viewer-request",
590
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/git_redirector_prd"
591
- }
592
- ]
593
- },
594
- {
595
- "PathPattern": "/*",
596
- "AllowedMethods": [
597
- "GET",
598
- "HEAD"
599
- ],
600
- "CachedMethods": [
601
- "GET",
602
- "HEAD"
603
- ],
604
- "TargetOriginId": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com",
605
- "ForwardedValues": {
606
- "QueryString": true,
607
- "Cookies": {
608
- "Forward": "none"
609
- }
610
- },
611
- "ViewerProtocolPolicy": "redirect-to-https",
612
- "MinTTL": 0,
613
- "DefaultTTL": 3600,
614
- "MaxTTL": 86400,
615
- "FunctionAssociations": [
616
- {
617
- "EventType": "viewer-request",
618
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/html_redirector_prd"
619
- }
620
- ]
621
- }
622
- ],
623
- "DefaultCacheBehavior": {
624
- "AllowedMethods": [
625
- "GET",
626
- "HEAD"
627
- ],
628
- "CachedMethods": [
629
- "GET",
630
- "HEAD"
631
- ],
632
- "TargetOriginId": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com",
633
- "ForwardedValues": {
634
- "QueryString": true,
635
- "Cookies": {
636
- "Forward": "none"
637
- }
638
- },
639
- "ViewerProtocolPolicy": "redirect-to-https",
640
- "MinTTL": 0,
641
- "DefaultTTL": 3600,
642
- "MaxTTL": 86400,
643
- "FunctionAssociations": [
644
- {
645
- "EventType": "viewer-request",
646
- "FunctionARN": "arn:aws:cloudfront::122129753516:function/html_redirector_prd"
647
- }
648
- ]
649
- },
650
- "PriceClass": "PriceClass_All",
651
- "Restrictions": {
652
- "GeoRestriction": {
653
- "RestrictionType": "none"
654
- }
655
- },
656
- "ViewerCertificate": {
657
- "MinimumProtocolVersion": "TLSv1.2_2021",
658
- "CloudFrontDefaultCertificate": false,
659
- "SslSupportMethod": "sni-only",
660
- "AcmCertificateArn": "arn:aws:acm:us-east-1:122129753516:certificate/d04cd0a5-623c-4d18-a9d1-f0d8df3e999d"
661
- },
662
- "Comment": "ProvisionedBy Alchemy - prd"
663
- }
664
- }
665
- }
.alchemy/prd/s3-oac-prd.json DELETED
@@ -1,44 +0,0 @@
1
- {
2
- "kind": "AWS::CloudFront::OriginAccessControl",
3
- "id": "s3-oac-prd",
4
- "fqn": "prd/s3-oac-prd",
5
- "seq": 3,
6
- "data": {},
7
- "status": "created",
8
- "output": {
9
- "Symbol(alchemy::ResourceKind)": "AWS::CloudFront::OriginAccessControl",
10
- "Symbol(alchemy::ResourceID)": "s3-oac-prd",
11
- "Symbol(alchemy::ResourceFQN)": "prd/s3-oac-prd",
12
- "Symbol(alchemy::ResourceScope)": {
13
- "@scope": null
14
- },
15
- "Symbol(alchemy::ResourceSeq)": 3,
16
- "typeName": "AWS::CloudFront::OriginAccessControl",
17
- "desiredState": {
18
- "OriginAccessControlConfig": {
19
- "Name": "s3-oac-prd",
20
- "OriginAccessControlOriginType": "s3",
21
- "SigningBehavior": "always",
22
- "SigningProtocol": "sigv4"
23
- }
24
- },
25
- "id": "E92NHWMY2XEI1",
26
- "createdAt": 1763311203616,
27
- "OriginAccessControlConfig": {
28
- "SigningBehavior": "always",
29
- "Description": "",
30
- "OriginAccessControlOriginType": "s3",
31
- "SigningProtocol": "sigv4",
32
- "Name": "s3-oac-prd"
33
- },
34
- "Id": "E92NHWMY2XEI1"
35
- },
36
- "props": {
37
- "OriginAccessControlConfig": {
38
- "Name": "s3-oac-prd",
39
- "OriginAccessControlOriginType": "s3",
40
- "SigningBehavior": "always",
41
- "SigningProtocol": "sigv4"
42
- }
43
- }
44
- }
.alchemy/prd/website-bucket-policy-prd.json DELETED
@@ -1,90 +0,0 @@
1
- {
2
- "kind": "AWS::S3::BucketPolicy",
3
- "id": "website-bucket-policy-prd",
4
- "fqn": "prd/website-bucket-policy-prd",
5
- "seq": 7,
6
- "data": {},
7
- "status": "created",
8
- "output": {
9
- "Symbol(alchemy::ResourceKind)": "AWS::S3::BucketPolicy",
10
- "Symbol(alchemy::ResourceID)": "website-bucket-policy-prd",
11
- "Symbol(alchemy::ResourceFQN)": "prd/website-bucket-policy-prd",
12
- "Symbol(alchemy::ResourceScope)": {
13
- "@scope": null
14
- },
15
- "Symbol(alchemy::ResourceSeq)": 7,
16
- "typeName": "AWS::S3::BucketPolicy",
17
- "desiredState": {
18
- "Bucket": "pyrossh-website-prd",
19
- "PolicyDocument": {
20
- "Version": "2012-10-17",
21
- "Statement": [
22
- {
23
- "Principal": {
24
- "Service": "cloudfront.amazonaws.com"
25
- },
26
- "Action": "s3:GetObject",
27
- "Resource": [
28
- "arn:aws:s3:::pyrossh-website-prd",
29
- "arn:aws:s3:::pyrossh-website-prd/*"
30
- ],
31
- "Effect": "Allow",
32
- "Condition": {
33
- "StringEquals": {
34
- "AWS:SourceArn": "arn:aws:cloudfront::122129753516:distribution/E2IM0M1RNCBSHJ"
35
- }
36
- }
37
- }
38
- ]
39
- }
40
- },
41
- "id": "pyrossh-website-prd",
42
- "createdAt": 1763311897729,
43
- "Bucket": "pyrossh-website-prd",
44
- "PolicyDocument": {
45
- "Version": "2012-10-17",
46
- "Statement": [
47
- {
48
- "Condition": {
49
- "StringEquals": {
50
- "AWS:SourceArn": "arn:aws:cloudfront::122129753516:distribution/E2IM0M1RNCBSHJ"
51
- }
52
- },
53
- "Action": "s3:GetObject",
54
- "Resource": [
55
- "arn:aws:s3:::pyrossh-website-prd",
56
- "arn:aws:s3:::pyrossh-website-prd/*"
57
- ],
58
- "Effect": "Allow",
59
- "Principal": {
60
- "Service": "cloudfront.amazonaws.com"
61
- }
62
- }
63
- ]
64
- }
65
- },
66
- "props": {
67
- "Bucket": "pyrossh-website-prd",
68
- "PolicyDocument": {
69
- "Version": "2012-10-17",
70
- "Statement": [
71
- {
72
- "Principal": {
73
- "Service": "cloudfront.amazonaws.com"
74
- },
75
- "Action": "s3:GetObject",
76
- "Resource": [
77
- "arn:aws:s3:::pyrossh-website-prd",
78
- "arn:aws:s3:::pyrossh-website-prd/*"
79
- ],
80
- "Effect": "Allow",
81
- "Condition": {
82
- "StringEquals": {
83
- "AWS:SourceArn": "arn:aws:cloudfront::122129753516:distribution/E2IM0M1RNCBSHJ"
84
- }
85
- }
86
- }
87
- ]
88
- }
89
- }
90
- }
.alchemy/prd/website-bucket-prd.json CHANGED
@@ -1,97 +1,42 @@
1
1
  {
2
- "kind": "AWS::S3::Bucket",
2
+ "kind": "cloudflare::R2Bucket",
3
3
  "id": "website-bucket-prd",
4
4
  "fqn": "prd/website-bucket-prd",
5
- "seq": 0,
5
+ "seq": 1,
6
6
  "data": {},
7
- "status": "created",
7
+ "status": "updated",
8
8
  "output": {
9
- "Symbol(alchemy::ResourceKind)": "AWS::S3::Bucket",
9
+ "Symbol(alchemy::ResourceKind)": "cloudflare::R2Bucket",
10
10
  "Symbol(alchemy::ResourceID)": "website-bucket-prd",
11
11
  "Symbol(alchemy::ResourceFQN)": "prd/website-bucket-prd",
12
12
  "Symbol(alchemy::ResourceScope)": {
13
13
  "@scope": null
14
14
  },
15
- "Symbol(alchemy::ResourceSeq)": 0,
15
+ "Symbol(alchemy::ResourceSeq)": 1,
16
- "typeName": "AWS::S3::Bucket",
17
- "desiredState": {
18
- "BucketName": "pyrossh-website-prd",
16
+ "name": "pyrossh-website-prd",
19
- "PublicAccessBlockConfiguration": {
20
- "BlockPublicAcls": true,
21
- "BlockPublicPolicy": true,
22
- "IgnorePublicAcls": true,
23
- "RestrictPublicBuckets": true
24
- },
25
- "Tags": [
26
- {
27
- "Key": "Stage",
28
- "Value": "prd"
17
+ "location": "APAC",
29
- },
30
- {
31
- "Key": "ProvisionedBy",
18
+ "creationDate": {
32
- "Value": "Alchemy"
19
+ "@date": "2026-05-13T13:52:35.852Z"
33
- }
34
- ]
35
20
  },
21
+ "jurisdiction": "default",
22
+ "type": "r2_bucket",
23
+ "accountId": "dfdb8ca4e419990852eb214c5b50bd5e",
24
+ "dev": {
36
- "id": "pyrossh-website-prd",
25
+ "id": "pyrossh-website-prd",
37
- "createdAt": 1763310525642,
26
+ "remote": false,
38
- "PublicAccessBlockConfiguration": {
39
- "RestrictPublicBuckets": true,
40
- "BlockPublicPolicy": true,
41
- "BlockPublicAcls": true,
42
- "IgnorePublicAcls": true
27
+ "isDeployed": true
43
28
  },
44
- "BucketName": "pyrossh-website-prd",
45
- "RegionalDomainName": "pyrossh-website-prd.s3.ap-south-1.amazonaws.com",
46
- "OwnershipControls": {
47
- "Rules": [
48
- {
49
- "ObjectOwnership": "BucketOwnerEnforced"
50
- }
51
- ]
52
- },
53
- "DomainName": "pyrossh-website-prd.s3.amazonaws.com",
54
- "BucketEncryption": {
55
- "ServerSideEncryptionConfiguration": [
56
- {
57
- "BucketKeyEnabled": false,
58
- "ServerSideEncryptionByDefault": {
59
- "SSEAlgorithm": "AES256"
60
- }
61
- }
62
- ]
63
- },
64
- "WebsiteURL": "http://pyrossh-website-prd.s3-website.ap-south-1.amazonaws.com",
65
- "DualStackDomainName": "pyrossh-website-prd.s3.dualstack.ap-south-1.amazonaws.com",
66
- "Arn": "arn:aws:s3:::pyrossh-website-prd",
67
- "Tags": [
29
+ "domains": [
68
- {
69
- "Value": "Alchemy",
70
- "Key": "ProvisionedBy"
71
- },
72
- {
73
- "Value": "prd",
74
- "Key": "Stage"
30
+ "pyrossh.dev"
75
- }
76
31
  ]
77
32
  },
78
33
  "props": {
79
- "BucketName": "pyrossh-website-prd",
34
+ "name": "pyrossh-website-prd",
80
- "PublicAccessBlockConfiguration": {
81
- "BlockPublicAcls": true,
82
- "BlockPublicPolicy": true,
83
- "IgnorePublicAcls": true,
84
- "RestrictPublicBuckets": true
85
- },
86
- "Tags": [
35
+ "domains": [
87
- {
88
- "Key": "Stage",
36
+ "pyrossh.dev"
89
- "Value": "prd"
90
- },
37
+ ],
91
- {
92
- "Key": "ProvisionedBy",
38
+ "dev": {
93
- "Value": "Alchemy"
39
+ "force": false
94
- }
40
+ }
95
- ]
96
41
  }
97
42
  }
.alchemy/prd/website-bucket-prd/pyrossh.dev.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "kind": "cloudflare::R2BucketCustomDomain",
3
+ "id": "pyrossh.dev",
4
+ "fqn": "prd/website-bucket-prd/pyrossh.dev",
5
+ "seq": 0,
6
+ "data": {},
7
+ "status": "created",
8
+ "output": {
9
+ "Symbol(alchemy::ResourceKind)": "cloudflare::R2BucketCustomDomain",
10
+ "Symbol(alchemy::ResourceID)": "pyrossh.dev",
11
+ "Symbol(alchemy::ResourceFQN)": "prd/website-bucket-prd/pyrossh.dev",
12
+ "Symbol(alchemy::ResourceScope)": {
13
+ "@scope": null
14
+ },
15
+ "Symbol(alchemy::ResourceSeq)": 0,
16
+ "domain": "pyrossh.dev",
17
+ "enabled": true,
18
+ "zoneId": "e95a5d8957b75859c814579deebfce33"
19
+ },
20
+ "props": {
21
+ "domain": "pyrossh.dev",
22
+ "adopt": false,
23
+ "bucketName": "pyrossh-website-prd",
24
+ "dev": {
25
+ "id": "pyrossh-website-prd",
26
+ "remote": false,
27
+ "isDeployed": true
28
+ }
29
+ }
30
+ }
.alchemy/prd/zone-prd.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "kind": "cloudflare::Zone",
3
+ "id": "zone-prd",
4
+ "fqn": "prd/zone-prd",
5
+ "seq": 0,
6
+ "data": {},
7
+ "status": "created",
8
+ "output": {
9
+ "Symbol(alchemy::ResourceKind)": "cloudflare::Zone",
10
+ "Symbol(alchemy::ResourceID)": "zone-prd",
11
+ "Symbol(alchemy::ResourceFQN)": "prd/zone-prd",
12
+ "Symbol(alchemy::ResourceScope)": {
13
+ "@scope": null
14
+ },
15
+ "Symbol(alchemy::ResourceSeq)": 0,
16
+ "id": "e95a5d8957b75859c814579deebfce33",
17
+ "name": "pyrossh.dev",
18
+ "type": "full",
19
+ "status": "pending",
20
+ "paused": false,
21
+ "accountId": "dfdb8ca4e419990852eb214c5b50bd5e",
22
+ "nameservers": [
23
+ "glen.ns.cloudflare.com",
24
+ "riya.ns.cloudflare.com"
25
+ ],
26
+ "originalNameservers": [
27
+ "ns-1020.awsdns-63.net",
28
+ "ns-1447.awsdns-52.org",
29
+ "ns-1888.awsdns-44.co.uk",
30
+ "ns-482.awsdns-60.com"
31
+ ],
32
+ "createdAt": 1778414069223,
33
+ "modifiedAt": 1778414069223,
34
+ "activatedAt": null,
35
+ "settings": {
36
+ "ssl": "strict",
37
+ "alwaysUseHttps": "on",
38
+ "automaticHttpsRewrites": "on",
39
+ "tls13": "on",
40
+ "earlyHints": "off",
41
+ "emailObfuscation": "on",
42
+ "browserCacheTtl": 14400,
43
+ "developmentMode": "off",
44
+ "http2": "on",
45
+ "http3": "on",
46
+ "ipv6": "on",
47
+ "websockets": "on",
48
+ "zeroRtt": "off",
49
+ "brotli": "on",
50
+ "hotlinkProtection": "off",
51
+ "minTlsVersion": "1.2"
52
+ }
53
+ },
54
+ "props": {
55
+ "name": "pyrossh.dev",
56
+ "type": "full",
57
+ "settings": {
58
+ "ssl": "strict",
59
+ "alwaysUseHttps": "on",
60
+ "minTlsVersion": "1.2",
61
+ "brotli": "on",
62
+ "http3": "on"
63
+ }
64
+ }
65
+ }
alchemy.run.ts CHANGED
@@ -1,289 +1,92 @@
1
1
  import { $ } from "bun";
2
2
  import alchemy from "alchemy";
3
- import AWS from "alchemy/aws/control";
4
- import { AccountId } from "alchemy/aws";
3
+ import { AccountApiToken, Zone, R2Bucket, Ruleset } from "alchemy/cloudflare";
5
4
 
6
- const domainName = "pyrossh.dev";
7
5
  const app = await alchemy("");
8
6
 
9
- const Tags = [
7
+ // const storageToken = await AccountApiToken("account-access-token", {
10
- { Key: "Stage", Value: app.stage },
8
+ // name: "alchemy-account-access-token",
9
+ // policies: [
10
+ // {
11
+ // effect: "allow",
12
+ // permissionGroups: ["Workers R2 Storage Write"],
13
+ // resources: {
11
- { Key: "ProvisionedBy", Value: "Alchemy" }
14
+ // "com.cloudflare.api.account": "*",
12
- ]
13
- const Comment = `ProvisionedBy Alchemy - ${app.stage}`;
15
+ // },
16
+ // },
17
+ // ],
18
+ // });
14
19
 
15
- // Route53 Zone
20
+ // storageToken.accessKeyId
16
- const hostedZone = await AWS.Route53.HostedZone(`hosted-zone-${app.stage}`, {
21
+ // storageToken.secretAccessKey
17
- Name: domainName,
18
- HostedZoneTags: Tags,
19
- HostedZoneConfig: {
20
- Comment: Comment,
21
- },
22
- });
23
22
 
24
- // S3 Buckets with Public Access Block Configuration
25
- const websiteBucket = await AWS.S3.Bucket(`website-bucket-${app.stage}`, {
23
+ const zone = await Zone(`zone-${app.stage}`, {
26
- BucketName: `pyrossh-website-${app.stage}`,
24
+ name: "pyrossh.dev",
27
- PublicAccessBlockConfiguration: {
28
- BlockPublicAcls: true,
25
+ type: "full",
26
+ settings: {
29
- BlockPublicPolicy: true,
27
+ ssl: "strict",
28
+ alwaysUseHttps: "on",
29
+ minTlsVersion: "1.2",
30
- IgnorePublicAcls: true,
30
+ brotli: "on",
31
- RestrictPublicBuckets: true
31
+ http3: "on",
32
32
  },
33
- Tags: Tags,
34
33
  });
35
34
 
35
+ // R2 Bucket for the website
36
- const reposBucket = await AWS.S3.Bucket(`repos-bucket-${app.stage}`, {
36
+ const websiteBucket = await R2Bucket(`website-bucket-${app.stage}`, {
37
- BucketName: `pyrossh-repos-${app.stage}`,
37
+ name: `pyrossh-website-${app.stage}`,
38
- PublicAccessBlockConfiguration: {
39
- BlockPublicAcls: true,
40
- BlockPublicPolicy: true,
41
- IgnorePublicAcls: true,
42
- RestrictPublicBuckets: true
43
- },
44
- Tags: Tags,
45
- });
46
-
47
- // CloudFront Origin Access Control
48
- const s3OAC = await AWS.CloudFront.OriginAccessControl(`s3-oac-${app.stage}`, {
49
- OriginAccessControlConfig: {
50
- Name: `s3-oac-${app.stage}`,
38
+ domains: [zone.name],
51
- OriginAccessControlOriginType: "s3",
52
- SigningBehavior: "always",
53
- SigningProtocol: "sigv4",
54
- },
55
39
  });
56
40
 
57
- // ACM Certificate (in us-east-1 for CloudFront)
58
- // Note: AWS Certificate Manager needs to be created separately or use ACMPCA
59
- // For now, assuming certificate ARN will be provided or created manually
60
- // You may need to adjust this based on your Alchemy setup
61
-
62
- // CloudFront Functions
41
+ // R2 Bucket for git repos
63
- const htmlRedirector = await AWS.CloudFront.Function(`html-redirector-${app.stage}`, {
64
- Name: `html_redirector_${app.stage}`,
65
- FunctionConfig: {
66
- Comment: "HTML redirector function",
67
- Runtime: "cloudfront-js-2.0"
68
- },
69
- FunctionCode: `function handler(event) {
70
- const request = event.request;
71
- const uri = request.uri;
72
-
73
- if (uri.endsWith('/')) {
74
- request.uri += 'index.html';
75
- } else if (!uri.startsWith('/_astro')) {
76
- request.uri += '/index.html';
77
- }
78
- return request;
79
- }`,
80
- AutoPublish: true,
81
- });
82
-
83
- const gitRedirector = await AWS.CloudFront.Function(`git-redirector-${app.stage}`, {
42
+ const reposBucket = await R2Bucket(`repos-bucket-${app.stage}`, {
84
- Name: `git_redirector_${app.stage}`,
43
+ name: `pyrossh-repos-${app.stage}`,
85
- FunctionConfig: {
86
- Comment: "Git redirector function",
87
- Runtime: "cloudfront-js-2.0"
88
- },
89
- FunctionCode: `function handler(event) {
90
- const request = event.request;
91
- const uri = request.uri;
92
- request.uri = "/" + request.uri.replace("/repos/", "");
93
- return request;
94
- }`,
95
- AutoPublish: true,
96
44
  });
97
45
 
98
- // CloudFront Distribution
46
+ // Rewrite trailing slash paths to serve index.html
99
- const s3Distribution = await AWS.CloudFront.Distribution(`s3-distribution-${app.stage}`, {
47
+ const rewriteRules = await Ruleset(`rewrite-rules-${app.stage}`, {
100
- Tags: Tags,
48
+ zone,
101
- DistributionConfig: {
49
+ phase: "http_request_transform",
102
- Origins: [
50
+ rules: [
103
- {
51
+ {
104
- DomainName: websiteBucket.RegionalDomainName,
105
- Id: websiteBucket.RegionalDomainName,
106
- OriginAccessControlId: s3OAC.Id,
107
- S3OriginConfig: {
108
- OriginAccessIdentity: ""
109
- }
110
- },
111
- {
112
- DomainName: reposBucket.RegionalDomainName,
113
- Id: reposBucket.RegionalDomainName,
114
- OriginAccessControlId: s3OAC.Id,
115
- S3OriginConfig: {
116
- OriginAccessIdentity: ""
117
- }
118
- }
119
- ],
120
- Enabled: true,
121
- IPV6Enabled: true,
122
- Aliases: [domainName],
123
- DefaultRootObject: "index.html",
52
+ description: "Rewrite trailing slash to index.html",
124
- CustomErrorResponses: [400, 403, 404, 405, 414, 416, 500, 501, 502, 503, 504].map(code => ({
125
- ErrorCode: code,
126
- ResponseCode: code,
127
- ResponsePagePath: code < 500 ? "/404.html" : "/500.html"
53
+ expression: `(ends_with(http.request.uri.path, "/") and http.host eq "${zone.name}")`,
128
- })),
129
- CacheBehaviors: [
130
- {
131
- PathPattern: "/repos/*.git/*",
132
- AllowedMethods: ["GET", "HEAD"],
133
- CachedMethods: ["GET", "HEAD"],
134
- TargetOriginId: reposBucket.RegionalDomainName,
135
- ForwardedValues: {
136
- QueryString: false,
137
- Cookies: {
138
- Forward: "none"
54
+ action: "rewrite",
55
+ action_parameters: {
139
- }
56
+ uri: {
57
+ path: { expression: `concat(http.request.uri.path, "index.html")` },
140
58
  },
141
- MinTTL: 0,
142
- DefaultTTL: 86400,
143
- MaxTTL: 31536000,
144
- Compress: true,
145
- ViewerProtocolPolicy: "redirect-to-https",
146
- FunctionAssociations: [{
147
- EventType: "viewer-request",
148
- FunctionARN: gitRedirector.FunctionARN
149
- }]
150
59
  },
60
+ },
151
- {
61
+ {
62
+ description: "Rewrite non-file paths to path/index.html",
63
+ expression: `(not ends_with(http.request.uri.path, "/") and not http.request.uri.path contains "." and http.host eq "${zone.name}")`,
152
- PathPattern: "/*",
64
+ action: "rewrite",
153
- AllowedMethods: ["GET", "HEAD"],
154
- CachedMethods: ["GET", "HEAD"],
155
- TargetOriginId: websiteBucket.RegionalDomainName,
156
- ForwardedValues: {
65
+ action_parameters: {
157
- QueryString: true,
158
- Cookies: {
66
+ uri: {
159
- Forward: "none"
67
+ path: { expression: `concat(http.request.uri.path, "/index.html")` },
160
- }
161
68
  },
162
- ViewerProtocolPolicy: "redirect-to-https",
163
- MinTTL: 0,
164
- DefaultTTL: 3600,
165
- MaxTTL: 86400,
166
- FunctionAssociations: [{
167
- EventType: "viewer-request",
168
- FunctionARN: htmlRedirector.FunctionARN
169
- }]
170
- }
171
- ],
172
- DefaultCacheBehavior: {
173
- AllowedMethods: ["GET", "HEAD"],
174
- CachedMethods: ["GET", "HEAD"],
175
- TargetOriginId: websiteBucket.RegionalDomainName,
176
- ForwardedValues: {
177
- QueryString: true,
178
- Cookies: {
179
- Forward: "none"
180
- }
181
69
  },
182
- ViewerProtocolPolicy: "redirect-to-https",
183
- MinTTL: 0,
184
- DefaultTTL: 3600,
185
- MaxTTL: 86400,
186
- FunctionAssociations: [{
187
- EventType: "viewer-request",
188
- FunctionARN: htmlRedirector.FunctionARN
189
- }]
190
- },
191
- PriceClass: "PriceClass_All",
192
- Restrictions: {
193
- GeoRestriction: {
194
- RestrictionType: "none"
195
- }
196
70
  },
71
+ {
197
- // resource "aws_acm_certificate" "domain_ssl_certificate" {
72
+ description: "Rewrite /files/ paths with extension to append /index.html",
198
- // domain_name = "pyrossh.dev"
73
+ expression: `(http.request.uri.path contains "/files/" and http.request.uri.path contains "." and not ends_with(http.request.uri.path, "/") and http.host eq "${zone.name}")`,
199
- // validation_method = "EMAIL"
200
- // provider = aws.useast
201
- // }
202
- ViewerCertificate: {
203
- MinimumProtocolVersion: "TLSv1.2_2021",
204
- CloudFrontDefaultCertificate: false,
205
- SslSupportMethod: "sni-only",
74
+ action: "rewrite",
206
- AcmCertificateArn: "arn:aws:acm:us-east-1:122129753516:certificate/d04cd0a5-623c-4d18-a9d1-f0d8df3e999d",
75
+ action_parameters: {
76
+ uri: {
207
- // AcmCertificateArn: domainSslCertificate.CertificateArn,
77
+ path: { expression: `concat(http.request.uri.path, "/index.html")` },
208
- },
78
+ },
209
- Comment: Comment,
210
- }
211
- });
212
-
213
- // S3 Bucket Policies
214
- const websiteBucketPolicy = await AWS.S3.BucketPolicy(`website-bucket-policy-${app.stage}`, {
215
- Bucket: websiteBucket.BucketName || `pyrossh-website-${app.stage}`,
216
- PolicyDocument: {
217
- Version: "2012-10-17",
218
- Statement: [{
219
- Principal: {
220
- Service: "cloudfront.amazonaws.com"
221
- },
222
- Action: "s3:GetObject",
223
- Resource: [
224
- websiteBucket.Arn,
225
- `${websiteBucket.Arn}/*`
226
- ],
227
- Effect: "Allow",
228
- Condition: {
229
- StringEquals: {
230
- "AWS:SourceArn": `arn:aws:cloudfront::${await AccountId()}:distribution/${s3Distribution.Id}`
231
- }
232
- }
233
- }]
234
- }
235
- });
236
-
237
- const reposBucketPolicy = await AWS.S3.BucketPolicy(`repos-bucket-policy-${app.stage}`, {
238
- Bucket: reposBucket.BucketName!,
239
- PolicyDocument: {
240
- Version: "2012-10-17",
241
- Statement: [{
242
- Principal: {
243
- Service: "cloudfront.amazonaws.com"
244
79
  },
245
- Action: "s3:GetObject",
246
- Resource: [
247
- reposBucket.Arn,
80
+ },
248
- `${reposBucket.Arn}/*`
249
- ],
81
+ ],
250
- Effect: "Allow",
251
- Condition: {
252
- StringEquals: {
253
- "AWS:SourceArn": `arn:aws:cloudfront::${await AccountId()}:distribution/${s3Distribution.Id}`
254
- }
255
- }
256
- }]
257
- }
258
82
  });
259
83
 
84
+ // Website (static site deployed to Cloudflare Workers with assets)
85
+ // await $`bun run build:resume:pdf`;
86
+ // await $`bun run build:resume:svg`;
260
- // Route53 A Record
87
+ // await $`rm -rf dist`;
261
- // console.log({
262
- // HostedZoneId: hostedZone.Id,
263
- // Name: domainName,
88
+ // await $`bun run build`;
264
- // Type: "A",
89
+ // await $`rclone sync --interactive dist r2:${websiteBucket.name}`;
265
- // AliasTarget: {
90
+ // await $`rm -rf dist`;
266
- // DNSName: s3Distribution.DomainName,
267
- // HostedZoneId: s3Distribution.DomainName, // CloudFront hosted zone ID
268
- // EvaluateTargetHealth: false
269
- // }
270
- // })
271
- // const aRecordDomain = await AWS.Route53.RecordSet("a-record-domain", {
272
- // HostedZoneId: hostedZone.Id,
273
- // Name: domainName,
274
- // Type: "A",
275
- // AliasTarget: {
276
- // DNSName: s3Distribution.DomainName,
277
- // HostedZoneId: s3Distribution.DomainName, // CloudFront hosted zone ID
278
- // EvaluateTargetHealth: false
279
- // }
280
- // });
281
91
 
282
92
  await app.finalize();
283
- await $`bun run build:resume:pdf`
284
- await $`bun run build:resume:svg`
285
- await $`rm -rf dist`
286
- await $`bun run build`
287
- await $`aws s3 sync --delete ./dist/ s3://${websiteBucket.BucketName}`
288
- await $`aws cloudfront create-invalidation --distribution-id ${s3Distribution.Id} --paths "/*" --no-cli-pager`
289
- await $`rm -rf dist`
package.json CHANGED
@@ -15,7 +15,9 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@appzic/astro-reset-css": "^1.2.0",
18
+ "@astrojs/cloudflare": "^13.5.0",
19
+ "alchemy": "^0.93.7",
18
- "astro": "6.3.0",
20
+ "astro": "6.3.1",
19
21
  "astro-color-scheme": "^1.1.6",
20
22
  "astro-expressive-code": "^0.42.0",
21
23
  "astro-icon": "^1.1.5",
@@ -33,8 +35,7 @@
33
35
  "@iconify-json/vscode-icons": "^1.2.36",
34
36
  "@playwright/test": "^1.52.0",
35
37
  "@types/bun": "^1.3.2",
36
- "alchemy": "^0.78.0",
37
38
  "diff2html": "^3.4.52",
38
39
  "vscode-icons": "https://github.com/vscode-icons/vscode-icons.git"
39
40
  }
40
- }
41
+ }