Skip to content

Commit d3c9dcb

Browse files
committed
chore: wip
chore: wip
1 parent 23362b9 commit d3c9dcb

File tree

19 files changed

+252
-146
lines changed

19 files changed

+252
-146
lines changed

.stacks/core/actions/src/clean.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
import { log } from '@stacksjs/logging'
2-
import { projectPath } from '@stacksjs/path'
3-
import { rimraf as del } from '@stacksjs/utils'
2+
import { clean } from '@stacksjs/utils'
43

54
log.info('Running clean command...')
65

7-
await del([
8-
projectPath('bun.lockb'),
9-
projectPath('yarn.lock'),
10-
projectPath('node_modules/'),
11-
projectPath('.stacks/dist'),
12-
projectPath('.stacks/**/dist'),
13-
])
6+
await clean()

.stacks/core/actions/src/fresh.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
import process from 'node:process'
22
import { ExitCode } from '@stacksjs/types'
3-
import { runCommands } from '@stacksjs/cli'
3+
import { runCommand } from '@stacksjs/cli'
44
import { projectPath } from '@stacksjs/path'
5+
import { cleanProject } from '@stacksjs/utils'
56

6-
const results = await runCommands([
7-
'buddy clean',
8-
'bun install',
9-
], { cwd: projectPath() })
7+
console.log('Cleaning project...')
8+
await cleanProject()
109

11-
for (const result of results) {
12-
if (result.isErr()) {
13-
handleError(result.error)
14-
process.exit(ExitCode.FatalError)
15-
}
10+
console.log('Installing dependencies...')
11+
12+
const result = await runCommand('bun install', {
13+
cwd: projectPath()
14+
})
15+
16+
if (result.isErr()) {
17+
handleError(result.error)
18+
process.exit(ExitCode.FatalError)
1619
}

.stacks/core/actions/src/helpers/utils.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as storage from '@stacksjs/storage'
22
import { italic, runCommand, runCommands, underline } from '@stacksjs/cli'
33
import { log } from '@stacksjs/logging'
44
import * as p from '@stacksjs/path'
5-
import { type ActionOptions, type StacksError, type SyncSubprocess } from '@stacksjs/types'
5+
import type { ActionOptions, StacksError, Subprocess } from '@stacksjs/types'
66
import { type Result, err, handleError } from '@stacksjs/error-handling'
77

88
function parseOptions(options?: ActionOptions) {
@@ -32,19 +32,19 @@ function parseOptions(options?: ActionOptions) {
3232
* @param options The options to pass to the command.
3333
* @returns The result of the command.
3434
*/
35-
export async function runAction(action: string, options?: ActionOptions): Promise<Result<SyncSubprocess, StacksError>> {
35+
export async function runAction(action: string, options?: ActionOptions): Promise<Result<Subprocess, StacksError>> {
3636
if (!hasAction(action))
3737
return err(handleError(`The specified action "${action}" does not exist`))
3838

3939
const opts = parseOptions(options)
4040
const path = p.relativeActionsPath(`${action}.ts`)
41-
const cmd = `bun --bun ${`${path} ${opts}`}`
41+
const cmd = `bun ${`${path} ${opts}`}`
4242

4343
if (options?.verbose)
4444
log.debug('Running action:', underline(italic(`./actions/${action}.ts`)))
4545

4646
return await runCommand(cmd, {
47-
cwd: options?.cwd ?? p.projectPath(),
47+
cwd: options?.cwd || p.projectPath(),
4848
...options,
4949
})
5050
}

.stacks/core/buddy/src/commands/fresh.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ export function fresh(buddy: CLI) {
1515
.option('--verbose', descriptions.verbose, { default: false })
1616
.action(async (options: FreshOptions) => {
1717
const perf = await intro('buddy fresh')
18-
const result = await runAction(Action.Fresh, options)
18+
const result = await runAction(Action.Fresh, { ...options, stdout: 'inherit' })
1919

2020
if (result.isErr()) {
21-
await outro('While running the `fresh` command, there was an issue', { startTime: perf, useSeconds: true, isError: true }, result.error)
21+
await outro('While running `buddy fresh`, there was an issue', { startTime: perf, useSeconds: true, isError: true }, result.error)
2222
process.exit(ExitCode.FatalError)
2323
}
2424

.stacks/core/cli/src/exec.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import { ExitCode } from '@stacksjs/types'
33
import type { CliOptions, StacksError, Subprocess, SyncSubprocess } from '@stacksjs/types'
44
import { type Result, err, handleError, ok } from '@stacksjs/error-handling'
5-
import { log } from './console'
65

76
/**
87
* Execute a command.
@@ -29,12 +28,14 @@ export async function exec(command: string | string[], options?: CliOptions): Pr
2928
const cmd: string[] = Array.isArray(command) ? command : command.split(' ')
3029
const proc = Bun.spawn(cmd, {
3130
...options,
32-
stdout: options?.stdout || 'inherit',
31+
stdout: options?.stdout || 'pipe',
32+
stderr: options?.stderr || 'inherit',
3333
cwd: options?.cwd || import.meta.dir,
34-
onExit(subprocess, exitCode, signalCode, error) {
35-
// if (exitCode !== ExitCode.Success && exitCode)
36-
// handleError(`Failed to execute command: ${cmd.join(' ')}`)
37-
},
34+
// onExit(subprocess, exitCode, signalCode, error) {
35+
// console.log('onExit', { subprocess, exitCode, signalCode, error })
36+
// // if (exitCode !== ExitCode.Success && exitCode)
37+
// // handleError(`Failed to execute command: ${cmd.join(' ')}`)
38+
// },
3839
})
3940

4041
const exited = await proc.exited
@@ -69,10 +70,11 @@ export function execSync(command: string | string[], options?: CliOptions): Resu
6970
...options,
7071
stdout: options?.stdout ?? 'inherit',
7172
cwd: options?.cwd ?? import.meta.dir,
72-
onExit(subprocess: any, exitCode: any, signalCode: any, error: any) {
73-
if (exitCode !== ExitCode.Success)
74-
log.error(error)
75-
},
73+
env: { ...process.env, ...options?.env },
74+
// onExit(subprocess: any, exitCode: any, signalCode: any, error: any) {
75+
// if (exitCode !== ExitCode.Success)
76+
// log.error(error)
77+
// },
7678
})
7779

7880
if (proc.success)

.stacks/core/cli/src/run.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type CliOptions, type CommandError, type SyncSubprocess } from '@stacksjs/types'
1+
import type { CliOptions, CommandError, Subprocess, SyncSubprocess } from '@stacksjs/types'
22
import { type Result, err, ok } from '@stacksjs/error-handling'
33
import { exec, execSync } from './exec'
44
import { italic, underline } from './utilities'
@@ -29,16 +29,11 @@ import { log } from './console'
2929
* console.log(result)
3030
* ```
3131
*/
32-
export async function runCommand(command: string, options?: CliOptions): Promise<Result<SyncSubprocess, CommandError>> {
32+
export async function runCommand(command: string, options?: CliOptions): Promise<Result<Subprocess, CommandError>> {
3333
if (options?.verbose)
3434
log.debug('Running command:', underline(italic(command)), 'with options:', options)
3535

36-
const result = await exec(command, options)
37-
38-
if (result.isErr())
39-
return err(result.error)
40-
41-
return ok(result.value)
36+
return await exec(command, options)
4237
}
4338

4439
/**

.stacks/core/cloud/src/cloud.ts

Lines changed: 99 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import {
1515
aws_route53_targets as targets,
1616
aws_wafv2 as wafv2,
1717
} from 'aws-cdk-lib'
18-
import { app } from '../../config/src'
18+
import { projectPath } from '@stacksjs/path'
19+
import { app } from '@stacksjs/config'
1920

2021
export class StacksCloud extends Stack {
2122
constructor(scope: Construct, id: string, props?: StackProps) {
@@ -35,11 +36,6 @@ export class StacksCloud extends Stack {
3536
validation: acm.CertificateValidation.fromDns(zone),
3637
})
3738

38-
const docsCertificate = new acm.Certificate(this, 'DocsCertificate', {
39-
domainName: `${app.subdomains.docs}.${domainName}`,
40-
validation: acm.CertificateValidation.fromDns(zone),
41-
})
42-
4339
const publicBucket = new s3.Bucket(this, 'PublicBucket', {
4440
bucketName: `${domainName}-${app.env}`,
4541
versioned: true,
@@ -54,27 +50,6 @@ export class StacksCloud extends Stack {
5450
autoDeleteObjects: true,
5551
})
5652

57-
const docsBucket = new s3.Bucket(this, 'DocsBucket', {
58-
bucketName: `docs.${domainName}-${app.env}`,
59-
versioned: true,
60-
removalPolicy: RemovalPolicy.DESTROY,
61-
autoDeleteObjects: true,
62-
})
63-
64-
// Create an S3 bucket for CloudFront access logs
65-
const logBucket = new s3.Bucket(this, 'LogBucket', {
66-
bucketName: `${domainName}-logs-${app.env}`,
67-
removalPolicy: RemovalPolicy.DESTROY,
68-
autoDeleteObjects: true,
69-
objectOwnership: s3.ObjectOwnership.BUCKET_OWNER_PREFERRED,
70-
})
71-
72-
logBucket.addLifecycleRule({
73-
enabled: true,
74-
expiration: Duration.days(30),
75-
id: 'rule',
76-
})
77-
7853
// Create WAF WebAcl
7954
const webAcl = new wafv2.CfnWebACL(this, 'WebAcl', {
8055
scope: 'CLOUDFRONT',
@@ -132,62 +107,13 @@ export class StacksCloud extends Stack {
132107
// ],
133108
})
134109

135-
const docsDistribution = new cloudfront.Distribution(this, 'DocsDistribution', {
136-
domainNames: [`${app.subdomains.docs}.${app.url}`],
137-
defaultRootObject: 'index.html',
138-
comment: `CDN for ${app.subdomains.docs}.${app.url}`,
139-
certificate: docsCertificate,
140-
// originShieldEnabled: true,
141-
enableLogging: true,
142-
logBucket,
143-
httpVersion: cloudfront.HttpVersion.HTTP2_AND_3,
144-
priceClass: cloudfront.PriceClass.PRICE_CLASS_ALL,
145-
enabled: true,
146-
minimumProtocolVersion: cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021,
147-
webAclId: webAcl.attrArn,
148-
enableIpv6: true,
149-
150-
defaultBehavior: {
151-
origin: new origins.S3Origin(docsBucket, {
152-
originAccessIdentity,
153-
}),
154-
compress: true,
155-
allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD,
156-
cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD,
157-
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
158-
cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
159-
},
160-
161-
// errorResponses: [
162-
// {
163-
// httpStatus: 403,
164-
// responsePagePath: '/index.html',
165-
// responseHttpStatus: 200,
166-
// ttl: cdk.Duration.minutes(0),
167-
// },
168-
// {
169-
// httpStatus: 404,
170-
// responsePagePath: '/index.html',
171-
// responseHttpStatus: 200,
172-
// ttl: cdk.Duration.minutes(0),
173-
// },
174-
// ],
175-
})
176-
177110
// Create a Route53 record pointing to the CloudFront distribution
178111
new route53.ARecord(this, 'AliasRecord', {
179112
recordName: domainName,
180113
zone,
181114
target: route53.RecordTarget.fromAlias(new targets.CloudFrontTarget(distribution)),
182115
})
183116

184-
// Create a Route53 record pointing to the Docs CloudFront distribution
185-
new route53.ARecord(this, 'DocsAliasRecord', {
186-
recordName: `${app.subdomains.docs}.${domainName}`,
187-
zone,
188-
target: route53.RecordTarget.fromAlias(new targets.CloudFrontTarget(docsDistribution)),
189-
})
190-
191117
new route53.CnameRecord(this, 'WwwCnameRecord', {
192118
zone,
193119
recordName: 'www',
@@ -210,25 +136,105 @@ export class StacksCloud extends Stack {
210136
destinationBucket: privateBucket,
211137
})
212138

213-
new s3deploy.BucketDeployment(this, 'DeployDocs', {
214-
sources: [s3deploy.Source.asset(docsSource)],
215-
destinationBucket: docsBucket,
216-
distribution: docsDistribution,
217-
distributionPaths: ['/*'],
218-
})
219-
139+
if (shouldDeployDocs()) {
140+
const docsCertificate = new acm.Certificate(this, 'DocsCertificate', {
141+
domainName: `${app.subdomains.docs}.${domainName}`,
142+
validation: acm.CertificateValidation.fromDns(zone),
143+
})
144+
145+
const docsBucket = new s3.Bucket(this, 'DocsBucket', {
146+
bucketName: `docs.${domainName}-${app.env}`,
147+
versioned: true,
148+
removalPolicy: RemovalPolicy.DESTROY,
149+
autoDeleteObjects: true,
150+
})
151+
152+
// Create an S3 bucket for CloudFront access logs
153+
const logBucket = new s3.Bucket(this, 'LogBucket', {
154+
bucketName: `${domainName}-logs-${app.env}`,
155+
removalPolicy: RemovalPolicy.DESTROY,
156+
autoDeleteObjects: true,
157+
objectOwnership: s3.ObjectOwnership.BUCKET_OWNER_PREFERRED,
158+
})
159+
160+
logBucket.addLifecycleRule({
161+
enabled: true,
162+
expiration: Duration.days(30), // TODO: make this configurable
163+
id: 'rule',
164+
})
165+
166+
const docsDistribution = new cloudfront.Distribution(this, 'DocsDistribution', {
167+
domainNames: [`${app.subdomains.docs}.${app.url}`],
168+
defaultRootObject: 'index.html',
169+
comment: `CDN for ${app.subdomains.docs}.${app.url}`,
170+
certificate: docsCertificate,
171+
// originShieldEnabled: true,
172+
enableLogging: true,
173+
logBucket,
174+
httpVersion: cloudfront.HttpVersion.HTTP2_AND_3,
175+
priceClass: cloudfront.PriceClass.PRICE_CLASS_ALL,
176+
enabled: true,
177+
minimumProtocolVersion: cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021,
178+
webAclId: webAcl.attrArn,
179+
enableIpv6: true,
180+
181+
defaultBehavior: {
182+
origin: new origins.S3Origin(docsBucket, {
183+
originAccessIdentity,
184+
}),
185+
compress: true,
186+
allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD,
187+
cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD,
188+
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
189+
cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
190+
},
191+
192+
// errorResponses: [
193+
// {
194+
// httpStatus: 403,
195+
// responsePagePath: '/index.html',
196+
// responseHttpStatus: 200,
197+
// ttl: cdk.Duration.minutes(0),
198+
// },
199+
// {
200+
// httpStatus: 404,
201+
// responsePagePath: '/index.html',
202+
// responseHttpStatus: 200,
203+
// ttl: cdk.Duration.minutes(0),
204+
// },
205+
// ],
206+
})
207+
// Create a Route53 record pointing to the Docs CloudFront distribution
208+
new route53.ARecord(this, 'DocsAliasRecord', {
209+
recordName: `${app.subdomains.docs}.${domainName}`,
210+
zone,
211+
target: route53.RecordTarget.fromAlias(new targets.CloudFrontTarget(docsDistribution)),
212+
})
213+
214+
new s3deploy.BucketDeployment(this, 'DeployDocs', {
215+
sources: [s3deploy.Source.asset(docsSource)],
216+
destinationBucket: docsBucket,
217+
distribution: docsDistribution,
218+
distributionPaths: ['/*'],
219+
})
220+
221+
new Output(this, 'DocsBucketName', {
222+
value: docsBucket.bucketName,
223+
description: 'The name of the docs bucket',
224+
})
225+
226+
// Prints out the web endpoint to the terminal
227+
new Output(this, 'DocsUrl', {
228+
value: `https://${app.subdomains.docs}.${app.url}`,
229+
description: 'The URL of the deployed documentation',
230+
})
231+
}
220232
// Prints out the web endpoint to the terminal
221233
new Output(this, 'AppUrl', {
222234
value: `https://${domainName}`,
223235
description: 'The URL of the deployed application',
224236
})
225237

226-
// Prints out the web endpoint to the terminal
227-
new Output(this, 'DocsUrl', {
228-
value: `https://${app.subdomains.docs}.${app.url}`,
229-
description: 'The URL of the deployed documentation',
230-
})
231-
232238
// Prints out the web endpoint to the terminal
233239
new Output(this, 'VanityUrl', {
234240
value: `https://${distribution.domainName}`,
@@ -242,3 +248,7 @@ export class StacksCloud extends Stack {
242248
// })
243249
}
244250
}
251+
252+
function shouldDeployDocs() {
253+
return hasFiles(projectPath('docs'))
254+
}

0 commit comments

Comments
 (0)