~repos /website
git clone https://pyrossh.dev/repos/website.git
木 Personal website of pyrossh. Built with astrojs, shiki, vite.
ba093c22
—
pyrossh 3 weeks ago
update alchemy code
- alchemy.run.ts +72 -69
- bun.lock +3 -0
- package.json +2 -1
- server.js +0 -128
alchemy.run.ts
CHANGED
|
@@ -14,64 +14,60 @@
|
|
|
14
14
|
* 1. Create the certificate manually in ACM (us-east-1 region)
|
|
15
15
|
* 2. Uncomment and provide the certificate ARN in the ViewerCertificate config
|
|
16
16
|
*/
|
|
17
|
-
|
|
17
|
+
import { $ } from "bun";
|
|
18
18
|
import alchemy from "alchemy";
|
|
19
19
|
import AWS from "alchemy/aws/control";
|
|
20
20
|
import { AccountId } from "alchemy/aws";
|
|
21
21
|
|
|
22
22
|
const domainName = "pyrossh.dev";
|
|
23
|
-
const app = await alchemy("
|
|
23
|
+
const app = await alchemy("");
|
|
24
|
+
|
|
25
|
+
const Tags = [
|
|
26
|
+
{ Key: "Stage", Value: app.stage },
|
|
27
|
+
{ Key: "ProvisionedBy", Value: "Alchemy" }
|
|
28
|
+
]
|
|
29
|
+
const Comment = `ProvisionedBy Alchemy - ${app.stage}`;
|
|
24
30
|
|
|
25
31
|
// Route53 Zone
|
|
26
|
-
const hostedZone = await AWS.Route53.HostedZone(
|
|
32
|
+
const hostedZone = await AWS.Route53.HostedZone(`hosted-zone-${app.stage}`, {
|
|
27
33
|
Name: domainName,
|
|
28
|
-
HostedZoneTags:
|
|
34
|
+
HostedZoneTags: Tags,
|
|
29
|
-
{ Key: "Environment", Value: "Production" },
|
|
30
|
-
{ Key: "ProvisionedBy", Value: "Alchemy" }
|
|
31
|
-
],
|
|
32
35
|
HostedZoneConfig: {
|
|
33
|
-
Comment:
|
|
36
|
+
Comment: Comment,
|
|
34
37
|
},
|
|
35
|
-
adopt: true,
|
|
36
38
|
});
|
|
37
39
|
|
|
38
40
|
// S3 Buckets with Public Access Block Configuration
|
|
39
|
-
const websiteBucket = await AWS.S3.Bucket(
|
|
41
|
+
const websiteBucket = await AWS.S3.Bucket(`website-bucket-${app.stage}`, {
|
|
40
|
-
BucketName:
|
|
42
|
+
BucketName: `pyrossh-website-${app.stage}`,
|
|
41
43
|
PublicAccessBlockConfiguration: {
|
|
42
44
|
BlockPublicAcls: true,
|
|
43
45
|
BlockPublicPolicy: true,
|
|
44
46
|
IgnorePublicAcls: true,
|
|
45
47
|
RestrictPublicBuckets: true
|
|
46
48
|
},
|
|
47
|
-
Tags:
|
|
49
|
+
Tags: Tags,
|
|
48
|
-
{ Key: "Environment", Value: "Production" },
|
|
49
|
-
{ Key: "ProvisionedBy", Value: "Alchemy" }
|
|
50
|
-
]
|
|
51
50
|
});
|
|
52
51
|
|
|
53
|
-
const reposBucket = await AWS.S3.Bucket(
|
|
52
|
+
const reposBucket = await AWS.S3.Bucket(`repos-bucket-${app.stage}`, {
|
|
54
|
-
BucketName:
|
|
53
|
+
BucketName: `pyrossh-repos-${app.stage}`,
|
|
55
54
|
PublicAccessBlockConfiguration: {
|
|
56
55
|
BlockPublicAcls: true,
|
|
57
56
|
BlockPublicPolicy: true,
|
|
58
57
|
IgnorePublicAcls: true,
|
|
59
58
|
RestrictPublicBuckets: true
|
|
60
59
|
},
|
|
61
|
-
Tags:
|
|
60
|
+
Tags: Tags,
|
|
62
|
-
{ Key: "Environment", Value: "Production" },
|
|
63
|
-
{ Key: "ProvisionedBy", Value: "Alchemy" }
|
|
64
|
-
]
|
|
65
61
|
});
|
|
66
62
|
|
|
67
63
|
// CloudFront Origin Access Control
|
|
68
|
-
const
|
|
64
|
+
const s3OAC = await AWS.CloudFront.OriginAccessControl(`s3-oac-${app.stage}`, {
|
|
69
65
|
OriginAccessControlConfig: {
|
|
70
|
-
Name:
|
|
66
|
+
Name: `s3-oac-${app.stage}`,
|
|
71
67
|
OriginAccessControlOriginType: "s3",
|
|
72
68
|
SigningBehavior: "always",
|
|
73
|
-
SigningProtocol: "sigv4"
|
|
69
|
+
SigningProtocol: "sigv4",
|
|
74
|
-
}
|
|
70
|
+
},
|
|
75
71
|
});
|
|
76
72
|
|
|
77
73
|
// ACM Certificate (in us-east-1 for CloudFront)
|
|
@@ -80,47 +76,50 @@ const s3Oac = await AWS.CloudFront.OriginAccessControl("s3-oac", {
|
|
|
80
76
|
// You may need to adjust this based on your Alchemy setup
|
|
81
77
|
|
|
82
78
|
// CloudFront Functions
|
|
83
|
-
const htmlRedirector = await AWS.CloudFront.Function(
|
|
79
|
+
const htmlRedirector = await AWS.CloudFront.Function(`html-redirector-${app.stage}`, {
|
|
84
|
-
FunctionCode: `function handler(event) {
|
|
85
|
-
|
|
80
|
+
Name: `html_redirector_${app.stage}`,
|
|
86
|
-
const uri = request.uri;
|
|
87
|
-
|
|
88
|
-
if (uri.endsWith('/')) {
|
|
89
|
-
request.uri += 'index.html';
|
|
90
|
-
} else if (!uri.startsWith('/_astro')) {
|
|
91
|
-
request.uri += '/index.html';
|
|
92
|
-
}
|
|
93
|
-
return request;
|
|
94
|
-
}`,
|
|
95
81
|
FunctionConfig: {
|
|
96
82
|
Comment: "HTML redirector function",
|
|
97
83
|
Runtime: "cloudfront-js-2.0"
|
|
98
84
|
},
|
|
85
|
+
FunctionCode: `function handler(event) {
|
|
99
|
-
|
|
86
|
+
const request = event.request;
|
|
87
|
+
const uri = request.uri;
|
|
88
|
+
|
|
89
|
+
if (uri.endsWith('/')) {
|
|
90
|
+
request.uri += 'index.html';
|
|
91
|
+
} else if (!uri.startsWith('/_astro')) {
|
|
92
|
+
request.uri += '/index.html';
|
|
93
|
+
}
|
|
94
|
+
return request;
|
|
95
|
+
}`,
|
|
96
|
+
AutoPublish: true,
|
|
100
97
|
});
|
|
101
98
|
|
|
102
|
-
const gitRedirector = await AWS.CloudFront.Function(
|
|
99
|
+
const gitRedirector = await AWS.CloudFront.Function(`git-redirector-${app.stage}`, {
|
|
103
|
-
FunctionCode: `function handler(event) {
|
|
104
|
-
|
|
100
|
+
Name: `git_redirector_${app.stage}`,
|
|
105
|
-
const uri = request.uri;
|
|
106
|
-
request.uri = "/" + request.uri.replace("/repos/", "");
|
|
107
|
-
return request;
|
|
108
|
-
}`,
|
|
109
101
|
FunctionConfig: {
|
|
110
102
|
Comment: "Git redirector function",
|
|
111
103
|
Runtime: "cloudfront-js-2.0"
|
|
112
104
|
},
|
|
105
|
+
FunctionCode: `function handler(event) {
|
|
113
|
-
|
|
106
|
+
const request = event.request;
|
|
107
|
+
const uri = request.uri;
|
|
108
|
+
request.uri = "/" + request.uri.replace("/repos/", "");
|
|
109
|
+
return request;
|
|
110
|
+
}`,
|
|
111
|
+
AutoPublish: true,
|
|
114
112
|
});
|
|
115
113
|
|
|
116
114
|
// CloudFront Distribution
|
|
117
|
-
const s3Distribution = await AWS.CloudFront.Distribution(
|
|
115
|
+
const s3Distribution = await AWS.CloudFront.Distribution(`s3-distribution-${app.stage}`, {
|
|
116
|
+
Tags: Tags,
|
|
118
117
|
DistributionConfig: {
|
|
119
118
|
Origins: [
|
|
120
119
|
{
|
|
121
120
|
DomainName: websiteBucket.RegionalDomainName,
|
|
122
121
|
Id: websiteBucket.RegionalDomainName,
|
|
123
|
-
OriginAccessControlId:
|
|
122
|
+
OriginAccessControlId: s3OAC.Id,
|
|
124
123
|
S3OriginConfig: {
|
|
125
124
|
OriginAccessIdentity: ""
|
|
126
125
|
}
|
|
@@ -128,7 +127,7 @@ const s3Distribution = await AWS.CloudFront.Distribution("s3-distribution", {
|
|
|
128
127
|
{
|
|
129
128
|
DomainName: reposBucket.RegionalDomainName,
|
|
130
129
|
Id: reposBucket.RegionalDomainName,
|
|
131
|
-
OriginAccessControlId:
|
|
130
|
+
OriginAccessControlId: s3OAC.Id,
|
|
132
131
|
S3OriginConfig: {
|
|
133
132
|
OriginAccessIdentity: ""
|
|
134
133
|
}
|
|
@@ -136,7 +135,7 @@ const s3Distribution = await AWS.CloudFront.Distribution("s3-distribution", {
|
|
|
136
135
|
],
|
|
137
136
|
Enabled: true,
|
|
138
137
|
IPV6Enabled: true,
|
|
139
|
-
Aliases: [domainName],
|
|
138
|
+
// Aliases: [domainName],
|
|
140
139
|
DefaultRootObject: "index.html",
|
|
141
140
|
CustomErrorResponses: [400, 403, 404, 405, 414, 416, 500, 501, 502, 503, 504].map(code => ({
|
|
142
141
|
ErrorCode: code,
|
|
@@ -212,18 +211,18 @@ const s3Distribution = await AWS.CloudFront.Distribution("s3-distribution", {
|
|
|
212
211
|
}
|
|
213
212
|
},
|
|
214
213
|
ViewerCertificate: {
|
|
215
|
-
CloudFrontDefaultCertificate:
|
|
214
|
+
CloudFrontDefaultCertificate: true,
|
|
215
|
+
// AcmCertificateArn: "arn:aws:acm:us-east-1:122129753516:certificate/d04cd0a5-623c-4d18-a9d1-f0d8df3e999d",
|
|
216
216
|
// AcmCertificateArn: domainSslCertificate.CertificateArn,
|
|
217
|
-
// Uncomment above and create certificate separately or provide ARN
|
|
218
|
-
SslSupportMethod: "sni-only"
|
|
217
|
+
// SslSupportMethod: "sni-only"
|
|
219
218
|
},
|
|
220
|
-
Comment:
|
|
219
|
+
Comment: Comment,
|
|
221
220
|
}
|
|
222
221
|
});
|
|
223
222
|
|
|
224
223
|
// S3 Bucket Policies
|
|
225
|
-
const websiteBucketPolicy = await AWS.S3.BucketPolicy(
|
|
224
|
+
const websiteBucketPolicy = await AWS.S3.BucketPolicy(`website-bucket-policy-${app.stage}`, {
|
|
226
|
-
Bucket: websiteBucket.BucketName ||
|
|
225
|
+
Bucket: websiteBucket.BucketName || `pyrossh-website-${app.stage}`,
|
|
227
226
|
PolicyDocument: {
|
|
228
227
|
Version: "2012-10-17",
|
|
229
228
|
Statement: [{
|
|
@@ -245,8 +244,8 @@ const websiteBucketPolicy = await AWS.S3.BucketPolicy("website-bucket-policy", {
|
|
|
245
244
|
}
|
|
246
245
|
});
|
|
247
246
|
|
|
248
|
-
const reposBucketPolicy = await AWS.S3.BucketPolicy(
|
|
247
|
+
const reposBucketPolicy = await AWS.S3.BucketPolicy(`repos-bucket-policy-${app.stage}`, {
|
|
249
|
-
Bucket: reposBucket.BucketName
|
|
248
|
+
Bucket: reposBucket.BucketName!,
|
|
250
249
|
PolicyDocument: {
|
|
251
250
|
Version: "2012-10-17",
|
|
252
251
|
Statement: [{
|
|
@@ -269,15 +268,19 @@ const reposBucketPolicy = await AWS.S3.BucketPolicy("repos-bucket-policy", {
|
|
|
269
268
|
});
|
|
270
269
|
|
|
271
270
|
// Route53 A Record
|
|
272
|
-
const aRecordDomain = await AWS.Route53.RecordSet("a-record-domain", {
|
|
271
|
+
// const aRecordDomain = await AWS.Route53.RecordSet("a-record-domain", {
|
|
273
|
-
|
|
272
|
+
// HostedZoneId: hostedZone.Id,
|
|
274
|
-
|
|
273
|
+
// Name: domainName,
|
|
275
|
-
|
|
274
|
+
// Type: "A",
|
|
276
|
-
|
|
275
|
+
// AliasTarget: {
|
|
277
|
-
|
|
276
|
+
// DNSName: s3Distribution.DomainName,
|
|
278
|
-
|
|
277
|
+
// HostedZoneId: s3Distribution.DomainName, // CloudFront hosted zone ID
|
|
279
|
-
|
|
278
|
+
// EvaluateTargetHealth: false
|
|
280
|
-
|
|
279
|
+
// }
|
|
281
|
-
});
|
|
280
|
+
// });
|
|
282
281
|
|
|
283
|
-
await app.finalize();
|
|
282
|
+
await app.finalize();
|
|
283
|
+
await $`rm -rf dist`
|
|
284
|
+
await $`bun run build`
|
|
285
|
+
await $`aws s3 sync --delete ./dist/ s3://${websiteBucket.BucketName}`
|
|
286
|
+
await $`aws cloudfront create-invalidation --distribution-id ${s3Distribution.Id} --paths "/*" --no-cli-pager`
|
bun.lock
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"timeago.js": "^4.0.2",
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
+
"@aws-sdk/client-sts": "^3.932.0",
|
|
22
23
|
"@iconify-json/material-symbols": "^1.2.39",
|
|
23
24
|
"@iconify-json/mdi": "^1.2.3",
|
|
24
25
|
"@playwright/test": "^1.52.0",
|
|
@@ -69,6 +70,8 @@
|
|
|
69
70
|
|
|
70
71
|
"@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.932.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.932.0", "@aws-sdk/middleware-host-header": "3.930.0", "@aws-sdk/middleware-logger": "3.930.0", "@aws-sdk/middleware-recursion-detection": "3.930.0", "@aws-sdk/middleware-user-agent": "3.932.0", "@aws-sdk/region-config-resolver": "3.930.0", "@aws-sdk/types": "3.930.0", "@aws-sdk/util-endpoints": "3.930.0", "@aws-sdk/util-user-agent-browser": "3.930.0", "@aws-sdk/util-user-agent-node": "3.932.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.2", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.9", "@smithy/middleware-retry": "^4.4.9", "@smithy/middleware-serde": "^4.2.5", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.5", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.8", "@smithy/util-defaults-mode-node": "^4.2.11", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-XHqHa5iv2OQsKoM2tUQXs7EAyryploC00Wg0XSFra/KAKqyGizUb5XxXsGlyqhebB29Wqur+zwiRwNmejmN0+Q=="],
|
|
71
72
|
|
|
73
|
+
"@aws-sdk/client-sts": ["@aws-sdk/client-sts@3.932.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.932.0", "@aws-sdk/credential-provider-node": "3.932.0", "@aws-sdk/middleware-host-header": "3.930.0", "@aws-sdk/middleware-logger": "3.930.0", "@aws-sdk/middleware-recursion-detection": "3.930.0", "@aws-sdk/middleware-user-agent": "3.932.0", "@aws-sdk/region-config-resolver": "3.930.0", "@aws-sdk/types": "3.930.0", "@aws-sdk/util-endpoints": "3.930.0", "@aws-sdk/util-user-agent-browser": "3.930.0", "@aws-sdk/util-user-agent-node": "3.932.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.2", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.9", "@smithy/middleware-retry": "^4.4.9", "@smithy/middleware-serde": "^4.2.5", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.5", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.8", "@smithy/util-defaults-mode-node": "^4.2.11", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-nH9ZKV7IN7uVU2HS67cknjTcwBRXgwKRCkhmOF/pn4r4aReD7LhUGCua7svttjGV9rkdlYUPEVW++0gk4FkoSg=="],
|
|
74
|
+
|
|
72
75
|
"@aws-sdk/core": ["@aws-sdk/core@3.932.0", "", { "dependencies": { "@aws-sdk/types": "3.930.0", "@aws-sdk/xml-builder": "3.930.0", "@smithy/core": "^3.18.2", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/smithy-client": "^4.9.5", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-AS8gypYQCbNojwgjvZGkJocC2CoEICDx9ZJ15ILsv+MlcCVLtUJSRSx3VzJOUY2EEIaGLRrPNlIqyn/9/fySvA=="],
|
|
73
76
|
|
|
74
77
|
"@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.932.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.932.0", "@aws-sdk/types": "3.930.0", "@smithy/property-provider": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-PWHX32VVYYy/Jbk8TdIwK/ydcC72xjN2OMFIhiOFcpCDF8Cq6yBb0DC90g1dENlJE57VTAs4bwpN290lSfZ1zw=="],
|
package.json
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"dev": "astro dev",
|
|
9
9
|
"build": "astro build",
|
|
10
10
|
"build:tauri": "astro build",
|
|
11
|
+
"infra:deploy": "alchemy deploy --stage prd",
|
|
11
12
|
"dev:android": "tauri android dev -v",
|
|
12
13
|
"build:android": "tauri android build --aab",
|
|
13
14
|
"build:android:sign": "bundletool build-apks --bundle=src-tauri/gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab --output=./app-universal-release.apks --mode=universal --ks=../config/pyrossh_keystore.jks --ks-key-alias=pyrossh --ks-pass=pass:Test@123 --key-pass=pass:Test@123",
|
|
@@ -23,13 +24,13 @@
|
|
|
23
24
|
"astro-color-scheme": "^1.1.5",
|
|
24
25
|
"astro-expressive-code": "^0.41.3",
|
|
25
26
|
"astro-icon": "^1.1.5",
|
|
26
|
-
|
|
27
27
|
"expressive-code-color-chips": "^0.1.2",
|
|
28
28
|
"pretty-bytes": "^7.1.0",
|
|
29
29
|
"simple-git": "^3.27.0",
|
|
30
30
|
"timeago.js": "^4.0.2"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
+
"@aws-sdk/client-sts": "^3.932.0",
|
|
33
34
|
"client-s3": "aws-sdk/client-s3",
|
|
34
35
|
"@iconify-json/mdi": "^1.2.3",
|
|
35
36
|
"@iconify-json/material-symbols": "^1.2.39",
|
server.js
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { Parser } from 'node-sql-parser';
|
|
2
|
-
import { PutObjectCommand, S3Client, GetObjectCommand, paginateListObjectsV2 } from "@aws-sdk/client-s3";
|
|
3
|
-
|
|
4
|
-
const bucketName = "";
|
|
5
|
-
|
|
6
|
-
// import { S3Client } from "bun";
|
|
7
|
-
// const client = new S3Client({
|
|
8
|
-
// region: "ap-south-1",
|
|
9
|
-
// bucket: "",
|
|
10
|
-
// accessKeyId: "",
|
|
11
|
-
// secretAccessKey: "",
|
|
12
|
-
// endpoint: "https://s3express-aps1-az1.ap-south-1.amazonaws.com",
|
|
13
|
-
// });
|
|
14
|
-
// const s3file = client.file("123.json");
|
|
15
|
-
// await s3file.write(JSON.stringify({ hello: "world" }));
|
|
16
|
-
|
|
17
|
-
// const data = await s3file.json()
|
|
18
|
-
// console.log(data);
|
|
19
|
-
|
|
20
|
-
// const client = new S3Client({});
|
|
21
|
-
// const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
22
|
-
// for (const i of arr) {
|
|
23
|
-
// await client.send(new PutObjectCommand({
|
|
24
|
-
// Bucket: bucketName,
|
|
25
|
-
// Key: `posts/${i}.json`,
|
|
26
|
-
// ContentType: "application/json",
|
|
27
|
-
// Body: JSON.stringify({ id: `${i}`, data: `hello '${i}' world` }),
|
|
28
|
-
// }));
|
|
29
|
-
// }
|
|
30
|
-
|
|
31
|
-
// If-None-Match: * if it doesn't exist 409 - ConditionalRequestConflict 412 Precondition Failed
|
|
32
|
-
// If-Match: etag checks if etag is same CAS 409 - ConditionalRequestConflict 412 Precondition Failed
|
|
33
|
-
|
|
34
|
-
const getObjectName = (name) => name.split("::")[2];
|
|
35
|
-
|
|
36
|
-
const client = new S3Client({});
|
|
37
|
-
|
|
38
|
-
const getAllS3Files = async (bucketName, tableName) => {
|
|
39
|
-
const totalFiles = [];
|
|
40
|
-
for await (const data of paginateListObjectsV2({ client }, { Bucket: bucketName, Prefix: `${tableName}/` })) {
|
|
41
|
-
totalFiles.push(...(data.Contents ?? []));
|
|
42
|
-
}
|
|
43
|
-
return totalFiles;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const sql = async (query) => {
|
|
47
|
-
const parser = new Parser();
|
|
48
|
-
const { tableList, columnList, ast } = parser.parse(query, {
|
|
49
|
-
database: "Hive",
|
|
50
|
-
// type: 'table',
|
|
51
|
-
parseOptions: {
|
|
52
|
-
includeLocations: true
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
// console.log(ast);
|
|
56
|
-
// console.log(JSON.stringify(ast, 2, 2));
|
|
57
|
-
// console.log("tableName", tableName);
|
|
58
|
-
const tableName = getObjectName(tableList[0]);
|
|
59
|
-
// if (ast.type === "select") {
|
|
60
|
-
// }
|
|
61
|
-
const contents = await getAllS3Files(bucketName, tableName)
|
|
62
|
-
return await Promise.all(contents.map((r) => {
|
|
63
|
-
return client.send(new GetObjectCommand({ Bucket: bucketName, Key: r.Key, }))
|
|
64
|
-
.then((rr) => rr.Body.transformToString())
|
|
65
|
-
.then(JSON.parse)
|
|
66
|
-
}));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const rows = await sql('SELECT * FROM posts LIMIT 10');
|
|
70
|
-
// const rows = await sql("INSERT INTO posts(id, data) VALUES ('11', 'body');");
|
|
71
|
-
console.log(rows);
|
|
72
|
-
|
|
73
|
-
// const rows = await sql(`
|
|
74
|
-
// CREATE TABLE struct_test(
|
|
75
|
-
// property_id INT
|
|
76
|
-
// )
|
|
77
|
-
// `);
|
|
78
|
-
|
|
79
|
-
// console.log(rows);
|
|
80
|
-
// const resp = await parseQuery("SELECT * FROM POSTS");
|
|
81
|
-
// resp.stmts[0].stmt.SelectStmt.fromClause
|
|
82
|
-
// console.log("stmts", stmts);
|
|
83
|
-
|
|
84
|
-
// Data Definition Language (DDL): CREATE, ALTER, DROP
|
|
85
|
-
// Data Manipulation Language (DML): INSERT, UPDATE, DELETE, MERGE
|
|
86
|
-
// Data Query Language (DQL): SELECT
|
|
87
|
-
// Data Control Language (DCL): GRANT, REVOKE
|
|
88
|
-
|
|
89
|
-
// TABLES/VIEWS/INDEX
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
//
|
|
94
|
-
// import { gluesql } from 'gluesql';
|
|
95
|
-
|
|
96
|
-
// const db = gluesql();
|
|
97
|
-
|
|
98
|
-
// async function run() {
|
|
99
|
-
// await db.query(`
|
|
100
|
-
// CREATE TABLE User (id INTEGER, name TEXT);
|
|
101
|
-
// CREATE TABLE Device (name TEXT, userId INTEGER);
|
|
102
|
-
// INSERT INTO User VALUES
|
|
103
|
-
// (1, 'glue'), (2, 'sticky'), (3, 'watt');
|
|
104
|
-
// INSERT INTO Device VALUES
|
|
105
|
-
// ('Phone', 1), ('Mic', 1), ('Monitor', 3),
|
|
106
|
-
// ('Mouse', 2), ('Touchpad', 2);
|
|
107
|
-
// `);
|
|
108
|
-
|
|
109
|
-
// let sql;
|
|
110
|
-
|
|
111
|
-
// sql = 'SHOW TABLES;';
|
|
112
|
-
// const [{ tables }] = await db.query(sql);
|
|
113
|
-
// console.log(`\n[Query]\n${sql}`);
|
|
114
|
-
// console.table(tables);
|
|
115
|
-
|
|
116
|
-
// sql = `
|
|
117
|
-
// SELECT
|
|
118
|
-
// u.name as user,
|
|
119
|
-
// d.name as device
|
|
120
|
-
// FROM User u
|
|
121
|
-
// JOIN Device d ON u.id = d.userId
|
|
122
|
-
// `.trim().replace(/[ ]{4}/g, '');
|
|
123
|
-
// const [{ rows }] = await db.query(sql);
|
|
124
|
-
// console.log(`\n[Query]\n${sql}`);
|
|
125
|
-
// console.table(rows);
|
|
126
|
-
// }
|
|
127
|
-
|
|
128
|
-
// run();
|