@stacksjs/cloud 0.58.48 → 0.58.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/index.js +144 -60
  2. package/package.json +34 -33
  3. package/src/cloud/ai.ts +94 -0
  4. package/src/cloud/aws-sdk-layer/nodejs/package-lock.json +386 -0
  5. package/src/cloud/aws-sdk-layer/nodejs/package.json +15 -0
  6. package/src/cloud/cache.ts +0 -0
  7. package/src/cloud/cdn.ts +374 -0
  8. package/src/cloud/cli.ts +45 -0
  9. package/src/cloud/compute.ts +202 -0
  10. package/src/cloud/dashboard.ts +85 -0
  11. package/src/cloud/database.ts +0 -0
  12. package/src/cloud/deployment.ts +41 -0
  13. package/src/cloud/dns.ts +34 -0
  14. package/src/cloud/docs.ts +51 -0
  15. package/src/cloud/email.ts +339 -0
  16. package/src/cloud/file-system.ts +35 -0
  17. package/src/cloud/index.ts +103 -0
  18. package/src/cloud/jump-box.ts +48 -0
  19. package/src/cloud/lambda/ask/index.js +35 -0
  20. package/src/cloud/lambda/cli-setup/index.js +67 -0
  21. package/src/cloud/lambda/summarize/index.js +35 -0
  22. package/src/cloud/network.ts +32 -0
  23. package/src/cloud/package/README.md +59 -0
  24. package/src/cloud/package/package.json +63 -0
  25. package/src/cloud/permissions.ts +33 -0
  26. package/src/cloud/queue.ts +0 -0
  27. package/src/cloud/redirects.ts +45 -0
  28. package/src/cloud/router-layer/nodejs/package.json +15 -0
  29. package/src/cloud/search-engine.ts +108 -0
  30. package/src/cloud/security.ts +259 -0
  31. package/src/cloud/storage.ts +168 -0
  32. package/src/edge/origin-request.ts +49 -0
  33. package/src/helpers.ts +597 -0
  34. package/src/index.ts +3 -0
  35. package/src/runtime/README.md +116 -0
  36. package/src/runtime/bootstrap +3 -0
  37. package/src/runtime/example/lambda.ts +36 -0
  38. package/src/runtime/runtime.ts +830 -0
  39. package/src/runtime/scripts/build-layer.ts +104 -0
  40. package/src/runtime/scripts/publish-layer.ts +110 -0
  41. package/src/runtime/server.ts +39 -0
  42. package/src/types.ts +28 -0
@@ -0,0 +1,48 @@
1
+ /* eslint-disable no-new */
2
+ import type { aws_efs as efs } from 'aws-cdk-lib'
3
+ import { CfnOutput as Output, aws_ec2 as ec2, aws_iam as iam } from 'aws-cdk-lib'
4
+ import type { Construct } from 'constructs'
5
+ import type { NestedCloudProps } from '../types'
6
+
7
+ export interface JumpBoxStackProps extends NestedCloudProps {
8
+ vpc: ec2.Vpc
9
+ fileSystem: efs.FileSystem
10
+ }
11
+
12
+ // export class DocsStack extends NestedStack {
13
+ export class JumpBoxStack {
14
+ jumpBox?: ec2.Instance
15
+
16
+ constructor(scope: Construct, props: JumpBoxStackProps) {
17
+ const role = new iam.Role(scope, 'JumpBoxInstanceRole', {
18
+ assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
19
+ managedPolicies: [
20
+ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'),
21
+ iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'),
22
+ ],
23
+ })
24
+
25
+ // this instance needs to be created once to mount the EFS & clone the Stacks repo
26
+ this.jumpBox = new ec2.Instance(scope, 'JumpBox', {
27
+ vpc: props.vpc,
28
+ instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
29
+ machineImage: new ec2.AmazonLinuxImage(),
30
+ role,
31
+ userData: ec2.UserData.custom(`
32
+ #!/bin/bash
33
+ yum update -y
34
+ yum install -y amazon-efs-utils
35
+ yum install -y git
36
+ yum install -y https://s3.us-east-1.amazonaws.com/amazon-ssm-us-east-1/latest/linux_amd64/amazon-ssm-agent.rpm
37
+ mkdir /mnt/efs
38
+ mount -t efs ${props.fileSystem.fileSystemId}:/ /mnt/efs
39
+ git clone https://github.com/stacksjs/stacks.git /mnt/efs
40
+ `),
41
+ })
42
+
43
+ new Output(scope, 'JumpBoxInstanceId', {
44
+ value: this.jumpBox.instanceId,
45
+ description: 'The ID of the EC2 instance that can be used to SSH into the Stacks Cloud.',
46
+ })
47
+ }
48
+ }
@@ -0,0 +1,35 @@
1
+ const AWS = require('aws-sdk')
2
+
3
+ async function handler(event) {
4
+ const requestBody = JSON.parse(event.body)
5
+
6
+ // Extract the 'question' property from the request body
7
+ const question = requestBody.question
8
+ // eslint-disable-next-line no-console
9
+ console.log(`Question received: ${question}`)
10
+
11
+ const bedrockRuntime = new AWS.BedrockRuntime({ apiVersion: '2023-09-30' })
12
+ const res = await bedrockRuntime.invokeModel({
13
+ modelId: 'amazon.titan-text-express-v1',
14
+ contentType: 'application/json',
15
+ accept: '*/*',
16
+ body: JSON.stringify({
17
+ inputText: question,
18
+ textGenerationConfig: {
19
+ maxTokenCount: 300,
20
+ stopSequences: [],
21
+ temperature: 0.1,
22
+ topP: 0.9,
23
+ },
24
+ }),
25
+ }).promise()
26
+
27
+ return {
28
+ statusCode: 200,
29
+ body: res.body.toString(),
30
+ }
31
+ }
32
+
33
+ module.exports = {
34
+ handler,
35
+ }
@@ -0,0 +1,67 @@
1
+ async function handler() {
2
+ const setupScriptContents = `if [ -n "$1" ]; then
3
+ # Check if the directory exists
4
+ if [ -d "storage/framework/core" ]; then # this is our identifier whether it is a Stacks project
5
+ :
6
+ else
7
+ if [ -d "$1" ]; then
8
+ echo "Project $1 exists locally. Please use a different name & run again."
9
+ exit 1
10
+ else
11
+ git clone https://github.com/stacksjs/stacks.git $1
12
+ cd $1
13
+ # Run the pkgx-install script
14
+ "./storage/framework/scripts/pkgx-install"
15
+
16
+ echo "Project $1 has been created. Please open a new terminal, run 'bun run dev' to start the server."
17
+
18
+ exit 1
19
+ fi
20
+ fi
21
+ fi
22
+
23
+ # Get the directory of the current script and go up 3 directories
24
+ PROJECT_ROOT="$(cd "$(dirname "$0")" && pwd)"
25
+ CLI_PATH="$PROJECT_ROOT/storage/framework/core/buddy/src/cli.ts"
26
+ SCRIPT_PATH="$PROJECT_ROOT/storage/framework/scripts/pkgx-install"
27
+ LOG_PATH="$PROJECT_ROOT/storage/logs/console.log"
28
+
29
+ if [[ $* == *--verbose* ]]; then
30
+ echo "Project root: $PROJECT_ROOT"
31
+ echo "CLI path: $CLI_PATH"
32
+ echo "Script path: $SCRIPT_PATH"
33
+ echo "Log path: $LOG_PATH"
34
+ fi
35
+
36
+ cd $PROJECT_ROOT
37
+ # Run the pkgx-install script
38
+ if [[ $* == *--verbose* ]]; then
39
+ "$SCRIPT_PATH"
40
+ # bun --bun ./storage/framework/core/buddy/src/cli.ts setup --verbose
41
+ else
42
+ "$SCRIPT_PATH" > /dev/null 2>&1
43
+ # bun --bun ./storage/framework/core/buddy/src/cli.ts setup
44
+ fi
45
+
46
+ # Create a named pipe
47
+ mkfifo /tmp/mypipe
48
+
49
+ # Run the command, send output to both the console and the pipe
50
+ bun --bun $CLI_PATH setup | tee /tmp/mypipe &
51
+
52
+ # Read from the pipe, add timestamps, and append to the file
53
+ while IFS= read -r line; do echo "$(date '+[%Y-%m-%d %H:%M:%S]') $line"; done < /tmp/mypipe >> $LOG_PATH
54
+
55
+ # Remove the named pipe
56
+ rm /tmp/mypipe
57
+ `
58
+
59
+ return {
60
+ statusCode: 200,
61
+ body: setupScriptContents,
62
+ }
63
+ }
64
+
65
+ module.exports = {
66
+ handler,
67
+ }
@@ -0,0 +1,35 @@
1
+ const AWS = require('aws-sdk')
2
+
3
+ async function handler(event) {
4
+ const requestBody = JSON.parse(event.body)
5
+
6
+ // Extract the 'question' property from the request body
7
+ const text = requestBody.text
8
+ // eslint-disable-next-line no-console
9
+ console.log(`Text received: ${text}`)
10
+
11
+ const bedrockRuntime = new AWS.BedrockRuntime({ apiVersion: '2023-09-30' })
12
+ const res = await bedrockRuntime.invokeModel({
13
+ modelId: 'amazon.titan-text-express-v1',
14
+ contentType: 'application/json',
15
+ accept: '*/*',
16
+ body: JSON.stringify({
17
+ inputText: `Summarize the following text: ${text}`,
18
+ textGenerationConfig: {
19
+ maxTokenCount: 512,
20
+ stopSequences: [],
21
+ temperature: 0,
22
+ topP: 0.9,
23
+ },
24
+ }),
25
+ }).promise()
26
+
27
+ return {
28
+ statusCode: 200,
29
+ body: res.body.toString(),
30
+ }
31
+ }
32
+
33
+ module.exports = {
34
+ handler,
35
+ }
@@ -0,0 +1,32 @@
1
+ import { aws_ec2 as ec2 } from 'aws-cdk-lib'
2
+ import type { Construct } from 'constructs'
3
+ import type { NestedCloudProps } from '../types'
4
+
5
+ export interface NetworkStackProps extends NestedCloudProps {
6
+ //
7
+ }
8
+
9
+ export class NetworkStack {
10
+ vpc: ec2.Vpc
11
+
12
+ constructor(scope: Construct, props: NetworkStackProps) {
13
+ this.vpc = new ec2.Vpc(scope, 'Network', {
14
+ vpcName: `${props.slug}-${props.appEnv}-vpc`,
15
+ ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
16
+ maxAzs: 3,
17
+ natGateways: 0,
18
+ subnetConfiguration: [
19
+ {
20
+ name: 'public-subnet-1',
21
+ subnetType: ec2.SubnetType.PUBLIC,
22
+ cidrMask: 24,
23
+ },
24
+ {
25
+ name: 'private-subnet-1',
26
+ subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
27
+ cidrMask: 28,
28
+ },
29
+ ],
30
+ })
31
+ }
32
+ }
@@ -0,0 +1,59 @@
1
+ # Stacks Router
2
+
3
+ This package contains the Stacks Router.
4
+
5
+ ## ☘️ Features
6
+
7
+ wip
8
+
9
+ - ⚡️
10
+
11
+ wip
12
+
13
+ ## 🤖 Usage
14
+
15
+ wip
16
+
17
+ ```bash
18
+ bun install -d @stacksjs/actions
19
+ ```
20
+
21
+ Now, you can use it in your project:
22
+
23
+ ```js
24
+ import * as router from '@stacksjs/router'
25
+
26
+ // wip
27
+ ```
28
+
29
+ Learn more in the docs.
30
+
31
+ ## 🧪 Testing
32
+
33
+ ```bash
34
+ bun test
35
+ ```
36
+
37
+ ## 📈 Changelog
38
+
39
+ Please see our [releases](https://github.com/stacksjs/stacks/releases) page for more information on what has changed recently.
40
+
41
+ ## 🚜 Contributing
42
+
43
+ Please review the [Contributing Guide](https://github.com/stacksjs/contributing) for details.
44
+
45
+ ## 🏝 Community
46
+
47
+ For help, discussion about best practices, or any other conversation that would benefit from being searchable:
48
+
49
+ [Discussions on GitHub](https://github.com/stacksjs/stacks/discussions)
50
+
51
+ For casual chit-chat with others using this package:
52
+
53
+ [Join the Stacks Discord Server](https://discord.gg/stacksjs)
54
+
55
+ ## 📄 License
56
+
57
+ The MIT License (MIT). Please see [LICENSE](https://github.com/stacksjs/stacks/tree/main/LICENSE.md) for more information.
58
+
59
+ Made with 💙
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@stacksjs/router",
3
+ "type": "module",
4
+ "version": "0.58.50",
5
+ "description": "The Stacks framework router.",
6
+ "author": "Chris Breuer",
7
+ "license": "MIT",
8
+ "funding": "https://github.com/sponsors/chrisbbreuer",
9
+ "homepage": "https://github.com/stacksjs/stacks/tree/main/storage/framework/core/router#readme",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/stacksjs/stacks.git",
13
+ "directory": "./storage/framework/core/router"
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/stacksjs/stacks/issues"
17
+ },
18
+ "keywords": [
19
+ "router",
20
+ "stacks",
21
+ "framework",
22
+ "typescript",
23
+ "javascript"
24
+ ],
25
+ "exports": {
26
+ ".": {
27
+ "bun": "./src/index.ts",
28
+ "import": "./dist/index.js"
29
+ },
30
+ "./*": {
31
+ "bun": "./src/*",
32
+ "import": "./dist/*"
33
+ }
34
+ },
35
+ "module": "dist/index.js",
36
+ "types": "dist/index.d.ts",
37
+ "contributors": [
38
+ "Chris Breuer <chris@stacksjs.org>"
39
+ ],
40
+ "files": [
41
+ "README.md",
42
+ "dist",
43
+ "src"
44
+ ],
45
+ "scripts": {
46
+ "build": "bun --bun build.ts",
47
+ "typecheck": "bun --bun tsc --noEmit",
48
+ "prepublishOnly": "bun --bun run build"
49
+ },
50
+ "peerDependencies": {
51
+ "@stacksjs/config": "latest",
52
+ "unplugin-vue-router": "^0.7.0",
53
+ "vue-router": "^4.2.5"
54
+ },
55
+ "dependencies": {
56
+ "@stacksjs/config": "latest",
57
+ "unplugin-vue-router": "^0.7.0",
58
+ "vue-router": "^4.2.5"
59
+ },
60
+ "devDependencies": {
61
+ "@stacksjs/development": "latest"
62
+ }
63
+ }
@@ -0,0 +1,33 @@
1
+ import { SecretValue, aws_iam as iam } from 'aws-cdk-lib'
2
+ import type { Construct } from 'constructs'
3
+ import { config } from '@stacksjs/config'
4
+ import { string } from '@stacksjs/strings'
5
+ import { env } from '@stacksjs/env'
6
+ import type { NestedCloudProps } from '../types'
7
+
8
+ export interface PermissionsStackProps extends NestedCloudProps {
9
+ //
10
+ }
11
+
12
+ export class PermissionsStack {
13
+ constructor(scope: Construct) {
14
+ const teamName = config.team.name
15
+ const users = config.team.members
16
+ const password = env.AWS_DEFAULT_PASSWORD || string.random()
17
+
18
+ for (const name in users) {
19
+ // const userEmail = users[userName]
20
+ const id = `User${string.pascalCase(teamName)}${string.pascalCase(name)}`
21
+ const userName = string.slug(`${teamName}-${name}`)
22
+ const user = new iam.User(scope, id, {
23
+ userName,
24
+ password: SecretValue.unsafePlainText(password),
25
+ passwordResetRequired: true,
26
+ })
27
+
28
+ user.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess'))
29
+
30
+ // TODO: email the userEmail their credentials
31
+ }
32
+ }
33
+ }
File without changes
@@ -0,0 +1,45 @@
1
+ /* eslint-disable no-new */
2
+ import { config } from '@stacksjs/config'
3
+ import { RemovalPolicy, aws_route53 as route53, aws_s3 as s3 } from 'aws-cdk-lib'
4
+ import type { Construct } from 'constructs'
5
+ import type { NestedCloudProps } from '../types'
6
+
7
+ export interface RedirectsStackProps extends NestedCloudProps {
8
+ //
9
+ }
10
+
11
+ export class RedirectsStack {
12
+ redirectZones: route53.IHostedZone[] = []
13
+
14
+ constructor(scope: Construct, props: RedirectsStackProps) {
15
+ // for each redirect, create a bucket & redirect it to the APP_URL
16
+ config.dns.redirects?.forEach((redirect) => {
17
+ // TODO: use string-ts function here instead
18
+ const slug = redirect.split('.').map((part, index) => index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)).join('') // creates a CamelCase slug from the redirect
19
+ const hostedZone = route53.HostedZone.fromLookup(scope, 'HostedZone', { domainName: redirect })
20
+
21
+ const redirectBucket = new s3.Bucket(scope, `RedirectBucket${slug}`, {
22
+ bucketName: `${redirect}-redirect`,
23
+ websiteRedirect: {
24
+ hostName: props.domain,
25
+ protocol: s3.RedirectProtocol.HTTPS,
26
+ },
27
+ removalPolicy: RemovalPolicy.DESTROY,
28
+ autoDeleteObjects: true,
29
+ })
30
+
31
+ new route53.CnameRecord(scope, `RedirectRecord${slug}`, {
32
+ zone: hostedZone,
33
+ recordName: 'redirect',
34
+ domainName: redirectBucket.bucketWebsiteDomainName,
35
+ })
36
+ })
37
+
38
+ // TODO: fix this – redirects do not work yet
39
+ config.dns.redirects?.forEach((redirect) => {
40
+ const slug = redirect.split('.').map((part, index) => index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)).join('') // creates a CamelCase slug from the redirect
41
+ const hostedZone = route53.HostedZone.fromLookup(scope, `RedirectHostedZone${slug}`, { domainName: redirect })
42
+ this.redirectZones.push(hostedZone)
43
+ })
44
+ }
45
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "stacks-router-layer",
3
+ "version": "0.58.50",
4
+ "description": "",
5
+ "author": "",
6
+ "license": "MIT",
7
+ "keywords": [],
8
+ "main": "index.js",
9
+ "scripts": {
10
+ "test": "echo \"Error: no test specified\" && exit 1"
11
+ },
12
+ "dependencies": {
13
+ "@stacksjs/router": "^0.58.49"
14
+ }
15
+ }
@@ -0,0 +1,108 @@
1
+ // async manageSearchEngine() {
2
+ // const vpc = this.vpc
3
+
4
+ // // Security Group
5
+ // const bastionSecurityGroup = new ec2.SecurityGroup(this, 'BastionSecurityGroup', {
6
+ // vpc,
7
+ // allowAllOutbound: true,
8
+ // securityGroupName: `${this.appName}-${appEnv}-bastion-sg`,
9
+ // })
10
+
11
+ // const opensearchSecurityGroup = new ec2.SecurityGroup(this, 'OpenSearchSecurityGroup', {
12
+ // vpc,
13
+ // securityGroupName: `${this.appName}-${appEnv}-opensearch-sg`,
14
+ // })
15
+
16
+ // opensearchSecurityGroup.addIngressRule(bastionSecurityGroup, ec2.Port.tcp(443))
17
+
18
+ // // Service-linked role that Amazon OpenSearch Service will use
19
+ // const iamClient = new IAMClient({})
20
+ // const response = await iamClient.send(
21
+ // new ListRolesCommand({
22
+ // PathPrefix: '/aws-service-role/opensearchservice.amazonaws.com/',
23
+ // }),
24
+ // )
25
+
26
+ // // Only if the role for OpenSearch Service doesn't exist, it will be created.
27
+ // if (response.Roles && response.Roles?.length === 0) {
28
+ // new iam.CfnServiceLinkedRole(this, 'OpenSearchServiceLinkedRole', {
29
+ // awsServiceName: 'es.amazonaws.com',
30
+ // })
31
+ // }
32
+
33
+ // // Bastion host to access Opensearch Dashboards
34
+ // new ec2.BastionHostLinux(this, 'BastionHost', {
35
+ // vpc,
36
+ // securityGroup: bastionSecurityGroup,
37
+ // machineImage: ec2.MachineImage.latestAmazonLinux2023(),
38
+ // blockDevices: [
39
+ // {
40
+ // deviceName: '/dev/xvda',
41
+ // volume: ec2.BlockDeviceVolume.ebs(10, {
42
+ // encrypted: true,
43
+ // }),
44
+ // },
45
+ // ],
46
+ // })
47
+
48
+ // // OpenSearch domain
49
+ // const domain = new opensearch.Domain(this, 'OpenSearchDomain', {
50
+ // version: opensearch.EngineVersion.OPENSEARCH_2_9,
51
+ // nodeToNodeEncryption: true,
52
+ // enforceHttps: true,
53
+ // encryptionAtRest: {
54
+ // enabled: true,
55
+ // },
56
+ // vpc,
57
+ // // unsure if there are "better" ways to do this
58
+ // vpcSubnets: [
59
+ // { subnetGroupName: `${this.appName}-${appEnv}-private-subnet-1` },
60
+ // { subnetGroupName: `${this.appName}-${appEnv}-private-subnet-2` },
61
+ // ],
62
+
63
+ // capacity: {
64
+ // masterNodes: 2,
65
+ // dataNodes: 2,
66
+ // multiAzWithStandbyEnabled: true,
67
+ // },
68
+ // ebs: {
69
+ // volumeSize: 10,
70
+ // volumeType: ec2.EbsDeviceVolumeType.GP3, // or opensearch.EbsVolumeType.IO1
71
+ // },
72
+ // removalPolicy: RemovalPolicy.DESTROY,
73
+ // zoneAwareness: {
74
+ // enabled: true,
75
+ // availabilityZoneCount: 2,
76
+ // },
77
+ // securityGroups: [opensearchSecurityGroup],
78
+ // })
79
+
80
+ // domain.addAccessPolicies(
81
+ // new iam.PolicyStatement({
82
+ // principals: [new iam.AnyPrincipal()],
83
+ // actions: ['es:ESHttp*'],
84
+ // resources: [`${domain.domainArn}/*`],
85
+ // }),
86
+ // )
87
+
88
+ // // // Lambda
89
+ // // const dataIndexFunction = PythonFunction(this, 'DataIndex', {
90
+ // // runtime: lambda.Runtime.PYTHON_3_10,
91
+ // // entry: 'lambda',
92
+ // // vpc,
93
+ // // environment: {
94
+ // // OPENSEARCH_HOST: domain.domainEndpoint,
95
+ // // },
96
+ // // })
97
+
98
+ // // domain.connections.allowFrom(dataIndexFunction, Port.tcp(443))
99
+
100
+ // // Outputs
101
+ // new Output(this, 'OpenSearchDomainHost', {
102
+ // value: domain.domainEndpoint,
103
+ // })
104
+
105
+ // // new Output(this, 'IndexingFunctionName', {
106
+ // // value: dataIndexFunction.functionName,
107
+ // // })
108
+ // }