@stacksjs/actions 0.70.44 → 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.
Files changed (127) hide show
  1. package/LICENSE.md +21 -0
  2. package/dist/action.d.ts +104 -17
  3. package/dist/blog.d.ts +12 -0
  4. package/dist/build/frontend-static.d.ts +16 -0
  5. package/dist/chunk-00qp27jy.js +93 -0
  6. package/dist/{chunk-jd1yzkq5.js → chunk-23thftnv.js} +1 -1
  7. package/dist/chunk-4qzb8g3z.js +3 -0
  8. package/dist/chunk-5dfz9en9.js +920 -0
  9. package/dist/{chunk-3beht8ja.js → chunk-5hwp0frq.js} +1 -1
  10. package/dist/{chunk-aw6d8zr3.js → chunk-5pwpk005.js} +2 -2
  11. package/dist/chunk-604jy79b.js +5 -0
  12. package/dist/{chunk-wnrgcx3d.js → chunk-63swek9d.js} +2 -2
  13. package/dist/chunk-67am4dae.js +688 -0
  14. package/dist/{chunk-gt77jmb5.js → chunk-8gbewxns.js} +1 -1
  15. package/dist/chunk-8r76qydb.js +240 -0
  16. package/dist/{chunk-schcaf73.js → chunk-9x17v4x2.js} +2 -2
  17. package/dist/chunk-aazd6qpv.js +3 -0
  18. package/dist/{chunk-n2fd1d0m.js → chunk-ag4fy7cx.js} +1 -1
  19. package/dist/{chunk-2qchdrf9.js → chunk-badehrwa.js} +1 -1
  20. package/dist/chunk-dbz9dp2h.js +3 -0
  21. package/dist/{chunk-v0wnrnaa.js → chunk-e8505qz8.js} +2 -2
  22. package/dist/chunk-jv7ry09n.js +3 -0
  23. package/dist/{chunk-w418anbq.js → chunk-jve1p4dz.js} +2 -2
  24. package/dist/chunk-mcwfmqzb.js +283 -0
  25. package/dist/chunk-n24m8prb.js +3 -0
  26. package/dist/{chunk-h93n2j40.js → chunk-nm9h5rye.js} +2 -2
  27. package/dist/{chunk-60qjz7zb.js → chunk-ny1racy0.js} +2 -2
  28. package/dist/{chunk-2gh7kgpc.js → chunk-p601xr03.js} +1 -1
  29. package/dist/{chunk-x471rxrn.js → chunk-pqnzp7x8.js} +2 -2
  30. package/dist/chunk-rj1cbghx.js +17 -0
  31. package/dist/chunk-rzhs51h1.js +3 -0
  32. package/dist/{chunk-7bpdkc40.js → chunk-sp5cjdhd.js} +213 -76
  33. package/dist/chunk-tqax3gbq.js +16 -0
  34. package/dist/{chunk-c8qt2xst.js → chunk-vsj8ns4p.js} +1 -1
  35. package/dist/{chunk-rdajkt2s.js → chunk-x8nrbsk1.js} +2 -2
  36. package/dist/dev/dashboard-utils.d.ts +19 -1
  37. package/dist/dev/migrate-watcher.d.ts +1 -0
  38. package/dist/index.d.ts +2 -0
  39. package/dist/make.d.ts +19 -0
  40. package/dist/queue/dlq-purge.d.ts +1 -0
  41. package/dist/queue/dlq-retry.d.ts +1 -0
  42. package/dist/queue/dlq.d.ts +1 -0
  43. package/dist/queue/list.d.ts +1 -0
  44. package/dist/queue/pause.d.ts +1 -0
  45. package/dist/queue/quarantine.d.ts +1 -0
  46. package/dist/queue/resume.d.ts +1 -0
  47. package/dist/queue/unquarantine.d.ts +1 -0
  48. package/dist/src/action.js +1 -1
  49. package/dist/src/actions.js +1 -1
  50. package/dist/src/add.js +1 -1
  51. package/dist/src/ai/request-model-access.js +1 -1
  52. package/dist/src/auth/setup.js +82 -24
  53. package/dist/src/blog.js +102 -0
  54. package/dist/src/build/core.js +1 -1
  55. package/dist/src/build/frontend-static.js +9 -0
  56. package/dist/src/build/views.js +1 -1
  57. package/dist/src/build.js +1 -1
  58. package/dist/src/commit.js +1 -1
  59. package/dist/src/database/seed.js +1 -1
  60. package/dist/src/deploy/index.js +38 -45
  61. package/dist/src/dev/api.js +4 -4
  62. package/dist/src/dev/dashboard-globals.js +1 -1
  63. package/dist/src/dev/dashboard-utils.js +1 -1
  64. package/dist/src/dev/dashboard.js +6 -6
  65. package/dist/src/dev/docs.js +1 -1
  66. package/dist/src/dev/index.js +1 -1
  67. package/dist/src/dev/migrate-watcher.js +2 -0
  68. package/dist/src/dev/views.js +1 -1
  69. package/dist/src/discover-packages.js +1 -1
  70. package/dist/src/examples.js +1 -1
  71. package/dist/src/generate/component-meta.js +1 -1
  72. package/dist/src/generate/env-files.js +1 -1
  73. package/dist/src/generate/ide-helpers.js +1 -1
  74. package/dist/src/generate/index.js +1 -1
  75. package/dist/src/generate/lib-entries.js +1 -1
  76. package/dist/src/generate/vscode-custom-data.js +1 -1
  77. package/dist/src/helpers/component-meta.js +1 -1
  78. package/dist/src/helpers/index.js +1 -1
  79. package/dist/src/helpers/lib-entries.js +1 -1
  80. package/dist/src/helpers/package-json.js +1 -1
  81. package/dist/src/helpers/utils.js +1 -1
  82. package/dist/src/helpers/vscode-custom-data.js +1 -1
  83. package/dist/src/index.js +1 -1
  84. package/dist/src/key-generate.js +1 -1
  85. package/dist/src/make-command.js +1 -1
  86. package/dist/src/make-job.js +1 -1
  87. package/dist/src/make-policy.js +1 -1
  88. package/dist/src/make-resource.js +1 -1
  89. package/dist/src/make.js +1 -1
  90. package/dist/src/migrate/fresh.js +1 -1
  91. package/dist/src/orm/base.js +1 -1
  92. package/dist/src/queue/dlq-purge.js +2 -0
  93. package/dist/src/queue/dlq-retry.js +2 -0
  94. package/dist/src/queue/dlq.js +5 -0
  95. package/dist/src/queue/failed.js +4 -4
  96. package/dist/src/queue/list.js +5 -0
  97. package/dist/src/queue/pause.js +2 -0
  98. package/dist/src/queue/quarantine.js +3 -0
  99. package/dist/src/queue/resume.js +2 -0
  100. package/dist/src/queue/unquarantine.js +2 -0
  101. package/dist/src/release.js +1 -1
  102. package/dist/src/run-action.js +1 -1
  103. package/dist/src/scaffold-crud.js +1 -1
  104. package/dist/src/serve/api.js +1 -1
  105. package/dist/src/setup/index.js +1 -1
  106. package/dist/src/setup/ssl.js +1 -1
  107. package/dist/src/stacks.js +1 -1
  108. package/dist/src/templates.js +1 -1
  109. package/dist/src/types.js +1 -1
  110. package/dist/src/upgrade/dependencies.js +1 -1
  111. package/dist/src/upgrade/framework-utils.js +1 -1
  112. package/dist/src/upgrade/framework.js +5 -5
  113. package/dist/src/upgrade/index.js +1 -1
  114. package/dist/src/upgrade.js +1 -1
  115. package/dist/upgrade/framework-utils.d.ts +48 -0
  116. package/package.json +18 -18
  117. package/dist/chunk-2kaj93p5.js +0 -3
  118. package/dist/chunk-3086k7zk.js +0 -184
  119. package/dist/chunk-67y94dzt.js +0 -658
  120. package/dist/chunk-6x1m5rkr.js +0 -17
  121. package/dist/chunk-96b7fcmd.js +0 -3
  122. package/dist/chunk-d4srk6ma.js +0 -3
  123. package/dist/chunk-kzhgexj4.js +0 -3
  124. package/dist/chunk-n1y0gpv6.js +0 -3
  125. package/dist/chunk-n2x7v39b.js +0 -5
  126. package/dist/chunk-tc935b45.js +0 -93
  127. package/dist/chunk-wv5yb5wb.js +0 -101
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
- declare interface ActionValidations {
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
- declare interface ActionOptions<TModel = string> {
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?: ActionValidations
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?: string
41
+ path?: TPath
19
42
  requestFile?: string
20
43
  model?: TModel
21
- handle: (request: InferRequest<TModel>) => Promise<any> | any
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
- * Infer the correct RequestInstance type from the model value.
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
- * When `model: Post` (a defineModel() return), resolves to RequestInstance<typeof Post>
27
- * with full field narrowing. When `model: 'Post'` (string) or omitted, falls back
28
- * to bare RequestInstance.
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
- declare type InferRequest<TModel> = TModel extends { _isStacksModel: true }
31
- ? RequestInstance<TModel>
32
- : RequestInstance;
33
- export declare class Action<TModel = string> {
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
- handle: ActionOptions<TModel>['handle'];
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
- }: ActionOptions<TModel>);
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 ab,r as bb,n as cb,s as db,d as eb};
3
+ export{o as hb,r as ib,n as jb,s as kb,d as lb};
@@ -0,0 +1,3 @@
1
+ // @bun
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 mb,t as nb,u as ob,v as pb};