@stacksjs/actions 0.70.45 → 0.70.53
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.
- package/LICENSE.md +21 -0
- package/dist/action.d.ts +104 -17
- package/dist/blog.d.ts +12 -0
- package/dist/build/frontend-static.d.ts +16 -0
- package/dist/chunk-00qp27jy.js +93 -0
- package/dist/{chunk-jd1yzkq5.js → chunk-23thftnv.js} +1 -1
- package/dist/{chunk-jbvvb45k.js → chunk-4qzb8g3z.js} +1 -1
- package/dist/{chunk-s03z9zn3.js → chunk-5dfz9en9.js} +2 -2
- package/dist/{chunk-3beht8ja.js → chunk-5hwp0frq.js} +1 -1
- package/dist/{chunk-cqedfbaf.js → chunk-5pwpk005.js} +2 -2
- package/dist/chunk-604jy79b.js +5 -0
- package/dist/{chunk-yh15ydty.js → chunk-63swek9d.js} +2 -2
- package/dist/chunk-67am4dae.js +688 -0
- package/dist/{chunk-gt77jmb5.js → chunk-8gbewxns.js} +1 -1
- package/dist/chunk-8r76qydb.js +240 -0
- package/dist/{chunk-zbhjh5sz.js → chunk-9x17v4x2.js} +2 -2
- package/dist/chunk-aazd6qpv.js +3 -0
- package/dist/{chunk-n2fd1d0m.js → chunk-ag4fy7cx.js} +1 -1
- package/dist/{chunk-2qchdrf9.js → chunk-badehrwa.js} +1 -1
- package/dist/chunk-dbz9dp2h.js +3 -0
- package/dist/{chunk-v0wnrnaa.js → chunk-e8505qz8.js} +2 -2
- package/dist/chunk-jv7ry09n.js +3 -0
- package/dist/{chunk-w418anbq.js → chunk-jve1p4dz.js} +2 -2
- package/dist/chunk-mcwfmqzb.js +283 -0
- package/dist/chunk-n24m8prb.js +3 -0
- package/dist/{chunk-d5yxdz7e.js → chunk-nm9h5rye.js} +2 -2
- package/dist/{chunk-h0hfqr1p.js → chunk-ny1racy0.js} +2 -2
- package/dist/{chunk-2gh7kgpc.js → chunk-p601xr03.js} +1 -1
- package/dist/{chunk-yvva7qsg.js → chunk-pqnzp7x8.js} +2 -2
- package/dist/chunk-rj1cbghx.js +17 -0
- package/dist/chunk-rzhs51h1.js +3 -0
- package/dist/{chunk-tzx3h4r8.js → chunk-sp5cjdhd.js} +213 -76
- package/dist/chunk-tqax3gbq.js +16 -0
- package/dist/{chunk-c8qt2xst.js → chunk-vsj8ns4p.js} +1 -1
- package/dist/{chunk-zaw01rqz.js → chunk-x8nrbsk1.js} +2 -2
- package/dist/dev/dashboard-utils.d.ts +19 -1
- package/dist/dev/migrate-watcher.d.ts +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/make.d.ts +19 -0
- package/dist/queue/dlq-purge.d.ts +1 -0
- package/dist/queue/dlq-retry.d.ts +1 -0
- package/dist/queue/dlq.d.ts +1 -0
- package/dist/queue/list.d.ts +1 -0
- package/dist/queue/pause.d.ts +1 -0
- package/dist/queue/quarantine.d.ts +1 -0
- package/dist/queue/resume.d.ts +1 -0
- package/dist/queue/unquarantine.d.ts +1 -0
- package/dist/src/action.js +1 -1
- package/dist/src/actions.js +1 -1
- package/dist/src/add.js +1 -1
- package/dist/src/ai/request-model-access.js +1 -1
- package/dist/src/auth/setup.js +82 -24
- package/dist/src/blog.js +102 -0
- package/dist/src/build/core.js +1 -1
- package/dist/src/build/frontend-static.js +9 -0
- package/dist/src/build/views.js +1 -1
- package/dist/src/build.js +1 -1
- package/dist/src/commit.js +1 -1
- package/dist/src/database/seed.js +1 -1
- package/dist/src/deploy/index.js +38 -45
- package/dist/src/dev/api.js +4 -4
- package/dist/src/dev/dashboard-globals.js +1 -1
- package/dist/src/dev/dashboard-utils.js +1 -1
- package/dist/src/dev/dashboard.js +6 -6
- package/dist/src/dev/docs.js +1 -1
- package/dist/src/dev/index.js +1 -1
- package/dist/src/dev/migrate-watcher.js +2 -0
- package/dist/src/dev/views.js +1 -1
- package/dist/src/discover-packages.js +1 -1
- package/dist/src/examples.js +1 -1
- package/dist/src/generate/component-meta.js +1 -1
- package/dist/src/generate/env-files.js +1 -1
- package/dist/src/generate/ide-helpers.js +1 -1
- package/dist/src/generate/index.js +1 -1
- package/dist/src/generate/lib-entries.js +1 -1
- package/dist/src/generate/vscode-custom-data.js +1 -1
- package/dist/src/helpers/component-meta.js +1 -1
- package/dist/src/helpers/index.js +1 -1
- package/dist/src/helpers/lib-entries.js +1 -1
- package/dist/src/helpers/package-json.js +1 -1
- package/dist/src/helpers/utils.js +1 -1
- package/dist/src/helpers/vscode-custom-data.js +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/key-generate.js +1 -1
- package/dist/src/make-command.js +1 -1
- package/dist/src/make-job.js +1 -1
- package/dist/src/make-policy.js +1 -1
- package/dist/src/make-resource.js +1 -1
- package/dist/src/make.js +1 -1
- package/dist/src/migrate/fresh.js +1 -1
- package/dist/src/orm/base.js +1 -1
- package/dist/src/queue/dlq-purge.js +2 -0
- package/dist/src/queue/dlq-retry.js +2 -0
- package/dist/src/queue/dlq.js +5 -0
- package/dist/src/queue/failed.js +4 -4
- package/dist/src/queue/list.js +5 -0
- package/dist/src/queue/pause.js +2 -0
- package/dist/src/queue/quarantine.js +3 -0
- package/dist/src/queue/resume.js +2 -0
- package/dist/src/queue/unquarantine.js +2 -0
- package/dist/src/release.js +1 -1
- package/dist/src/run-action.js +1 -1
- package/dist/src/scaffold-crud.js +1 -1
- package/dist/src/serve/api.js +1 -1
- package/dist/src/setup/index.js +1 -1
- package/dist/src/setup/ssl.js +1 -1
- package/dist/src/stacks.js +1 -1
- package/dist/src/templates.js +1 -1
- package/dist/src/types.js +1 -1
- package/dist/src/upgrade/dependencies.js +1 -1
- package/dist/src/upgrade/framework-utils.js +1 -1
- package/dist/src/upgrade/framework.js +5 -5
- package/dist/src/upgrade/index.js +1 -1
- package/dist/src/upgrade.js +1 -1
- package/dist/upgrade/framework-utils.d.ts +48 -0
- package/package.json +18 -18
- package/dist/chunk-2kaj93p5.js +0 -3
- package/dist/chunk-3086k7zk.js +0 -184
- package/dist/chunk-4fz2qb8b.js +0 -17
- package/dist/chunk-4p0rjazd.js +0 -101
- package/dist/chunk-77pta9ww.js +0 -93
- package/dist/chunk-d4srk6ma.js +0 -3
- package/dist/chunk-h5rff0v9.js +0 -658
- package/dist/chunk-kr2k0h74.js +0 -16
- package/dist/chunk-kzhgexj4.js +0 -3
- package/dist/chunk-sxp97zys.js +0 -3
- package/dist/chunk-vek18p55.js +0 -5
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Open Web Foundation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/action.d.ts
CHANGED
|
@@ -1,51 +1,130 @@
|
|
|
1
|
-
import type { JobOptions, RequestInstance } from '@stacksjs/types';
|
|
2
|
-
|
|
1
|
+
import type { ExtractParams, InferValidations, JobOptions, RequestInstance } from '@stacksjs/types';
|
|
2
|
+
/**
|
|
3
|
+
* Shape of `validations:` on an action. Each entry pairs a
|
|
4
|
+
* ts-validation `Validator<T>` rule with an optional error message.
|
|
5
|
+
*
|
|
6
|
+
* Kept loose at the index-signature level so existing actions with
|
|
7
|
+
* untyped validation objects keep compiling. New code that wants the
|
|
8
|
+
* body-inference benefit (stacksjs/stacks#1851 Phase 2b) declares
|
|
9
|
+
* validations `as const` so {@link InferValidations} can read the
|
|
10
|
+
* concrete rule types.
|
|
11
|
+
*
|
|
12
|
+
* Exported so the router can run validations without redeclaring the
|
|
13
|
+
* type (stacksjs/stacks#1870 R-3 — the previous copy in
|
|
14
|
+
* `stacks-router.ts` would drift out of sync).
|
|
15
|
+
*/
|
|
16
|
+
export declare interface ActionValidations {
|
|
3
17
|
[key: string]: {
|
|
4
18
|
rule: { validate: (value: unknown) => { valid: boolean, errors?: Array<{ message: string }> } }
|
|
5
19
|
message?: string | Record<string, string>
|
|
6
20
|
}
|
|
7
21
|
}
|
|
8
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Shape of {@link validateActionInput}'s return value. Lives here next
|
|
24
|
+
* to {@link ActionValidations} so the router and actions package share
|
|
25
|
+
* a single declaration (stacksjs/stacks#1870 R-3).
|
|
26
|
+
*/
|
|
27
|
+
export declare interface ValidationResult {
|
|
28
|
+
valid: boolean
|
|
29
|
+
errors: Record<string, string[]>
|
|
30
|
+
}
|
|
31
|
+
declare interface ActionOptions<TModel = string, TValidations extends ActionValidations | undefined = undefined, TPath extends string = '',> {
|
|
9
32
|
name?: string
|
|
10
33
|
description?: string
|
|
11
34
|
apiResponse?: boolean
|
|
12
|
-
validations?:
|
|
35
|
+
validations?: TValidations
|
|
13
36
|
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
|
|
14
37
|
rate?: JobOptions['rate']
|
|
15
38
|
tries?: JobOptions['tries']
|
|
16
39
|
backoff?: JobOptions['backoff']
|
|
17
40
|
enabled?: JobOptions['enabled']
|
|
18
|
-
path?:
|
|
41
|
+
path?: TPath
|
|
19
42
|
requestFile?: string
|
|
20
43
|
model?: TModel
|
|
21
|
-
|
|
44
|
+
skipCsrf?: boolean
|
|
45
|
+
csrf?: boolean
|
|
46
|
+
authorize?: (
|
|
47
|
+
request: InferRequest<TModel, TValidations, TPath>,
|
|
48
|
+
) => boolean | Response | Promise<boolean | Response>
|
|
49
|
+
before?: (
|
|
50
|
+
request: InferRequest<TModel, TValidations, TPath>,
|
|
51
|
+
) => void | Response | Promise<void | Response>
|
|
52
|
+
handle: (
|
|
53
|
+
request: InferRequest<TModel, TValidations, TPath>,
|
|
54
|
+
) => ActionResult | Promise<ActionResult>
|
|
55
|
+
dependencies?: () => Record<string, unknown>
|
|
22
56
|
}
|
|
23
57
|
/**
|
|
24
|
-
*
|
|
58
|
+
* Resolve the body shape (`TFields`) for an action's request:
|
|
59
|
+
*
|
|
60
|
+
* 1. If `model:` is a `defineModel()` return, use its row shape —
|
|
61
|
+
* preserves the existing model-aware ergonomics.
|
|
62
|
+
* 2. Else if `validations:` is set as a const, infer the body
|
|
63
|
+
* from each rule's `Validator<T>` output type
|
|
64
|
+
* (stacksjs/stacks#1851 Phase 2b).
|
|
65
|
+
* 3. Else fall back to `Record<string, any>` — bare-typed action
|
|
66
|
+
* with no narrowing.
|
|
67
|
+
*/
|
|
68
|
+
declare type ResolveBody<TModel, TValidations> = TModel extends { _isStacksModel: true }
|
|
69
|
+
? TModel
|
|
70
|
+
: TValidations extends ActionValidations
|
|
71
|
+
? InferValidations<TValidations>
|
|
72
|
+
: Record<string, any>;
|
|
73
|
+
/**
|
|
74
|
+
* Build the request type passed to the action's `handle()`. Combines
|
|
75
|
+
* the body resolution above with path-extracted params from `TPath`
|
|
76
|
+
* (stacksjs/stacks#1851 Phase 2a).
|
|
77
|
+
*/
|
|
78
|
+
declare type InferRequest<TModel, TValidations, TPath extends string> = TPath extends ''
|
|
79
|
+
? RequestInstance<ResolveBody<TModel, TValidations>>
|
|
80
|
+
: RequestInstance<ResolveBody<TModel, TValidations>, ExtractParams<TPath>>;
|
|
81
|
+
/**
|
|
82
|
+
* Everything an action's `handle()` is allowed to return. The router's
|
|
83
|
+
* `formatResult()` walks each branch:
|
|
84
|
+
*
|
|
85
|
+
* - `Response` → returned as-is (caller built their own)
|
|
86
|
+
* - `null` / `undefined` → `204` for API clients, empty `200` for browser
|
|
87
|
+
* - object / array (incl. records) → `Response.json(...)`
|
|
88
|
+
* - `string` / `number` / `boolean` → JSON-encoded for API clients, `text/plain`
|
|
89
|
+
* for top-level browser navigations
|
|
90
|
+
* - `ReadableStream` → streamed back (stacksjs/stacks#1870 R-4)
|
|
25
91
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* to
|
|
92
|
+
* Previously typed `Promise<any> | any`, which let non-serializable returns
|
|
93
|
+
* (class instances with cycles, undefined-bearing tuples, etc.) sneak through
|
|
94
|
+
* to runtime. Narrowing here surfaces them at the call site instead.
|
|
95
|
+
* See stacksjs/stacks#1870 R-11.
|
|
29
96
|
*/
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
97
|
+
export type ActionResult = | Response
|
|
98
|
+
| ReadableStream
|
|
99
|
+
| null
|
|
100
|
+
| undefined
|
|
101
|
+
| string
|
|
102
|
+
| number
|
|
103
|
+
| boolean
|
|
104
|
+
| Record<string, unknown>
|
|
105
|
+
| unknown[];
|
|
106
|
+
export declare class Action<TModel = string, TValidations extends ActionValidations | undefined = undefined, TPath extends string = '',> {
|
|
34
107
|
name?: string;
|
|
35
108
|
description?: string;
|
|
109
|
+
apiResponse?: boolean;
|
|
36
110
|
rate?: ActionOptions['rate'];
|
|
37
111
|
tries?: ActionOptions['tries'];
|
|
38
112
|
backoff?: ActionOptions['backoff'];
|
|
39
113
|
enabled?: ActionOptions['enabled'];
|
|
40
|
-
path?: ActionOptions['path'];
|
|
114
|
+
path?: ActionOptions<TModel, TValidations, TPath>['path'];
|
|
41
115
|
method?: ActionOptions['method'];
|
|
42
116
|
validations?: ActionOptions['validations'];
|
|
43
117
|
requestFile?: string;
|
|
44
|
-
|
|
118
|
+
skipCsrf?: boolean;
|
|
119
|
+
csrf?: boolean;
|
|
120
|
+
authorize?: ActionOptions<TModel, TValidations, TPath>['authorize'];
|
|
121
|
+
before?: ActionOptions<TModel, TValidations, TPath>['before'];
|
|
122
|
+
handle: ActionOptions<TModel, TValidations, TPath>['handle'];
|
|
45
123
|
model?: string;
|
|
46
124
|
constructor({
|
|
47
125
|
name,
|
|
48
126
|
description,
|
|
127
|
+
apiResponse,
|
|
49
128
|
validations,
|
|
50
129
|
handle,
|
|
51
130
|
rate,
|
|
@@ -56,5 +135,13 @@ export declare class Action<TModel = string> {
|
|
|
56
135
|
method,
|
|
57
136
|
requestFile,
|
|
58
137
|
model,
|
|
59
|
-
|
|
138
|
+
skipCsrf,
|
|
139
|
+
csrf,
|
|
140
|
+
authorize,
|
|
141
|
+
before,
|
|
142
|
+
dependencies,
|
|
143
|
+
}: ActionOptions<TModel, TValidations, TPath>);
|
|
144
|
+
get deps(): Record<string, unknown>;
|
|
145
|
+
overrideDependencies(overrides: Record<string, unknown>): void;
|
|
146
|
+
resetDependencies(): void;
|
|
60
147
|
}
|
package/dist/blog.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render a blog request via BunPress, or return null to let the caller handle
|
|
3
|
+
* non-blog paths. Handles the listing, posts, the RSS feed, and the sitemap.
|
|
4
|
+
*/
|
|
5
|
+
export declare function renderBlog(req: Request): Promise<Response | null>;
|
|
6
|
+
/**
|
|
7
|
+
* Build the blog to a static directory the same way /docs is built (see
|
|
8
|
+
* config/cloud.ts). Emits clean-URL pages (`<slug>/index.html`), the listing,
|
|
9
|
+
* the RSS feed, and the sitemap. `baseUrl` is the deployed site origin
|
|
10
|
+
* (e.g. https://stacksjs.com) — used for absolute feed/sitemap/share URLs.
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildBlog(options?: { outDir: string, baseUrl?: string }): Promise<void>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the marketing / public static site.
|
|
3
|
+
*
|
|
4
|
+
* Pre-renders `resources/views/index.stx` to a static `index.html`,
|
|
5
|
+
* copies `resources/assets` into `<outDir>/assets`, and copies the
|
|
6
|
+
* project `public/` directory into `<outDir>`. This is the source of
|
|
7
|
+
* truth previously inlined in the AWS deploy action's "Deploy frontend
|
|
8
|
+
* to S3" block; the deploy action now calls this function and uploads
|
|
9
|
+
* the resulting directory to S3.
|
|
10
|
+
*
|
|
11
|
+
* @returns The absolute path to the built static-site directory.
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildFrontendStatic(options?: BuildFrontendStaticOptions): Promise<string>;
|
|
14
|
+
export declare interface BuildFrontendStaticOptions {
|
|
15
|
+
outDir?: string
|
|
16
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{pb as L}from"./chunk-4qzb8g3z.js";import f from"process";import{log as N}from"@stacksjs/cli";import{getErrorMessage as E}from"@stacksjs/utils";async function C(){try{return(await import("./chunk-604jy79b.js")).tsCloud||null}catch{return null}}async function b(){let G=await C();return{name:G?.project?.name||"stacks",region:G?.project?.region||"us-east-1"}}async function v(G){try{let{AWSClient:Q}=await import("@stacksjs/ts-cloud"),J=new Q,_=new URLSearchParams({Action:"GetCallerIdentity",Version:"2011-06-15"}),K=await J.request({service:"sts",region:G,method:"POST",path:"/",body:_.toString()}),j=String(K).match(/<Account>(\d+)<\/Account>/);if(j&&j[1])return j[1];return f.env.AWS_ACCOUNT_ID||""}catch(Q){return f.env.AWS_ACCOUNT_ID||""}}async function p(G){let{environment:Q}=G,J=await C();if(!J)throw Error("Cloud configuration not found. Ensure config/cloud.ts exports tsCloud.");let{InfrastructureGenerator:_}=await import("@stacksjs/ts-cloud"),j=new _({config:J,environment:Q}).generate().getBuilder().build();return JSON.stringify(j)}function S(G){let Q={green:"\x1B[32m",yellow:"\x1B[33m",red:"\x1B[31m",cyan:"\x1B[36m",gray:"\x1B[90m",reset:"\x1B[0m"};if(G.includes("COMPLETE")&&!G.includes("ROLLBACK"))return`${Q.green}${G}${Q.reset}`;if(G.includes("IN_PROGRESS"))return`${Q.yellow}${G}${Q.reset}`;if(G.includes("FAILED")||G.includes("ROLLBACK"))return`${Q.red}${G}${Q.reset}`;if(G.includes("DELETE"))return`${Q.gray}${G}${Q.reset}`;return G}async function k(G){let{region:Q,domain:J,sslDomains:_,hostedZoneId:K,albDnsName:j,stackName:Y}=G;console.log(""),console.log("Setting up SSL certificate...");try{let{Route53Client:$,ACMClient:w,AWSClient:F}=await import("@stacksjs/ts-cloud"),P=new $(Q),V=new w(Q),W=new F;console.log(` Requesting SSL certificate for ${J}...`);let Z=await V.requestCertificate({DomainName:_[0]??J,SubjectAlternativeNames:_.length>1?_.slice(1):void 0,ValidationMethod:"DNS"});console.log(` Certificate ARN: ${Z.CertificateArn}`),await new Promise((R)=>setTimeout(R,5000));let U=await V.describeCertificate({CertificateArn:Z.CertificateArn});console.log(" Adding DNS validation records...");for(let R of U.DomainValidationOptions||[])if(R.ResourceRecord)await P.changeResourceRecordSets({HostedZoneId:K,ChangeBatch:{Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:R.ResourceRecord.Name,Type:"CNAME",TTL:300,ResourceRecords:[{Value:R.ResourceRecord.Value}]}}]}});console.log("\u2713 Validation records added"),console.log(" Waiting for certificate validation (this may take 1-5 minutes)...");for(let R=0;R<30;R++){let M=await V.describeCertificate({CertificateArn:Z.CertificateArn});if(M.Status==="ISSUED"){console.log("\u2713 Certificate issued!");let{AWSCloudFormationClient:A}=await import("@stacksjs/ts-cloud"),B=await new A(Q).listStackResources(Y),I=B.StackResourceSummaries.find((O)=>O.LogicalResourceId==="ApplicationLoadBalancer")?.PhysicalResourceId,X=B.StackResourceSummaries.find((O)=>O.LogicalResourceId==="ECSTargetGroup")?.PhysicalResourceId||B.StackResourceSummaries.find((O)=>O.LogicalResourceId==="WebTargetGroup")?.PhysicalResourceId;if(I&&X){console.log(" Creating HTTPS listener...");let O=new URLSearchParams({Action:"CreateListener",LoadBalancerArn:I,Protocol:"HTTPS",Port:"443","Certificates.member.1.CertificateArn":Z.CertificateArn,"DefaultActions.member.1.Type":"forward","DefaultActions.member.1.TargetGroupArn":X,Version:"2015-12-01"});await W.request({service:"elasticloadbalancing",region:Q,method:"POST",path:"/",body:O.toString()}),console.log("\u2713 HTTPS listener created!"),console.log(" Configuring HTTP to HTTPS redirect...");let h=new URLSearchParams({Action:"DescribeListeners",LoadBalancerArn:I,Version:"2015-12-01"}),H=await W.request({service:"elasticloadbalancing",region:Q,method:"POST",path:"/",body:h.toString()}),x=H?.DescribeListenersResponse?.DescribeListenersResult?.Listeners?.member||H?.DescribeListenersResult?.Listeners?.member,T=(Array.isArray(x)?x:x?[x]:[]).find((D)=>D.Port==="80"||D.Port===80);if(T){let D=new URLSearchParams({Action:"ModifyListener",ListenerArn:T.ListenerArn,"DefaultActions.member.1.Type":"redirect","DefaultActions.member.1.RedirectConfig.Protocol":"HTTPS","DefaultActions.member.1.RedirectConfig.Port":"443","DefaultActions.member.1.RedirectConfig.StatusCode":"HTTP_301",Version:"2015-12-01"});await W.request({service:"elasticloadbalancing",region:Q,method:"POST",path:"/",body:D.toString()}),console.log("\u2713 HTTP to HTTPS redirect configured!")}}let z=B.StackResourceSummaries.find((O)=>O.LogicalResourceId==="CloudFrontDistribution")?.PhysicalResourceId;if(z){console.log(" Updating CloudFront distribution with SSL certificate...");let O=await W.request({service:"cloudfront",region:"us-east-1",method:"GET",path:`/2020-05-31/distribution/${z}/config`}),h=O._headers?.etag||O._headers?.ETag,H=O.DistributionConfig;if(H&&h){H.Aliases={Quantity:_.length,Items:_},H.ViewerCertificate={ACMCertificateArn:Z.CertificateArn,SSLSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021",CloudFrontDefaultCertificate:!1};let x=`<?xml version="1.0" encoding="UTF-8"?>
|
|
3
|
+
<DistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2020-05-31/">
|
|
4
|
+
<CallerReference>${H.CallerReference}</CallerReference>
|
|
5
|
+
<Aliases>
|
|
6
|
+
<Quantity>${_.length}</Quantity>
|
|
7
|
+
<Items>
|
|
8
|
+
${_.map((q)=>` <CNAME>${q}</CNAME>`).join(`
|
|
9
|
+
`)}
|
|
10
|
+
</Items>
|
|
11
|
+
</Aliases>
|
|
12
|
+
<DefaultRootObject>${H.DefaultRootObject||"index.html"}</DefaultRootObject>
|
|
13
|
+
<Origins>
|
|
14
|
+
<Quantity>${H.Origins?.Quantity||0}</Quantity>
|
|
15
|
+
<Items>
|
|
16
|
+
${(H.Origins?.Items||[]).map((q)=>` <Origin>
|
|
17
|
+
<Id>${q.Id}</Id>
|
|
18
|
+
<DomainName>${q.DomainName}</DomainName>
|
|
19
|
+
${q.OriginPath?`<OriginPath>${q.OriginPath}</OriginPath>`:"<OriginPath></OriginPath>"}
|
|
20
|
+
${q.S3OriginConfig?`<S3OriginConfig><OriginAccessIdentity>${q.S3OriginConfig.OriginAccessIdentity||""}</OriginAccessIdentity></S3OriginConfig>`:""}
|
|
21
|
+
${q.CustomOriginConfig?`<CustomOriginConfig>
|
|
22
|
+
<HTTPPort>${q.CustomOriginConfig.HTTPPort}</HTTPPort>
|
|
23
|
+
<HTTPSPort>${q.CustomOriginConfig.HTTPSPort}</HTTPSPort>
|
|
24
|
+
<OriginProtocolPolicy>${q.CustomOriginConfig.OriginProtocolPolicy}</OriginProtocolPolicy>
|
|
25
|
+
<OriginSslProtocols><Quantity>${q.CustomOriginConfig.OriginSslProtocols?.Quantity||1}</Quantity><Items>${(q.CustomOriginConfig.OriginSslProtocols?.Items||["TLSv1.2"]).map((T)=>`<SslProtocol>${T}</SslProtocol>`).join("")}</Items></OriginSslProtocols>
|
|
26
|
+
</CustomOriginConfig>`:""}
|
|
27
|
+
${q.OriginAccessControlId?`<OriginAccessControlId>${q.OriginAccessControlId}</OriginAccessControlId>`:""}
|
|
28
|
+
<ConnectionAttempts>${q.ConnectionAttempts||3}</ConnectionAttempts>
|
|
29
|
+
<ConnectionTimeout>${q.ConnectionTimeout||10}</ConnectionTimeout>
|
|
30
|
+
</Origin>`).join(`
|
|
31
|
+
`)}
|
|
32
|
+
</Items>
|
|
33
|
+
</Origins>
|
|
34
|
+
<DefaultCacheBehavior>
|
|
35
|
+
<TargetOriginId>${H.DefaultCacheBehavior?.TargetOriginId}</TargetOriginId>
|
|
36
|
+
<ViewerProtocolPolicy>${H.DefaultCacheBehavior?.ViewerProtocolPolicy||"redirect-to-https"}</ViewerProtocolPolicy>
|
|
37
|
+
<AllowedMethods>
|
|
38
|
+
<Quantity>${H.DefaultCacheBehavior?.AllowedMethods?.Quantity||3}</Quantity>
|
|
39
|
+
<Items>${(H.DefaultCacheBehavior?.AllowedMethods?.Items||["GET","HEAD","OPTIONS"]).map((q)=>`<Method>${q}</Method>`).join("")}</Items>
|
|
40
|
+
<CachedMethods>
|
|
41
|
+
<Quantity>${H.DefaultCacheBehavior?.AllowedMethods?.CachedMethods?.Quantity||2}</Quantity>
|
|
42
|
+
<Items>${(H.DefaultCacheBehavior?.AllowedMethods?.CachedMethods?.Items||["GET","HEAD"]).map((q)=>`<Method>${q}</Method>`).join("")}</Items>
|
|
43
|
+
</CachedMethods>
|
|
44
|
+
</AllowedMethods>
|
|
45
|
+
<Compress>${H.DefaultCacheBehavior?.Compress!==!1}</Compress>
|
|
46
|
+
<CachePolicyId>${H.DefaultCacheBehavior?.CachePolicyId||"658327ea-f89d-4fab-a63d-7e88639e58f6"}</CachePolicyId>
|
|
47
|
+
${H.DefaultCacheBehavior?.OriginRequestPolicyId?`<OriginRequestPolicyId>${H.DefaultCacheBehavior.OriginRequestPolicyId}</OriginRequestPolicyId>`:""}
|
|
48
|
+
</DefaultCacheBehavior>
|
|
49
|
+
<CacheBehaviors>
|
|
50
|
+
<Quantity>${H.CacheBehaviors?.Quantity||0}</Quantity>
|
|
51
|
+
${H.CacheBehaviors?.Quantity>0?`<Items>
|
|
52
|
+
${(H.CacheBehaviors?.Items||[]).map((q)=>` <CacheBehavior>
|
|
53
|
+
<PathPattern>${q.PathPattern}</PathPattern>
|
|
54
|
+
<TargetOriginId>${q.TargetOriginId}</TargetOriginId>
|
|
55
|
+
<ViewerProtocolPolicy>${q.ViewerProtocolPolicy}</ViewerProtocolPolicy>
|
|
56
|
+
<AllowedMethods>
|
|
57
|
+
<Quantity>${q.AllowedMethods?.Quantity||3}</Quantity>
|
|
58
|
+
<Items>${(q.AllowedMethods?.Items||["GET","HEAD","OPTIONS"]).map((T)=>`<Method>${T}</Method>`).join("")}</Items>
|
|
59
|
+
<CachedMethods>
|
|
60
|
+
<Quantity>${q.AllowedMethods?.CachedMethods?.Quantity||2}</Quantity>
|
|
61
|
+
<Items>${(q.AllowedMethods?.CachedMethods?.Items||["GET","HEAD"]).map((T)=>`<Method>${T}</Method>`).join("")}</Items>
|
|
62
|
+
</CachedMethods>
|
|
63
|
+
</AllowedMethods>
|
|
64
|
+
<Compress>${q.Compress!==!1}</Compress>
|
|
65
|
+
<CachePolicyId>${q.CachePolicyId}</CachePolicyId>
|
|
66
|
+
${q.OriginRequestPolicyId?`<OriginRequestPolicyId>${q.OriginRequestPolicyId}</OriginRequestPolicyId>`:""}
|
|
67
|
+
</CacheBehavior>`).join(`
|
|
68
|
+
`)}
|
|
69
|
+
</Items>`:""}
|
|
70
|
+
</CacheBehaviors>
|
|
71
|
+
<CustomErrorResponses>
|
|
72
|
+
<Quantity>${H.CustomErrorResponses?.Quantity||0}</Quantity>
|
|
73
|
+
${H.CustomErrorResponses?.Quantity>0?`<Items>
|
|
74
|
+
${(H.CustomErrorResponses?.Items||[]).map((q)=>` <CustomErrorResponse>
|
|
75
|
+
<ErrorCode>${q.ErrorCode}</ErrorCode>
|
|
76
|
+
<ResponsePagePath>${q.ResponsePagePath}</ResponsePagePath>
|
|
77
|
+
<ResponseCode>${q.ResponseCode}</ResponseCode>
|
|
78
|
+
<ErrorCachingMinTTL>${q.ErrorCachingMinTTL}</ErrorCachingMinTTL>
|
|
79
|
+
</CustomErrorResponse>`).join(`
|
|
80
|
+
`)}
|
|
81
|
+
</Items>`:""}
|
|
82
|
+
</CustomErrorResponses>
|
|
83
|
+
<Comment>${H.Comment||""}</Comment>
|
|
84
|
+
<PriceClass>${H.PriceClass||"PriceClass_100"}</PriceClass>
|
|
85
|
+
<Enabled>${H.Enabled!==!1}</Enabled>
|
|
86
|
+
<ViewerCertificate>
|
|
87
|
+
<ACMCertificateArn>${Z.CertificateArn}</ACMCertificateArn>
|
|
88
|
+
<SSLSupportMethod>sni-only</SSLSupportMethod>
|
|
89
|
+
<MinimumProtocolVersion>TLSv1.2_2021</MinimumProtocolVersion>
|
|
90
|
+
</ViewerCertificate>
|
|
91
|
+
<HttpVersion>${H.HttpVersion||"http2and3"}</HttpVersion>
|
|
92
|
+
<IsIPV6Enabled>${H.IsIPV6Enabled!==!1}</IsIPV6Enabled>
|
|
93
|
+
</DistributionConfig>`;await W.request({service:"cloudfront",region:"us-east-1",method:"PUT",path:`/2020-05-31/distribution/${z}/config`,headers:{"Content-Type":"application/xml","If-Match":h},body:x}),console.log("\u2713 CloudFront distribution updated with SSL certificate!")}}console.log(""),console.log(`\u2713 SSL setup complete! https://${J} should be accessible shortly.`),console.log("");return}if(M.Status==="FAILED"){console.log("\u2717 Certificate validation failed!");return}await new Promise((A)=>setTimeout(A,1e4))}console.log("\u26A0 Certificate validation timed out. Please check AWS Console.")}catch($){console.log(`\u2717 DNS/SSL setup failed: ${E($)}`),console.log(" You can manually set up DNS and SSL using ./buddy cloud:ssl")}}async function l(G){let{environment:Q,region:J,waitForCompletion:_=!0,verbose:K=!1}=G,Y=(await b()).name,$=`${Y}-cloud`;if(K)console.log(`Deploying ${$} to ${J}...`);try{let{AWSCloudFormationClient:w}=await import("@stacksjs/ts-cloud"),F=new w(J),P=await C(),V=P?.infrastructure?.compute?.mode||P?.mode||"server";if(K)console.log(`Generating CloudFormation template (${V} mode)...`);let W=await p({environment:Q,projectName:Y}),Z=51200,U;if(Buffer.byteLength(W,"utf-8")>Z){if(K)console.log(`Template exceeds inline limit (${Buffer.byteLength(W,"utf-8")} bytes), uploading to S3...`);let{S3Client:X,AWSClient:z}=await import("@stacksjs/ts-cloud"),O=new X(J),h=new z,H=`${Y}-cf-templates-${J}`;try{await h.request({service:"s3",region:J,method:"HEAD",path:`/${H}`,bucket:H})}catch{let q=J==="us-east-1"?"":`<CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><LocationConstraint>${J}</LocationConstraint></CreateBucketConfiguration>`;await h.request({service:"s3",region:J,method:"PUT",path:`/${H}`,bucket:H,body:q||void 0})}let x=`${$}/template-${Date.now()}.json`;if(await O.putObject({bucket:H,key:x,body:W,contentType:"application/json"}),U=`https://${H}.s3.${J}.amazonaws.com/${x}`,K)console.log(`Template uploaded to: ${U}`)}let R=U?{templateUrl:U}:{templateBody:W},M=!1,A=!1;try{let X=(await F.describeStacks({stackName:$})).Stacks?.[0];if(X&&X.StackStatus){if(K)console.log(`Current status: ${S(X.StackStatus)}`);if(M=!0,A=!0,X.StackStatus.endsWith("_IN_PROGRESS")){console.log(`Stack is busy (${X.StackStatus}). Waiting for current operation to finish...`);let z=X.StackStatus.startsWith("DELETE")?"stack-delete-complete":X.StackStatus.startsWith("CREATE")?"stack-create-complete":"stack-update-complete";try{await F.waitForStack($,z)}catch{}try{let O=(await F.describeStacks({stackName:$})).Stacks?.[0];if(!O||!O.StackStatus)M=!1,A=!1;else{if(K)console.log(`Stack settled to: ${S(O.StackStatus)}`);X.StackStatus=O.StackStatus}}catch{M=!1,A=!1}}if(X.StackStatus==="UPDATE_ROLLBACK_COMPLETE")console.log("Stack rolled back from a previous update. Re-deploying...");else if(X.StackStatus==="DELETE_COMPLETE")M=!1,A=!1;else if(X.StackStatus==="ROLLBACK_COMPLETE"||X.StackStatus==="ROLLBACK_FAILED"||X.StackStatus==="CREATE_FAILED"){console.log(`Stack is in ${X.StackStatus} state. Deleting before recreating...`),await F.deleteStack($),await F.waitForStack($,"stack-delete-complete"),console.log("Cleaning up retained resources...");try{let{S3Client:z}=await import("@stacksjs/ts-cloud"),O=new z(J),h=await v(J),H=`${Y}-${Q}-assets-${h}`,x=`${Y}-${Q}-frontend-${h}`;if(K)console.log(` Checking bucket: ${H}`);try{await O.emptyAndDeleteBucket(H),console.log(`\u2713 Deleted retained bucket: ${H}`)}catch(q){if(!q.message?.includes("NoSuchBucket")&&!q.message?.includes("does not exist"))console.log(`\u26A0 Could not delete assets bucket: ${q.message}`);else if(K)console.log(" No retained assets bucket to clean up")}if(K)console.log(` Checking bucket: ${x}`);try{await O.emptyAndDeleteBucket(x),console.log(`\u2713 Deleted retained bucket: ${x}`)}catch(q){if(!q.message?.includes("NoSuchBucket")&&!q.message?.includes("does not exist"))console.log(`\u26A0 Could not delete frontend bucket: ${q.message}`);else if(K)console.log(" No retained frontend bucket to clean up")}}catch(z){console.log(`\u26A0 Cleanup error: ${z.message}`)}M=!1,A=!1}}}catch{M=!1}if(M){console.log("Updating stack..."),console.log("");try{let X=U?{templateURL:U}:{templateBody:W};if(await F.updateStack({stackName:$,...X,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Environment",Value:Q},{Key:"Project",Value:Y},{Key:"ManagedBy",Value:"stacks"}]}),_)console.log(` ${"Resource".padEnd(35)} ${"Type".padEnd(30)} Status`),console.log(" "+"\u2500".repeat(85)),await F.waitForStack($,"stack-update-complete"),console.log("")}catch(X){if(E(X)?.includes("No updates are to be performed"))console.log("\u2713 Stack is up to date (no changes)");else throw X}}else{console.log("Checking for retained resources...");try{let{S3Client:O}=await import("@stacksjs/ts-cloud"),h=new O(J),H=await v(J),x=`${Y}-${Q}-assets-${H}`,q=`${Y}-${Q}-frontend-${H}`;if(K)console.log(` Checking bucket: ${x}`);try{await h.emptyAndDeleteBucket(x),console.log(`\u2713 Cleaned up existing bucket: ${x}`)}catch(T){if(!T.message?.includes("NoSuchBucket")&&!T.message?.includes("does not exist"))console.log(`\u26A0 Could not delete assets bucket: ${T.message}`);else if(K)console.log(" No existing assets bucket to clean up")}if(K)console.log(` Checking bucket: ${q}`);try{await h.emptyAndDeleteBucket(q),console.log(`\u2713 Cleaned up existing bucket: ${q}`)}catch(T){if(!T.message?.includes("NoSuchBucket")&&!T.message?.includes("does not exist"))console.log(`\u26A0 Could not delete frontend bucket: ${T.message}`);else if(K)console.log(" No existing frontend bucket to clean up")}}catch(O){console.log(`\u26A0 Pre-deployment cleanup error: ${O.message}`)}console.log("Creating stack..."),console.log("");let X=U?{templateURL:U}:{templateBody:W},z=await F.createStack({stackName:$,...X,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Environment",Value:Q},{Key:"Project",Value:Y},{Key:"ManagedBy",Value:"stacks"}],onFailure:"ROLLBACK",timeoutInMinutes:30});if(K)console.log(`Stack ID: ${z}`);if(_)console.log(` ${"Resource".padEnd(35)} ${"Type".padEnd(30)} Status`),console.log(" "+"\u2500".repeat(85)),await F.waitForStack($,"stack-create-complete"),console.log("")}let y=P?.infrastructure?.dns?.domain||"stacksjs.com",B=P?.infrastructure?.ssl||{enabled:!0,domains:[]},I=B.domains||[y,`www.${y}`];try{let X=(await F.describeStacks({stackName:$})).Stacks?.[0];if(X&&X.StackStatus){let z={};for(let O of X.Outputs||[])if(O.OutputKey&&O.OutputValue)z[O.OutputKey]=O.OutputValue;if(console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"),console.log(""),console.log(" \u2713 Infrastructure deployed successfully"),console.log(""),console.log(` Stack: ${$}`),console.log(` Status: ${X.StackStatus}`),console.log(` Domain: https://${y}`),z.LoadBalancerDNS)console.log(` Load Balancer: ${z.LoadBalancerDNS}`);if(z.WebServerPublicIP)console.log(` Server IP: ${z.WebServerPublicIP}`);if(z.AssetsBucketName&&K)console.log(` Assets: ${z.AssetsBucketName}`);if(console.log(""),console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"),console.log(""),B.enabled&&P?.infrastructure?.dns?.hostedZoneId&&z.LoadBalancerDNS)await k({region:J,domain:y,sslDomains:I,hostedZoneId:P.infrastructure.dns.hostedZoneId,albDnsName:z.LoadBalancerDNS,stackName:$});else if(!B.certificateArn&&K)console.log(" Next steps:"),console.log(" 1. DNS records need to be updated to point to the ALB"),console.log(" 2. SSL certificate needs to be requested and attached"),console.log(` Run: ./buddy cloud:ssl to set up SSL for ${y}`),console.log("")}}catch{}}catch(w){throw console.error(`Stack deployment failed: ${E(w)}`),w}}async function u(G){let{environment:Q,region:J,buildDir:_}=G,j=(await b()).name;N.info(`Deploying frontend from ${_} to ${Q} in ${J}...`);try{let{S3Client:Y,AWSCloudFormationClient:$}=await import("@stacksjs/ts-cloud"),w=new Y(J),F=new $(J),P=`${j}-cloud`,W=(await F.describeStacks({stackName:P})).Stacks?.[0]?.Outputs?.find((Z)=>Z.OutputKey==="AssetsBucketName")?.OutputValue;if(!W)throw Error("Assets bucket not found in stack outputs");N.info(`Syncing ${_} to s3://${W}/...`),await w.sync({source:_,bucket:W,delete:!0,cacheControl:"max-age=31536000"}),N.success("Frontend deployment completed!")}catch(Y){throw N.error(`Frontend deployment failed: ${E(Y)}`),Y}}async function c(G){let{environment:Q,region:J}=G,j=`${(await b()).name}-cloud`,{AWSCloudFormationClient:Y}=await import("@stacksjs/ts-cloud"),$=new Y(J);try{let w=(await $.describeStacks({stackName:j})).Stacks?.[0];if(!w||!w.StackStatus)return{status:"NOT_FOUND",outputs:{}};let F={};for(let P of w.Outputs||[])if(P.OutputKey&&P.OutputValue)F[P.OutputKey]=P.OutputValue;return{status:w.StackStatus,outputs:F}}catch{return{status:"NOT_FOUND",outputs:{}}}}async function i(G){let{environment:Q,region:J,verbose:_}=G,K=await b(),Y=`${K.name}-cloud`;console.log(`Undeploying ${Y} from ${J}...`),console.log("");try{let{AWSCloudFormationClient:$,AWSClient:w}=await import("@stacksjs/ts-cloud"),F=new $(J),P=!1;try{let V=(await F.describeStacks({stackName:Y})).Stacks?.[0];if(V&&V.StackStatus){if(console.log(`Current status: ${S(V.StackStatus)}`),P=!0,V.StackStatus.endsWith("_IN_PROGRESS")){console.log(`Waiting for current operation (${V.StackStatus}) to finish...`);let W=V.StackStatus.startsWith("DELETE")?"stack-delete-complete":V.StackStatus.startsWith("CREATE")?"stack-create-complete":"stack-update-complete";try{await F.waitForStack(Y,W)}catch{}try{let Z=(await F.describeStacks({stackName:Y})).Stacks?.[0];if(!Z||!Z.StackStatus||Z.StackStatus==="DELETE_COMPLETE"){console.log("Stack was already deleted during the in-progress operation.");return}}catch{console.log("Stack was already deleted during the in-progress operation.");return}}if(V.StackStatus==="DELETE_COMPLETE")P=!1}}catch{P=!1}if(!P){console.log(`Stack ${Y} does not exist. Nothing to undeploy.`);return}if(_)console.log("Checking for resources to clean up before deletion...");try{let V=new w,{AWSCloudFormationClient:W}=await import("@stacksjs/ts-cloud"),M=((await new W(J).listStackResources(Y)).StackResourceSummaries||[]).find((A)=>A.LogicalResourceId==="ApplicationLoadBalancer");if(M?.PhysicalResourceId){let y={Action:"DescribeListeners",LoadBalancerArn:M.PhysicalResourceId,Version:"2015-12-01"},B=await V.request({service:"elasticloadbalancing",region:J,method:"POST",path:"/",body:new URLSearchParams(y).toString()}),I=B?.DescribeListenersResult?.Listeners?.member||B?.DescribeListenersResponse?.DescribeListenersResult?.Listeners?.member,X=Array.isArray(I)?I:I?[I]:[],z=0;for(let O of X)if(O.Protocol==="HTTPS"){if(_)console.log(` Removing HTTPS listener on port ${O.Port}...`);let h={Action:"DeleteListener",ListenerArn:O.ListenerArn,Version:"2015-12-01"};await V.request({service:"elasticloadbalancing",region:J,method:"POST",path:"/",body:new URLSearchParams(h).toString()}),z++}if(z>0&&_)console.log(`\u2713 Cleaned up ${z} HTTPS listener(s)`),await new Promise((O)=>setTimeout(O,2000))}}catch(V){if(_)console.log(`Warning: ${V.message}`)}console.log("Deleting stack..."),console.log(""),await F.deleteStack(Y),console.log(` ${"Resource".padEnd(35)} ${"Type".padEnd(30)} Status`),console.log(" "+"\u2500".repeat(85)),await F.waitForStack(Y,"stack-delete-complete");try{let{S3Client:V}=await import("@stacksjs/ts-cloud"),W=new V(J),Z=await v(J),U=`${K.name}-${Q}-assets-${Z}`,R=`${K.name}-${Q}-frontend-${Z}`;console.log("Cleaning up retained buckets...");try{await W.emptyAndDeleteBucket(U),console.log("\u2713 Assets bucket deleted successfully")}catch(M){if(!M.message?.includes("NoSuchBucket")&&!M.message?.includes("does not exist"))console.log(`\u26A0 Could not delete assets bucket: ${M.message}`);else console.log("\u2713 No retained assets bucket to clean up")}try{await W.emptyAndDeleteBucket(R),console.log("\u2713 Frontend bucket deleted successfully")}catch(M){if(!M.message?.includes("NoSuchBucket")&&!M.message?.includes("does not exist"))console.log(`\u26A0 Could not delete frontend bucket: ${M.message}`);else console.log("\u2713 No retained frontend bucket to clean up")}}catch(V){console.log(`\u26A0 Cleanup error: ${V.message}`)}console.log(""),console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"),console.log(""),console.log(" \u2713 Infrastructure removed successfully"),console.log(""),console.log(` Stack: ${Y}`),console.log(` Environment: ${Q}`),console.log(` Region: ${J}`),console.log(""),console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"),console.log("")}catch($){let w=String(E($)||$);if(w.includes("does not exist")){console.log(""),console.log("\u2713 Stack already deleted or does not exist.");return}if($.code==="DELETE_FAILED"||w.includes("DELETE_FAILED")){console.log(""),console.log("Some resources could not be deleted automatically"),console.log("Identifying resources to retain...");let{AWSCloudFormationClient:F}=await import("@stacksjs/ts-cloud"),P=new F(J);try{let Z=((await P.listStackResources(Y)).StackResourceSummaries||[]).filter((U)=>U.ResourceStatus==="DELETE_FAILED").map((U)=>U.LogicalResourceId);if(Z.length>0){console.log(`Retaining ${Z.length} resource(s):`),Z.forEach((M)=>console.log(` - ${M}`)),console.log(""),console.log("Retrying deletion with retained resources..."),await P.deleteStack(Y,void 0,Z);let{AWSCloudFormationClient:U}=await import("@stacksjs/ts-cloud");await new U(J).waitForStack(Y,"stack-delete-complete"),console.log(""),console.log("\u2713 Stack removed (with retained resources)"),console.log(""),console.log("Note: Some resources were retained and may need manual cleanup."),console.log("Run `./buddy cloud:cleanup` to clean up remaining resources.");return}}catch(V){if(String(V.message||V).includes("does not exist")){console.log(""),console.log("\u2713 Stack deleted successfully!");return}throw V}}throw console.error(`Stack deletion failed: ${E($)}`),$}}export{i as undeployStack,c as getDeploymentStatus,l as deployStack,u as deployFrontend};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import{installPackage as t}from"@stacksjs/cli";async function o(a){if(a?.table)await n();if(a?.calendar)await s()}async function r(a){return await o(a)}async function n(){await t("@stacksjs/table")}async function s(){await t("@stacksjs/calendar")}async function d(a){for(let i of a)await t(i)}
|
|
3
|
-
export{o as
|
|
3
|
+
export{o as hb,r as ib,n as jb,s as kb,d as lb};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var j=Object.create;var{getPrototypeOf:k,defineProperty:f,getOwnPropertyNames:l}=Object;var m=Object.prototype.hasOwnProperty;function n(a){return this[a]}var o,p,s=(a,b,c)=>{var g=a!=null&&typeof a==="object";if(g){var h=b?o??=new WeakMap:p??=new WeakMap,i=h.get(a);if(i)return i}c=a!=null?j(k(a)):{};let d=b||!a||!a.__esModule?f(c,"default",{value:a,enumerable:!0}):c;for(let e of l(a))if(!m.call(d,e))f(d,e,{get:n.bind(a,e),enumerable:!0});if(g)h.set(a,d);return d};var t=(a,b)=>()=>(b||a((b={exports:{}}).exports,b),b.exports);var q=(a)=>a;function r(a,b){this[a]=q.bind(null,b)}var u=(a,b)=>{for(var c in b)f(a,c,{get:b[c],enumerable:!0,configurable:!0,set:r.bind(b,c)})};var v=import.meta.require;
|
|
3
|
-
export{s as
|
|
3
|
+
export{s as mb,t as nb,u as ob,v as pb};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
3
|
-
`)}var OJ=null;async function J8(){if(!OJ){let J=await import("./chunk-
|
|
2
|
+
import{mb as v0,pb as j}from"./chunk-4qzb8g3z.js";import{execFile as f0,spawn as m0}from"child_process";import{mkdtempSync as p0,readFileSync as c0,writeFileSync as d0}from"fs";import{tmpdir as l0}from"os";import{join as TJ}from"path";import{promisify as n0}from"util";import{existsSync as lJ}from"fs";import{exec as i0,spawn as e}from"child_process";import{chmodSync as o,copyFileSync as d,cpSync as o0,createWriteStream as a0,existsSync as NJ,mkdirSync as P,mkdtempSync as kJ,rmSync as l,writeFileSync as g}from"fs";import{homedir as t0,tmpdir as IJ}from"os";import{basename as e0,join as L}from"path";import{EventEmitter as F8}from"events";import{EventEmitter as T8}from"events";import{createReadStream as C0,createWriteStream as m$,existsSync as Z0,mkdirSync as X0,readFileSync as SJ,statSync as Y0,unlinkSync as p,writeFileSync as p$}from"fs";import{join as MJ,basename as c$,dirname as EJ}from"path";import{execFileSync as S,spawn as i}from"child_process";import{createHash as RJ}from"crypto";import{EventEmitter as d$}from"events";var h0=Object.defineProperty,u0=(J)=>J;function g0(J,$){this[J]=u0.bind(null,$)}var q0=(J,$)=>{for(var Z in $)h0(J,Z,{get:$[Z],enumerable:!0,configurable:!0,set:g0.bind($,Z)})};function s0(J){if(J){if(!lJ(J))throw Error(`Custom Craft binary path not found: ${J}`);return J}let $=typeof process<"u"?process.env.CRAFT_BIN:void 0;if($){if(!lJ($))throw Error(`CRAFT_BIN points to ${$}, which does not exist`);return $}return"craft"}function r0(J){return[`Craft native binary not found (tried "${J}").`,"","Craft ships through the pantry package registry. Install it with:",""," pantry install craft","","or, in a project, declare it in deps.yaml / pantry.jsonc and run"," pantry install","","See https://pantry.dev/quickstart for pantry installation instructions.","For monorepo development you can also point CRAFT_BIN at a local build."].join(`
|
|
3
|
+
`)}var OJ=null;async function J8(){if(!OJ){let J=await import("./chunk-tqax3gbq.js").then((m)=>v0(m.default,1));OJ=J.default??J}return OJ}async function $8(J){let $=[];if(!J.binaryPath||!NJ(J.binaryPath))throw Error(`Binary not found: ${J.binaryPath}`);let Z=J.platforms||[z0()],X=J.outDir||L(process.cwd(),"dist");if(!NJ(X))P(X,{recursive:!0});for(let Y of Z)switch(Y){case"macos":$.push(...await Z8(J,X));break;case"windows":$.push(...await X8(J,X));break;case"linux":$.push(...await Y8(J,X));break}return $}async function Z8(J,$){let Z=[],{name:X,version:Y,bundleId:Q=`com.myapp.${X.toLowerCase()}`}=J,q=J.macos||{},z=L($,`${X}.app`),H=Q8({name:X,version:Y,bundleId:Q,binaryPath:J.binaryPath,iconPath:J.iconPath,outputPath:z});if(!H.success)return Z.push({success:!1,platform:"macos",format:"app",error:H.error}),Z;if(q.dmg!==!1){let K=await G8({appBundlePath:z,outputPath:L($,`${X}-${Y}.dmg`),volumeName:X});Z.push({success:K.success,platform:"macos",format:"dmg",outputPath:K.outputPath,error:K.error})}if(q.pkg){let K=await U8({appBundlePath:z,outputPath:L($,`${X}-${Y}.pkg`),identifier:Q,version:Y});Z.push({success:K.success,platform:"macos",format:"pkg",outputPath:K.outputPath,error:K.error})}return Z}async function X8(J,$){let Z=[],{name:X,version:Y}=J,Q=J.windows||{};if(Q.msi!==!1){let q=await q8({name:X,version:Y,binaryPath:J.binaryPath,outputPath:L($,`${X}-${Y}.msi`),manufacturer:J.author||"Unknown"});Z.push({success:q.success,platform:"windows",format:"msi",outputPath:q.outputPath,error:q.error})}if(Q.zip||Q.msi===!1){let q=await z8({name:X,version:Y,binaryPath:J.binaryPath,outputPath:L($,`${X}-${Y}-windows.zip`)});Z.push({success:q.success,platform:"windows",format:"zip",outputPath:q.outputPath,error:q.error})}return Z}async function Y8(J,$){let Z=[],{name:X,version:Y}=J,Q=J.linux||{};if(Q.deb!==!1){let q=await K8({name:X,version:Y,binaryPath:J.binaryPath,outputPath:L($,`${X}_${Y}_amd64.deb`),description:J.description||"",maintainer:J.author||"Unknown",dependencies:Q.debDependencies||["libgtk-3-0","libwebkit2gtk-4.1-37"]});Z.push({success:q.success,platform:"linux",format:"deb",outputPath:q.outputPath,error:q.error})}if(Q.rpm){let q=await H8({name:X,version:Y,binaryPath:J.binaryPath,outputPath:L($,`${X}-${Y}-1.x86_64.rpm`),description:J.description||"",requires:Q.rpmDependencies||["gtk3","webkit2gtk3"]});Z.push({success:q.success,platform:"linux",format:"rpm",outputPath:q.outputPath,error:q.error})}if(Q.appImage){let q=await W8({name:X,version:Y,binaryPath:J.binaryPath,outputPath:L($,`${X}-${Y}-x86_64.AppImage`),iconPath:J.iconPath});Z.push({success:q.success,platform:"linux",format:"appimage",outputPath:q.outputPath,error:q.error})}return Z}function Q8(J){try{let{name:$,version:Z,bundleId:X,binaryPath:Y,outputPath:Q}=J;P(L(Q,"Contents","MacOS"),{recursive:!0}),P(L(Q,"Contents","Resources"),{recursive:!0}),d(Y,L(Q,"Contents","MacOS",$)),o(L(Q,"Contents","MacOS",$),493);let q=`<?xml version="1.0" encoding="UTF-8"?>
|
|
4
4
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
5
5
|
<plist version="1.0">
|
|
6
6
|
<dict>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
2
|
+
import{pb as U}from"./chunk-4qzb8g3z.js";import{frameworkPath as E,join as W,path as R,projectPath as L}from"@stacksjs/path";import{existsSync as T,globSync as j,mkdirSync as I,writeFileSync as F}from"@stacksjs/storage";import{readFileSync as v}from"fs";var $=null;async function P(){if($)return $;try{$=(await import("@stacksjs/ts-md")).parseMarkdown}catch{$=(q)=>q}return $}function M(q){if(!q)return"";return $?$(q):q}async function p(){await P();let q=j(["components/*.stx","components/**/*.stx","resources/components/**/*.stx","storage/framework/defaults/resources/components/**/*.stx"],{cwd:L(),absolute:!0}),G=E("component-meta");if(!T(G))I(G,{recursive:!0});for(let X of q){let Q=R.parse(X).name,H=B(X),z=W(G,`${Q}.json`);F(z,JSON.stringify(H,null,2))}}function B(q){let G=v(q,"utf8"),X=b(G),Q=x(G),H=X?D(X):[],z=X?f(X):[],Z=h(Q);return{props:H,events:z,slots:Z}}function b(q){let G=/<script\b[^>]*\bserver\b[^>]*>([\s\S]*?)<\/script>/i.exec(q);if(G?.[1])return G[1];return/<script\b[^>]*>([\s\S]*?)<\/script>/i.exec(q)?.[1]??null}function x(q){let G=/<template\b[^>]*>([\s\S]*?)<\/template>/i.exec(q);if(G?.[1])return G[1];return q.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi,"").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi,"")}function D(q){let G=w(q),X=S(q,G);if(!X)return[];let Q=k(X,G),H=g(q);return Q.map((z)=>{return{name:z.required?z.name:`${z.name}?`,description:M(z.description),type:z.type,default:H[z.name]??z.default??"unknown",required:z.required}})}function w(q){let G=new Map,X=/(?:export\s+)?interface\s+([A-Z][\w$]*)\s*(?:extends\s+[\w$,\s]+)?\s*\{/g,Q;while((Q=X.exec(q))!==null){let z=Q[1];if(!z)continue;let Z=Q.index+Q[0].length,Y=K(q,Z-1,"{","}");if(Y!==null)G.set(z,Y)}let H=/(?:export\s+)?type\s+([A-Z][\w$]*)\s*=\s*\{/g;while((Q=H.exec(q))!==null){let z=Q[1];if(!z)continue;let Z=Q.index+Q[0].length,Y=K(q,Z-1,"{","}");if(Y!==null)G.set(z,Y)}return G}function S(q,G){let Q=/defineProps\s*<\s*([\s\S]+?)\s*>\s*\(/.exec(q),H=Q?.[1]?.trim();if(!Q||!H)return null;if(H.startsWith("{")){let Z=q.indexOf("{",Q.index);return K(q,Z,"{","}")}let z=H.replace(/[<>(].*$/,"").split("&")[0]?.trim();if(!z)return null;return G.get(z)??null}function k(q,G){let X=[],Q=N(q,[";",`
|
|
3
3
|
`]),H="";for(let z of Q){let Z=z.trim();if(!Z)continue;let Y=/^\/\*\*([\s\S]*?)\*\/\s*([\s\S]*)$/.exec(Z);if(Y){H=(Y[1]??"").split(`
|
|
4
4
|
`).map((A)=>A.replace(/^\s*\*\s?/,"")).join(`
|
|
5
5
|
`).trim();let C=(Y[2]??"").trim();if(!C)continue;let J=V(C,H,G);if(J)X.push(J);H="";continue}if(Z.startsWith("//")){H=Z.replace(/^\/\/\s?/,"");continue}let _=V(Z,H,G);if(_)X.push(_);H=""}return X}function V(q,G,X){if(/^[a-zA-Z_$][\w$]*\s*\(/.test(q.trimStart()))return null;let Q=/^([a-zA-Z_$][\w$]*)\s*(\??)\s*:\s*([\s\S]+?)\s*[;,]?\s*$/.exec(q);if(!Q)return null;let H=Q[1],z=Q[2]??"",Z=Q[3];if(!H||!Z)return null;return{name:H,type:O(Z),required:z!=="?",description:G}}function g(q){let G={},X=/const\s*\{\s*([\s\S]*?)\s*\}\s*=\s*(?:withDefaults\s*\(\s*)?defineProps/g,Q;while((Q=X.exec(q))!==null)if(Q[1])y(Q[1],G);let H=q.indexOf("withDefaults(");if(H>=0){let z=q.indexOf("defineProps",H);if(z>0){let Z=q.indexOf(">",z),Y=q.indexOf(")",Z>=0?Z:z);if(Y>0){let _=q.indexOf(",",Y),C=_>=0?q.indexOf("{",_):-1;if(C>0){let J=K(q,C,"{","}");if(J)u(J,G)}}}}return G}function y(q,G){for(let X of N(q,[","])){let Q=/^\s*([a-zA-Z_$][\w$]*)\s*=\s*([\s\S]+?)\s*$/.exec(X),H=Q?.[1],z=Q?.[2];if(H&&z)G[H]=O(z)}}function u(q,G){for(let X of N(q,[","])){let Q=/^\s*([a-zA-Z_$][\w$]*)\s*:\s*([\s\S]+?)\s*$/.exec(X.trim()),H=Q?.[1],z=Q?.[2];if(H&&z)G[H]=O(z)}}function f(q){let G=/defineEmits\s*<\s*\{([\s\S]*?)\}\s*>\s*\(/.exec(q);if(!G?.[1])return[];let X=[];for(let Q of N(G[1],[";",`
|
|
6
6
|
`])){let H=Q.trim();if(!H)continue;let z=/^['"]?([\w-]+)['"]?\s*:\s*\[(.*?)\]\s*$/.exec(H);if(z){let Y=z[1];if(!Y)continue;X.push({name:Y,type:z[2]?.trim()||"void",description:""});continue}let Z=/^([a-zA-Z_$][\w$]*)\s*\(([\s\S]*?)\)\s*:\s*([\s\S]+)$/.exec(H);if(Z){let Y=Z[1];if(!Y)continue;X.push({name:Y,type:Z[2]?.trim()||"void",description:""})}}return X}function h(q){let G=[],X=new Set,Q=/<slot\b([^>]*)>/g,H;while((H=Q.exec(q))!==null){let z=H[1]??"",Y=/\bname\s*=\s*["']([^"']+)["']/.exec(z)?.[1]??"default";if(X.has(Y))continue;X.add(Y),G.push({name:Y,description:""})}return G}function K(q,G,X,Q){if(q[G]!==X)return null;let H=0,z=G,Z=null;while(z<q.length){let Y=q[z];if(Y===void 0)break;if(Z){if(Y==="\\"){z+=2;continue}if(Y===Z)Z=null;z++;continue}if(Y==='"'||Y==="'"||Y==="`"){Z=Y,z++;continue}if(Y===X)H++;else if(Y===Q){if(H--,H===0)return q.slice(G+1,z)}z++}return null}function N(q,G){let X=[],Q=new Set(G),H=0,z=null,Z=0;for(let Y=0;Y<q.length;Y++){let _=q[Y];if(_===void 0)break;if(z){if(_==="\\"){Y++;continue}if(_===z)z=null;continue}if(_==='"'||_==="'"||_==="`"){z=_;continue}if(_==="{"||_==="["||_==="("||_==="<")H++;else if(_==="}"||_==="]"||_===")"||_===">")H--;else if(H===0&&Q.has(_))X.push(q.slice(Z,Y)),Z=Y+1}return X.push(q.slice(Z)),X}function O(q){return q.replace(/\s+/g," ").trim()}
|
|
7
|
-
export{p as
|
|
7
|
+
export{p as ia,B as ja};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import"./chunk-4qzb8g3z.js";var q={type:"aws",useLoadBalancer:!0,app:{name:"app-server-1",domain:"stacksjs.com",region:"us-east-1",type:"app",size:"t3.micro",diskSize:20,serverOS:"ubuntu-20-lts-x86_64",bunVersion:"1.1.26",database:"sqlite",databaseName:"stacks"},app2:{name:"app-server-2",domain:"stacksjs.com",instanceType:"t3.micro",userData:`#!/bin/bash
|
|
3
|
+
echo "Hello World from App Server 2!" > /tmp/test.txt
|
|
4
|
+
chown ubuntu:ubuntu /tmp/test.txt
|
|
5
|
+
`},web:{name:"web-server",domain:"ow3.org",region:"us-east-1",type:"web",size:"t3.micro",diskSize:20,serverOS:"ubuntu-20-lts-x86_64",bunVersion:"1.1.26"},cache:{name:"cache-server",domain:"stacksjs.com",region:"us-east-1",type:"cache",size:"t3.micro",diskSize:20,serverOS:"ubuntu-20-lts-x86_64",bunVersion:"1.1.26"}};import{env as m}from"@stacksjs/env";var C={project:{name:"stacks",slug:"stacks",region:"us-east-1"},cloud:{provider:"hetzner"},mode:"server",environments:{production:{type:"production",deployBranch:"main",region:"us-east-1",variables:{NODE_ENV:"production",LOG_LEVEL:"info"}},staging:{type:"staging",deployBranch:"stage",domainPrefix:"staging",region:"us-east-1",variables:{NODE_ENV:"staging",LOG_LEVEL:"debug"}},development:{type:"development",deployBranch:"dev",domainPrefix:"dev",region:"us-east-1",variables:{NODE_ENV:"development",LOG_LEVEL:"debug"}}},infrastructure:{compute:{instances:1,size:"small",disk:{size:20,type:"ssd",encrypted:!0},webServer:"rpx",proxy:{engine:"rpx",onDemandTls:!0,onDemandTlsEmail:"hello@stacksjs.com"}},servers:{app:q.app},containers:{api:{cpu:512,memory:1024,port:3000,healthCheck:"/health",desiredCount:2,autoScaling:{min:1,max:10,targetCpuUtilization:70,targetMemoryUtilization:80}}},loadBalancer:{enabled:!0,type:"application",healthCheck:{path:"/health",interval:30,healthyThreshold:2,unhealthyThreshold:5}},ssl:{enabled:!0,provider:"acm",domains:m.SSL_DOMAINS?.split(",")||["stacksjs.com","www.stacksjs.com"],redirectHttp:!0,letsEncrypt:{email:m.LETSENCRYPT_EMAIL||"admin@stacksjs.com",staging:!1,autoRenew:!0}},dns:{domain:m.APP_DOMAIN||"stacksjs.com",hostedZoneId:m.AWS_HOSTED_ZONE_ID||"Z01455702Q7952O6RCY37"},storage:{public:{public:!0,encryption:!0,versioning:!0,website:{indexDocument:"index.html",errorDocument:"index.html"}},private:{encryption:!0,versioning:!0},docs:{public:!0,encryption:!0,versioning:!0,path:"/docs",pathRewriteStyle:"flat",website:{indexDocument:"index.html",errorDocument:"404.html"}},blog:{public:!0,encryption:!0,versioning:!0,path:"/blog",website:{indexDocument:"index.html",errorDocument:"404.html"}},logs:{encryption:!0,versioning:!1},backups:{encryption:!0,versioning:!0},email:{public:!1,encryption:!0,versioning:!1}},functions:{},queues:{jobs:{visibilityTimeout:120,deadLetterQueue:!0,maxReceiveCount:3}},databases:{},cdn:{},monitoring:{}},sites:{main:{root:".",path:"/",domain:m.APP_DOMAIN||"stacksjs.com",start:"./buddy serve",port:3000,preStart:["bun install"]},api:{root:".",start:"./buddy serve:api",port:3008,preStart:["bun install"],env:{HOST:"127.0.0.1",APP_ENV:"production"}},docs:{deploy:"server",root:"dist/docs/.bunpress",path:"/docs",domain:m.APP_DOMAIN||"stacksjs.com",build:"bunx @stacksjs/bunpress build --dir ./docs --outdir ./dist/docs",pathRewriteStyle:"directory"},blog:{deploy:"server",root:"dist/blog",path:"/blog",domain:m.APP_DOMAIN||"stacksjs.com",build:`bun -e "const {buildBlog}=await import('./storage/framework/core/actions/src/blog'); await buildBlog({outDir:'./dist/blog', baseUrl: (process.env.APP_URL?(/^https?:/.test(process.env.APP_URL)?process.env.APP_URL:'https://'+process.env.APP_URL):'https://stacksjs.com')})"`,pathRewriteStyle:"directory"},wwwStacksjs:{domain:"www.stacksjs.com",redirect:"https://stacksjs.com"}}},w={},E=w;export{C as tsCloud,E as default};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
2
|
+
import{pb as G}from"./chunk-4qzb8g3z.js";import{log as x}from"@stacksjs/logging";import*as z from"@stacksjs/path";import{doesExist as H,writeFile as I}from"@stacksjs/storage";async function O(q){let j=q.name;if(!j)return x.error("Resource name is required"),!1;let v=j.endsWith("Resource")?j:`${j}Resource`,A=q.model||v.replace("Resource",""),F=q.collection?K(v,A):J(v,A),B=z.appPath("Resources");if(!H(B)){let{mkdirSync:w}=await import("@stacksjs/storage");w(B,{recursive:!0})}let E=z.appPath(`Resources/${v}.ts`);try{return await I(E,F),x.success(`Created resource: ${E}`),!0}catch(w){return x.error(`Failed to create resource: ${w.message}`),!1}}function J(q,j){return`import type { Request } from '@stacksjs/router'
|
|
3
3
|
import { JsonResource } from '@stacksjs/api'
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -111,4 +111,4 @@ export default class ${q} extends ResourceCollection<${j}, ${v}> {
|
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
`}
|
|
114
|
-
export{O as
|
|
114
|
+
export{O as D};
|