~repos /only-bible-app

#kotlin#android#ios

git clone https://pyrossh.dev/repos/only-bible-app.git

The only bible app you will ever need. No ads. No in-app purchases. No distractions.



ui/alchemy.run.ts



import { $ } from "bun";
import alchemy from "alchemy";
import AWS from "alchemy/aws/control";
import { AccountId } from "alchemy/aws";
const domainName = "onlybible.app";
const appName = 'onlybible';
const app = await alchemy("");
const Tags = [
{ Key: "App", Value: appName },
{ Key: "Stage", Value: app.stage },
{ Key: "ProvisionedBy", Value: "Alchemy" }
]
const Comment = `ProvisionedBy Alchemy - ${appName} - ${app.stage}`;
// Route53 Zone
const hostedZone = await AWS.Route53.HostedZone(`hosted-zone-${app.stage}`, {
Name: domainName,
HostedZoneTags: Tags,
HostedZoneConfig: {
Comment: Comment,
},
});
// S3 Buckets with Public Access Block Configuration
const websiteBucket = await AWS.S3.Bucket(`website-bucket-${app.stage}`, {
BucketName: `${appName}-website-${app.stage}`,
PublicAccessBlockConfiguration: {
BlockPublicAcls: true,
BlockPublicPolicy: true,
IgnorePublicAcls: true,
RestrictPublicBuckets: true
},
Tags: Tags,
});
// CloudFront Origin Access Control
const s3OAC = await AWS.CloudFront.OriginAccessControl(`s3-oac-${app.stage}`, {
OriginAccessControlConfig: {
Name: `${appName}-s3-oac-${app.stage}`,
OriginAccessControlOriginType: "s3",
SigningBehavior: "always",
SigningProtocol: "sigv4",
},
});
// CloudFront Functions
const htmlRedirector = await AWS.CloudFront.Function(`html-redirector-${app.stage}`, {
Name: `${appName}_html_redirector_${app.stage}`,
FunctionConfig: {
Comment: "HTML redirector function",
Runtime: "cloudfront-js-2.0"
},
FunctionCode: `function handler(event) {
const request = event.request;
const uri = request.uri;
if (uri.endsWith('/')) {
request.uri += 'index.html';
} else if (!uri.startsWith('/_astro')) {
request.uri += '/index.html';
}
return request;
}`,
AutoPublish: true,
});
const websiteDistribution = await AWS.CloudFront.Distribution(`s3-distribution-${app.stage}`, {
Tags: Tags,
DistributionConfig: {
Origins: [
{
DomainName: websiteBucket.RegionalDomainName,
Id: websiteBucket.RegionalDomainName,
OriginAccessControlId: s3OAC.Id,
S3OriginConfig: {
OriginAccessIdentity: ""
}
},
],
Enabled: true,
IPV6Enabled: true,
Aliases: [domainName],
DefaultRootObject: "index.html",
CustomErrorResponses: [400, 403, 404, 405, 414, 416, 500, 501, 502, 503, 504].map(code => ({
ErrorCode: code,
ResponseCode: code,
ResponsePagePath: code < 500 ? "/404.html" : "/500.html"
})),
CacheBehaviors: [
{
PathPattern: "/*",
AllowedMethods: ["GET", "HEAD"],
CachedMethods: ["GET", "HEAD"],
TargetOriginId: websiteBucket.RegionalDomainName,
ForwardedValues: {
QueryString: true,
Cookies: {
Forward: "none"
}
},
ViewerProtocolPolicy: "redirect-to-https",
MinTTL: 0,
DefaultTTL: 3600,
MaxTTL: 86400,
FunctionAssociations: [{
EventType: "viewer-request",
FunctionARN: htmlRedirector.FunctionARN
}]
}
],
DefaultCacheBehavior: {
AllowedMethods: ["GET", "HEAD"],
CachedMethods: ["GET", "HEAD"],
TargetOriginId: websiteBucket.RegionalDomainName,
ForwardedValues: {
QueryString: true,
Cookies: {
Forward: "none"
}
},
ViewerProtocolPolicy: "redirect-to-https",
MinTTL: 0,
DefaultTTL: 3600,
MaxTTL: 86400,
FunctionAssociations: [{
EventType: "viewer-request",
FunctionARN: htmlRedirector.FunctionARN
}]
},
PriceClass: "PriceClass_All",
Restrictions: {
GeoRestriction: {
RestrictionType: "none"
}
},
ViewerCertificate: {
SslSupportMethod: "sni-only",
AcmCertificateArn: "arn:aws:acm:us-east-1:122129753516:certificate/f8329274-9402-4f91-a8df-3e648567600d",
},
Comment: Comment,
}
});
// S3 Bucket Policies
await AWS.S3.BucketPolicy(`website-bucket-policy-${app.stage}`, {
Bucket: websiteBucket.BucketName!,
PolicyDocument: {
Version: "2012-10-17",
Statement: [{
Principal: {
Service: "cloudfront.amazonaws.com"
},
Action: "s3:GetObject",
Resource: [
websiteBucket.Arn,
`${websiteBucket.Arn}/*`
],
Effect: "Allow",
Condition: {
StringEquals: {
"AWS:SourceArn": `arn:aws:cloudfront::${await AccountId()}:distribution/${websiteDistribution.Id}`
}
}
}]
}
});
// const aRecordDomain = await AWS.Route53.RecordSet("a-record-domain", {
// HostedZoneId: hostedZone.Id,
// Name: domainName,
// Type: "A",
// AliasTarget: {
// DNSName: websiteDistribution.DomainName,
// HostedZoneId: websiteDistribution.DomainName, // CloudFront hosted zone ID
// EvaluateTargetHealth: false
// }
// });
await app.finalize();
// await $`rm -rf dist`
// await $`bun run build`
// await $`aws s3 sync --delete ./dist/ s3://${websiteBucket.BucketName}`
// await $`aws cloudfront create-invalidation --distribution-id ${websiteDistribution.Id} --paths "/*" --no-cli-pager`
// await $`rm -rf dist`