@stacksjs/ts-cloud 0.16.37 → 0.16.39

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 (192) hide show
  1. package/dist/aws/bedrock.d.ts +110 -32
  2. package/dist/aws/client.d.ts +16 -7
  3. package/dist/aws/event-stream.d.ts +36 -0
  4. package/dist/aws/index.d.ts +1 -0
  5. package/dist/aws/index.js +1 -1
  6. package/dist/bin/{chunk-7xj986z7.js → chunk-07qwk0sj.js} +5 -5
  7. package/dist/bin/{chunk-1fjhc7w7.js → chunk-0c1fv0xt.js} +4 -4
  8. package/dist/bin/chunk-0c5vn8rp.js +1 -0
  9. package/dist/bin/{chunk-v4gpkkzh.js → chunk-0ynfqf9t.js} +1 -1
  10. package/dist/bin/chunk-1wf1s8db.js +1 -0
  11. package/dist/bin/{chunk-0ffqbgbs.js → chunk-48nz63ab.js} +3 -3
  12. package/dist/bin/{chunk-2bkxxset.js → chunk-4bp4k1x2.js} +2 -2
  13. package/dist/bin/chunk-4dtrry0t.js +1 -0
  14. package/dist/bin/{chunk-nhz2az7v.js → chunk-4h60xsat.js} +2 -2
  15. package/dist/bin/{chunk-kj4gm2hk.js → chunk-55cckkb2.js} +3 -3
  16. package/dist/bin/{chunk-6r35j09y.js → chunk-5wqjqh6c.js} +1 -1
  17. package/dist/bin/chunk-6kcxf3b2.js +1 -0
  18. package/dist/bin/chunk-6ksbfg6t.js +1 -0
  19. package/dist/bin/{chunk-4zxwtvvf.js → chunk-6r5mehaj.js} +2 -2
  20. package/dist/bin/chunk-7rkg1yph.js +1 -0
  21. package/dist/bin/{chunk-4mt7rspg.js → chunk-7rpj0qhb.js} +2 -2
  22. package/dist/bin/{chunk-w663zt0w.js → chunk-85k5gvnc.js} +3 -3
  23. package/dist/bin/{chunk-vg9et0kb.js → chunk-8zn63v9h.js} +3 -3
  24. package/dist/bin/chunk-989j6ezd.js +1 -0
  25. package/dist/bin/{chunk-na2j5twe.js → chunk-aykdp1wv.js} +1 -1
  26. package/dist/bin/chunk-bgdvhp6m.js +1 -0
  27. package/dist/bin/{chunk-2qdktx9h.js → chunk-c7z8et78.js} +1 -1
  28. package/dist/bin/{chunk-5keq8y15.js → chunk-cqhtnsby.js} +3 -3
  29. package/dist/bin/{chunk-tv0rtc0s.js → chunk-cvc9bxd4.js} +2 -2
  30. package/dist/bin/chunk-czzrfhn7.js +1 -0
  31. package/dist/bin/chunk-d5arnf2f.js +1 -0
  32. package/dist/bin/{chunk-017cjgwt.js → chunk-d8x60kvn.js} +2 -2
  33. package/dist/bin/{chunk-7rwc5bvv.js → chunk-dmwfnbg0.js} +5 -5
  34. package/dist/bin/{chunk-y2qz4vw1.js → chunk-dnmb3sr0.js} +1 -1
  35. package/dist/bin/chunk-e06m9m6z.js +1 -0
  36. package/dist/bin/{chunk-71z22p71.js → chunk-e0kapeev.js} +12 -12
  37. package/dist/bin/chunk-e51ajfyr.js +1 -0
  38. package/dist/bin/{chunk-r3gxhy1k.js → chunk-e6mfcw0v.js} +5 -5
  39. package/dist/bin/{chunk-dvyd4bxh.js → chunk-ehnevjt4.js} +77 -77
  40. package/dist/bin/chunk-fh5bjm3d.js +1 -0
  41. package/dist/bin/chunk-fw6hbyeg.js +1 -0
  42. package/dist/bin/{chunk-ymfnqae6.js → chunk-gc8p1tdr.js} +1 -1
  43. package/dist/bin/chunk-h7gfd2yq.js +1 -0
  44. package/dist/bin/{chunk-gd94501z.js → chunk-hjq05rxh.js} +5 -5
  45. package/dist/bin/chunk-jxnw879g.js +1 -0
  46. package/dist/bin/chunk-k3yq569a.js +1 -0
  47. package/dist/bin/{chunk-8gay06gq.js → chunk-mbr9j2fw.js} +3 -3
  48. package/dist/bin/chunk-nhrwct94.js +1 -0
  49. package/dist/bin/chunk-pa4fymr0.js +1 -0
  50. package/dist/bin/{chunk-6dm7x6g2.js → chunk-pyr0dc6j.js} +52 -52
  51. package/dist/bin/{chunk-hsek7hvh.js → chunk-q8hp4dfy.js} +176 -176
  52. package/dist/bin/{chunk-haqap7d1.js → chunk-r0yapyqc.js} +1 -1
  53. package/dist/bin/chunk-s9xven24.js +1 -0
  54. package/dist/bin/{chunk-s7f24j6k.js → chunk-sqmays54.js} +1 -1
  55. package/dist/bin/{chunk-f76wtb7d.js → chunk-tt3m3fda.js} +1 -1
  56. package/dist/bin/{chunk-6sdffc79.js → chunk-w6yx9bhb.js} +1 -1
  57. package/dist/bin/{chunk-gbpmgae9.js → chunk-w8jfw39t.js} +2 -2
  58. package/dist/bin/{chunk-j01jx36v.js → chunk-wga7gj0h.js} +1 -1
  59. package/dist/bin/chunk-wgv9nv0z.js +1 -0
  60. package/dist/bin/{chunk-yt95wsqg.js → chunk-x0ywfbk5.js} +1 -1
  61. package/dist/bin/{chunk-rbjj0bcn.js → chunk-y5980ycr.js} +1 -1
  62. package/dist/bin/chunk-y5ez6ba7.js +1 -0
  63. package/dist/bin/chunk-ya71t2ed.js +1 -0
  64. package/dist/bin/{chunk-fxyr2wkt.js → chunk-ygsdntxq.js} +4 -4
  65. package/dist/bin/chunk-zb1nh252.js +1 -0
  66. package/dist/bin/cli.js +187 -187
  67. package/dist/bin/dashboard-server.js +1 -1
  68. package/dist/{chunk-mbs6pr03.js → chunk-0rvnerbw.js} +7 -10
  69. package/dist/chunk-1ty76ybd.js +1 -0
  70. package/dist/chunk-2mypcz4a.js +1 -0
  71. package/dist/{chunk-n0vz557v.js → chunk-2n4ktft4.js} +1 -1
  72. package/dist/{chunk-2bvmp0br.js → chunk-3cyszqzh.js} +2 -2
  73. package/dist/{chunk-ybdxrf42.js → chunk-5vk7nss8.js} +2 -2
  74. package/dist/{chunk-kzjvasjs.js → chunk-bx3jmgd0.js} +2 -2
  75. package/dist/{chunk-n3p8vr8s.js → chunk-c45ay9fx.js} +5 -5
  76. package/dist/{chunk-5np6w0g7.js → chunk-dg834141.js} +5 -5
  77. package/dist/chunk-fe5sbczg.js +1 -0
  78. package/dist/{chunk-t0azf37g.js → chunk-ffba3270.js} +2 -2
  79. package/dist/{chunk-x7pnt65y.js → chunk-ffjgw5m6.js} +75 -75
  80. package/dist/{chunk-3bsf7585.js → chunk-gcqq9m4b.js} +4 -4
  81. package/dist/chunk-gtc1gvfj.js +1 -0
  82. package/dist/{chunk-azt6sm0r.js → chunk-j1aq97br.js} +3 -3
  83. package/dist/chunk-j5t1amn0.js +1 -0
  84. package/dist/{chunk-zg589zg1.js → chunk-jsnhb1p4.js} +19 -19
  85. package/dist/{chunk-1kfagk30.js → chunk-kkeb1dk1.js} +1 -1
  86. package/dist/{chunk-rkjnr9fp.js → chunk-kpjhfgbh.js} +3 -3
  87. package/dist/{chunk-aqxp4s43.js → chunk-kyn6a4zf.js} +2 -2
  88. package/dist/{chunk-98xzqtnw.js → chunk-n1r9313b.js} +2 -2
  89. package/dist/{chunk-0fhz75e0.js → chunk-n8g8t8hf.js} +3 -3
  90. package/dist/{chunk-fsdd2cj8.js → chunk-nzmangkw.js} +4 -4
  91. package/dist/{chunk-78r4k21k.js → chunk-p4rknh9f.js} +1 -1
  92. package/dist/{chunk-a74kqzne.js → chunk-q08s698e.js} +49 -49
  93. package/dist/{chunk-mce0cpgf.js → chunk-qhtgfjhd.js} +19 -19
  94. package/dist/chunk-s20830hg.js +1 -0
  95. package/dist/{chunk-pjhag27y.js → chunk-t52wetq8.js} +1 -1
  96. package/dist/{chunk-vmhfc7nk.js → chunk-tbn385ak.js} +88 -88
  97. package/dist/{chunk-50m6sq01.js → chunk-v83qx041.js} +4 -4
  98. package/dist/{chunk-svzmsd7g.js → chunk-xr7ew64s.js} +1 -1
  99. package/dist/{chunk-pfav9qnt.js → chunk-yrcv3hrj.js} +6 -6
  100. package/dist/{chunk-k92sywmh.js → chunk-zvyrpmvd.js} +1 -1
  101. package/dist/deploy/index.js +1 -1
  102. package/dist/dns/index.js +1 -1
  103. package/dist/drivers/index.js +1 -1
  104. package/dist/index.js +27 -27
  105. package/dist/operations/index.js +1 -1
  106. package/dist/protection/index.js +1 -1
  107. package/dist/spend/index.js +1 -1
  108. package/dist/ui/404.html +1 -1
  109. package/dist/ui/accept-invitation.html +1 -1
  110. package/dist/ui/access-denied.html +1 -1
  111. package/dist/ui/account/automation.html +6 -6
  112. package/dist/ui/account/security.html +2 -2
  113. package/dist/ui/applications/compose.html +6 -6
  114. package/dist/ui/applications/new.html +1 -1
  115. package/dist/ui/data/backups.html +6 -6
  116. package/dist/ui/data/services.html +6 -6
  117. package/dist/ui/data/volumes.html +6 -6
  118. package/dist/ui/index.html +6 -6
  119. package/dist/ui/infrastructure/topology.html +5 -5
  120. package/dist/ui/integrations.html +2 -2
  121. package/dist/ui/operations/alerts.html +6 -6
  122. package/dist/ui/operations/configuration.html +6 -6
  123. package/dist/ui/operations/jobs.html +6 -6
  124. package/dist/ui/operations/maintenance.html +6 -6
  125. package/dist/ui/operations/observability.html +6 -6
  126. package/dist/ui/operations/previews.html +6 -6
  127. package/dist/ui/operations/queue.html +6 -6
  128. package/dist/ui/operations/regions.html +6 -6
  129. package/dist/ui/operations/releases.html +6 -6
  130. package/dist/ui/operations/spend.html +6 -6
  131. package/dist/ui/operations/workloads.html +5 -5
  132. package/dist/ui/security.html +1 -1
  133. package/dist/ui/server/actions.html +6 -6
  134. package/dist/ui/server/activity.html +2 -2
  135. package/dist/ui/server/capacity.html +6 -6
  136. package/dist/ui/server/database.html +6 -6
  137. package/dist/ui/server/deployments.html +6 -6
  138. package/dist/ui/server/diagnostics.html +1 -1
  139. package/dist/ui/server/firewall.html +6 -6
  140. package/dist/ui/server/fleet.html +6 -6
  141. package/dist/ui/server/logs.html +6 -6
  142. package/dist/ui/server/metrics.html +6 -6
  143. package/dist/ui/server/security.html +2 -2
  144. package/dist/ui/server/services.html +2 -2
  145. package/dist/ui/server/sites.html +6 -6
  146. package/dist/ui/server/ssh-keys.html +6 -6
  147. package/dist/ui/server/team.html +5 -5
  148. package/dist/ui/server/terminal.html +1 -1
  149. package/dist/ui/serverless/alarms.html +5 -5
  150. package/dist/ui/serverless/assets.html +1 -1
  151. package/dist/ui/serverless/cost.html +1 -1
  152. package/dist/ui/serverless/data.html +5 -5
  153. package/dist/ui/serverless/deployments.html +1 -1
  154. package/dist/ui/serverless/firewall.html +1 -1
  155. package/dist/ui/serverless/functions.html +6 -6
  156. package/dist/ui/serverless/logs.html +5 -5
  157. package/dist/ui/serverless/metrics.html +2 -2
  158. package/dist/ui/serverless/queues.html +5 -5
  159. package/dist/ui/serverless/secrets.html +5 -5
  160. package/dist/ui/serverless/traces.html +6 -6
  161. package/dist/ui/serverless.html +6 -6
  162. package/package.json +3 -3
  163. package/dist/bin/chunk-1k9sw5y7.js +0 -1
  164. package/dist/bin/chunk-2cx4k97r.js +0 -1
  165. package/dist/bin/chunk-2gygs4xw.js +0 -1
  166. package/dist/bin/chunk-2rcwhdx9.js +0 -1
  167. package/dist/bin/chunk-3gc8y0ta.js +0 -1
  168. package/dist/bin/chunk-683zr91n.js +0 -1
  169. package/dist/bin/chunk-cdzas02w.js +0 -1
  170. package/dist/bin/chunk-dd567z84.js +0 -1
  171. package/dist/bin/chunk-dzx0w4zb.js +0 -1
  172. package/dist/bin/chunk-e7h2j23x.js +0 -1
  173. package/dist/bin/chunk-excjyrfx.js +0 -1
  174. package/dist/bin/chunk-fawjv4dc.js +0 -1
  175. package/dist/bin/chunk-gewxhd5z.js +0 -1
  176. package/dist/bin/chunk-gjadvs6y.js +0 -1
  177. package/dist/bin/chunk-hc4s84v1.js +0 -1
  178. package/dist/bin/chunk-n84pv5ns.js +0 -1
  179. package/dist/bin/chunk-p5k5z7gm.js +0 -1
  180. package/dist/bin/chunk-r263q1aa.js +0 -1
  181. package/dist/bin/chunk-sp78dh4p.js +0 -1
  182. package/dist/bin/chunk-t844fst8.js +0 -1
  183. package/dist/bin/chunk-tj589nbw.js +0 -1
  184. package/dist/bin/chunk-tkz95bkg.js +0 -1
  185. package/dist/bin/chunk-xpzkwgb4.js +0 -1
  186. package/dist/bin/chunk-zswkrc34.js +0 -1
  187. package/dist/chunk-1mrqpf8e.js +0 -1
  188. package/dist/chunk-2bbm2q0s.js +0 -1
  189. package/dist/chunk-46jnzd0d.js +0 -1
  190. package/dist/chunk-j5v7fgxz.js +0 -1
  191. package/dist/chunk-jfqm2c9q.js +0 -1
  192. package/dist/chunk-ppr0bkgd.js +0 -1
@@ -108,9 +108,59 @@ export interface BedrockStreamChunk {
108
108
  message: string;
109
109
  };
110
110
  }
111
+ /**
112
+ * A Converse content block. Converse keys each block by its kind rather than
113
+ * tagging it with `type` the way Anthropic's Messages API does; a
114
+ * `{ type: 'text', text }` block is refused with a ValidationException.
115
+ */
116
+ export type ConverseContentBlock = {
117
+ text: string;
118
+ } | {
119
+ image: {
120
+ format: 'png' | 'jpeg' | 'gif' | 'webp';
121
+ source: {
122
+ bytes: string;
123
+ };
124
+ };
125
+ } | {
126
+ document: {
127
+ format: 'pdf' | 'csv' | 'doc' | 'docx' | 'xls' | 'xlsx' | 'html' | 'txt' | 'md';
128
+ name: string;
129
+ source: {
130
+ bytes: string;
131
+ };
132
+ };
133
+ } | {
134
+ toolUse: {
135
+ toolUseId: string;
136
+ name: string;
137
+ input: Record<string, unknown>;
138
+ };
139
+ } | {
140
+ toolResult: {
141
+ toolUseId: string;
142
+ content: Array<{
143
+ text: string;
144
+ } | {
145
+ json: unknown;
146
+ }>;
147
+ status?: 'success' | 'error';
148
+ };
149
+ };
150
+ export interface ConverseMessage {
151
+ role: 'user' | 'assistant';
152
+ content: ConverseContentBlock[];
153
+ }
154
+ export interface ConverseToolSpec {
155
+ name: string;
156
+ description?: string;
157
+ inputSchema: {
158
+ json: Record<string, unknown>;
159
+ };
160
+ }
111
161
  export interface ConverseCommandInput {
112
162
  modelId: string;
113
- messages: BedrockMessage[];
163
+ messages: ConverseMessage[];
114
164
  system?: Array<{
115
165
  text: string;
116
166
  }>;
@@ -122,7 +172,7 @@ export interface ConverseCommandInput {
122
172
  };
123
173
  toolConfig?: {
124
174
  tools: Array<{
125
- toolSpec: BedrockToolDefinition;
175
+ toolSpec: ConverseToolSpec;
126
176
  }>;
127
177
  toolChoice?: {
128
178
  auto: Record<string, never>;
@@ -142,9 +192,9 @@ export interface ConverseCommandInput {
142
192
  }
143
193
  export interface ConverseCommandOutput {
144
194
  output: {
145
- message?: BedrockMessage;
195
+ message?: ConverseMessage;
146
196
  };
147
- stopReason: 'end_turn' | 'tool_use' | 'max_tokens' | 'stop_sequence' | 'guardrail_intervened' | 'content_filtered';
197
+ stopReason: 'end_turn' | 'tool_use' | 'max_tokens' | 'stop_sequence' | 'guardrail_intervened' | 'content_filtered' | 'malformed_model_output' | 'malformed_tool_use' | 'model_context_window_exceeded';
148
198
  usage: {
149
199
  inputTokens: number;
150
200
  outputTokens: number;
@@ -356,12 +406,40 @@ export interface GetCustomModelCommandOutput {
356
406
  }>;
357
407
  creationTime: string;
358
408
  }
359
- export interface CreateFoundationModelEntitlementCommandInput {
409
+ export interface GetFoundationModelAvailabilityCommandOutput {
360
410
  modelId: string;
411
+ agreementAvailability: {
412
+ status: 'AVAILABLE' | 'PENDING' | 'NOT_AVAILABLE' | 'ERROR';
413
+ errorMessage?: string | null;
414
+ };
415
+ authorizationStatus: 'AUTHORIZED' | 'NOT_AUTHORIZED';
416
+ entitlementAvailability: 'AVAILABLE' | 'NOT_AVAILABLE';
417
+ regionAvailability: 'AVAILABLE' | 'NOT_AVAILABLE';
418
+ }
419
+ export interface FoundationModelAgreementOffer {
420
+ offerId: string;
421
+ offerToken: string;
422
+ termDetails?: Record<string, unknown>;
361
423
  }
362
- export interface CreateFoundationModelEntitlementCommandOutput {
363
- status: 'PENDING' | 'APPROVED' | 'DENIED';
424
+ export interface ListFoundationModelAgreementOffersCommandOutput {
364
425
  modelId: string;
426
+ offers: FoundationModelAgreementOffer[];
427
+ }
428
+ export interface CreateFoundationModelAgreementCommandInput {
429
+ modelId: string;
430
+ offerToken: string;
431
+ }
432
+ export interface RequestModelAccessCommandInput {
433
+ modelId: string;
434
+ }
435
+ export interface RequestModelAccessCommandOutput {
436
+ modelId: string;
437
+ /**
438
+ * `available` - the model can be invoked now, no agreement needed or one
439
+ * already in place. `requested` - an agreement was created from the model's
440
+ * public offer; Bedrock processes it asynchronously.
441
+ */
442
+ status: 'available' | 'requested';
365
443
  }
366
444
  export interface ListModelInvocationJobsCommandInput {
367
445
  submitTimeAfter?: string;
@@ -824,9 +902,6 @@ export interface InvokeAgentCommandOutput {
824
902
  sessionId: string;
825
903
  memoryId?: string;
826
904
  }
827
- /**
828
- * Bedrock Runtime client for AI model invocations
829
- */
830
905
  export declare class BedrockRuntimeClient {
831
906
  private client;
832
907
  private region;
@@ -839,26 +914,6 @@ export declare class BedrockRuntimeClient {
839
914
  * Invoke model with streaming response (matches AWS SDK InvokeModelWithResponseStreamCommand)
840
915
  */
841
916
  invokeModelWithResponseStream(params: InvokeModelWithResponseStreamCommandInput): Promise<InvokeModelWithResponseStreamCommandOutput>;
842
- /**
843
- * Internal method to make streaming request
844
- */
845
- private makeStreamRequest;
846
- /**
847
- * Parse AWS event stream format
848
- */
849
- private parseEventStream;
850
- /**
851
- * Extract JSON chunks from event stream buffer
852
- */
853
- private extractJsonChunks;
854
- /**
855
- * Get credentials from environment
856
- */
857
- private getCredentialsFromEnv;
858
- /**
859
- * Sign request for streaming (simplified SigV4)
860
- */
861
- private signStreamRequest;
862
917
  /**
863
918
  * Invoke Claude model with messages API (convenience method)
864
919
  */
@@ -999,9 +1054,32 @@ export declare class BedrockClient {
999
1054
  */
1000
1055
  deleteCustomModel(params: DeleteCustomModelCommandInput): Promise<DeleteCustomModelCommandOutput>;
1001
1056
  /**
1002
- * Request access to a foundation model
1057
+ * Whether `modelId` can be invoked in this region by this account, and
1058
+ * whether an agreement is still needed.
1059
+ */
1060
+ getFoundationModelAvailability(modelId: string): Promise<GetFoundationModelAvailabilityCommandOutput>;
1061
+ /**
1062
+ * The agreement offers for a marketplace model. A first-party model takes
1063
+ * no agreement and Bedrock answers 400 "Agreement not supported".
1064
+ */
1065
+ listFoundationModelAgreementOffers(modelId: string, offerType?: 'ALL' | 'PUBLIC'): Promise<ListFoundationModelAgreementOffersCommandOutput>;
1066
+ /**
1067
+ * Accept an offer for a model. Bedrock answers 202 and processes it
1068
+ * asynchronously.
1069
+ */
1070
+ createFoundationModelAgreement(params: CreateFoundationModelAgreementCommandInput): Promise<{
1071
+ modelId: string;
1072
+ }>;
1073
+ /**
1074
+ * Make a foundation model invocable: a no-op for a model that needs no
1075
+ * agreement or already has one, otherwise an agreement from its public offer.
1076
+ *
1077
+ * This used to POST to `/foundation-model-entitlement`, which is not a
1078
+ * Bedrock operation, so it never requested anything. A model the account is
1079
+ * not authorised for (Anthropic's first-use form, for one) is refused with
1080
+ * the reason rather than reported as requested.
1003
1081
  */
1004
- requestModelAccess(params: CreateFoundationModelEntitlementCommandInput): Promise<CreateFoundationModelEntitlementCommandOutput>;
1082
+ requestModelAccess(params: RequestModelAccessCommandInput): Promise<RequestModelAccessCommandOutput>;
1005
1083
  /**
1006
1084
  * Create a guardrail
1007
1085
  */
@@ -17,6 +17,12 @@ export interface AWSRequestOptions {
17
17
  cacheTTL?: number;
18
18
  returnHeaders?: boolean;
19
19
  rawResponse?: boolean;
20
+ /**
21
+ * Resolve with the `Response` itself, body unread, once its status is known
22
+ * to be a success. For bodies consumed incrementally, such as an event
23
+ * stream; an error status still throws the same parsed error as any request.
24
+ */
25
+ streamResponse?: boolean;
20
26
  /** S3 bucket name for virtual-hosted style URLs */
21
27
  bucket?: string;
22
28
  }
@@ -79,16 +85,19 @@ export interface AWSError extends Error {
79
85
  type?: string;
80
86
  }
81
87
  /**
82
- * AWS API Client - Makes authenticated requests to AWS services
88
+ * The SigV4 signing name for a request sent to `<endpointPrefix>.<region>.amazonaws.com`.
83
89
  */
90
+ export declare function signingNameFor(endpointPrefix: string): string;
84
91
  /**
85
- * Convert parsed XML text the way the parser's own option did, minus the
86
- * lossy cases: `true`/`false` become booleans, and text becomes a number only
87
- * when the number prints back as exactly the same text. So `16` and
88
- * `923076644019` are numbers, while `+18082188241` (a phone number), `7.0`
89
- * (an engine version), `1.50`, `0x1F`, `1e3` and a 20-digit ID stay strings.
90
- * Exported for tests.
92
+ * The SigV4 canonical URI for `path`, the path exactly as it is sent.
93
+ *
94
+ * Every service but S3 canonicalises the path by URI-encoding each segment of
95
+ * it again, so an already-encoded `%3A` is signed as `%253A`. Signing the path
96
+ * verbatim failed every request whose path carried an encoded character - a
97
+ * Bedrock model id such as `amazon.nova-lite-v1:0`, a Lambda function ARN -
98
+ * with a signature mismatch. S3 signs the path as sent.
91
99
  */
100
+ export declare function canonicalUriFor(endpointPrefix: string, path: string): string;
92
101
  export declare function coerceXmlValues(node: any): any;
93
102
  export declare class AWSClient {
94
103
  private credentials?;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Decoder for the AWS event stream encoding (`application/vnd.amazon.eventstream`),
3
+ * the binary framing Bedrock uses for `invoke-with-response-stream`,
4
+ * `converse-stream` and Agents' `InvokeAgent`.
5
+ *
6
+ * Each message is:
7
+ *
8
+ * total length (u32) | headers length (u32) | prelude CRC32 (u32)
9
+ * headers | payload | message CRC32 (u32)
10
+ *
11
+ * all big-endian. Both checksums are verified, so a truncated or corrupted
12
+ * frame is an error rather than a silently wrong chunk.
13
+ */
14
+ export type EventStreamHeaderValue = string | number | boolean | bigint | Uint8Array | Date;
15
+ export interface EventStreamMessage {
16
+ headers: Record<string, EventStreamHeaderValue>;
17
+ payload: Uint8Array;
18
+ }
19
+ export declare function crc32(bytes: Uint8Array): number;
20
+ /**
21
+ * Decode one complete message. `frame` must be exactly one message long.
22
+ */
23
+ export declare function decodeEventStreamMessage(frame: Uint8Array): EventStreamMessage;
24
+ /**
25
+ * Split a byte stream into event stream messages, however the transport
26
+ * happened to chunk it. A stream that ends partway through a message throws.
27
+ */
28
+ export declare function decodeEventStream(source: AsyncIterable<Uint8Array> | ReadableStream<Uint8Array>): AsyncGenerator<EventStreamMessage>;
29
+ /**
30
+ * The error an `exception` (or `error`) message stands for.
31
+ *
32
+ * Bedrock sends a mid-stream failure - throttling, a model timeout, a
33
+ * validation error - as a message rather than an HTTP status, so a decoder
34
+ * that skipped these ended the stream early and reported success.
35
+ */
36
+ export declare function eventStreamError(message: EventStreamMessage): Error | null;
@@ -31,6 +31,7 @@ export * from './dynamodb';
31
31
  export * from './opensearch';
32
32
  export * from './transcribe';
33
33
  export * from './bedrock';
34
+ export * from './event-stream';
34
35
  export * from './comprehend';
35
36
  export { RekognitionClient, detectLabelsFromS3, countFacesInS3Image, isContentSafe } from './rekognition';
36
37
  export type { S3Object as RekognitionS3Object, BoundingBox as RekognitionBoundingBox, Image, Video, Landmark, Pose, ImageQuality, Emotion, FaceDetail, DetectFacesCommandInput, DetectFacesCommandOutput, Label, DetectLabelsCommandInput, DetectLabelsCommandOutput, DetectTextCommandInput, TextDetection, DetectTextCommandOutput, DetectModerationLabelsCommandInput, ModerationLabel, DetectModerationLabelsCommandOutput, Celebrity, RecognizeCelebritiesCommandInput, RecognizeCelebritiesCommandOutput, CompareFacesCommandInput, CompareFacesMatch, CompareFacesCommandOutput, CreateCollectionCommandInput, CreateCollectionCommandOutput, DeleteCollectionCommandInput, DeleteCollectionCommandOutput, ListCollectionsCommandInput, ListCollectionsCommandOutput, IndexFacesCommandInput, FaceRecord, IndexFacesCommandOutput, SearchFacesByImageCommandInput, FaceMatch, SearchFacesByImageCommandOutput, SearchFacesCommandInput, SearchFacesCommandOutput, StartLabelDetectionCommandInput, StartLabelDetectionCommandOutput, GetLabelDetectionCommandInput, LabelDetection, GetLabelDetectionCommandOutput, StartFaceDetectionCommandInput, StartFaceDetectionCommandOutput, GetFaceDetectionCommandInput, FaceDetection, GetFaceDetectionCommandOutput, StartContentModerationCommandInput, StartContentModerationCommandOutput, GetContentModerationCommandInput, ContentModerationDetection, GetContentModerationCommandOutput, } from './rekognition';
package/dist/aws/index.js CHANGED
@@ -1 +1 @@
1
- import{Se,ar,Ss,Is,Yu,Wa,Ja,bs,Cs,Xa,nt,K,it,oe,E,Ie,vn,Ya,Le,Za,Tn,wn,Rn,jf,zf,SS,IS,bS,CS,kt,ES,vS,TS,wS,Bt,Kf,Wf,Jf,xt,Xf,Yf,Zf,Dn,RS,DS,PS,cr,NS,kS,BS,ec,tc,Zu,xS,OS,_S,dr,eh,th,lr,st,Pn,rc,eg,LS,tg,$S,Ot,MS,FS,US,QS,ce,HS,GS,VS,qS,ur,jS,zS,KS,Nn,nc,ic,rg,ng,sc,gr}from"../chunk-mbs6pr03.js";import{be,ot,kn,rh}from"../chunk-0fhz75e0.js";import{oc,$e,S}from"../chunk-98xzqtnw.js";import{Me}from"../chunk-aqxp4s43.js";import{W}from"../chunk-78r4k21k.js";import{at,de,Fe,Ce,_t,xn,vs,Ts,pr,mr,On,fr,ws,Rs,Ds,Ps,J,Ns,ks,Bs,xs,le,Os,_s,Ls,D,dc,_n,lc,ue,hr}from"../chunk-ybdxrf42.js";import{I}from"../chunk-n0vz557v.js";import{Pr,De}from"../chunk-azt6sm0r.js";import{h}from"../chunk-k92sywmh.js";import{o}from"../chunk-svzmsd7g.js";import{kr,hi,n,l,bh}from"../chunk-5np6w0g7.js";export{ue as ACMClient,hr as ACMDnsValidator,n as AWSClient,rc as ApplicationAutoScalingClient,ar as AwsBackupClient,zf as BedrockAgentClient,jf as BedrockAgentRuntimeClient,Rn as BedrockClient,wn as BedrockRuntimeClient,h as CloudFormationClient,S as CloudFrontClient,Ie as CloudWatchLogsClient,Ce as CloudflareProvider,kt as ComprehendClient,vn as ConnectClient,Cs as CostExplorerClient,_n as DnsProviderFactory,Le as DynamoDBClient,Pr as EC2Client,Me as ECRClient,nt as ECSClient,gr as EFSClient,Ya as ELBv2Client,st as ElastiCacheClient,kn as EmailClient,lr as EventBridgeClient,Fe as GoDaddyProvider,be as IAMClient,eg as ImapServer,dr as KendraClient,E as LambdaClient,Za as OpenSearchClient,at as PROXIABLE_RECORD_TYPES,ec as PersonalizeClient,Zu as PersonalizeEventsClient,tc as PersonalizeRuntimeClient,Dn as PollyClient,de as PorkbunProvider,W as RDSClient,Bt as RekognitionClient,I as Route53Client,Xa as Route53DomainsClient,J as Route53Provider,o as S3Client,ot as SESClient,it as SNSClient,oe as SQSClient,De as SSMClient,Se as STSClient,Pn as SchedulerClient,K as SecretsManagerClient,Ot as SmsClient,sc as SmsVoiceClient,tg as SmtpServer,Nn as SupportClient,nc as SupportTemplates,xt as TextractClient,Tn as TranscribeClient,cr as TranslateClient,le as UnifiedDnsValidator,ur as VoiceClient,ES as analyzeSentiment,Ds as applyDeclaredZoneSettings,Bs as applyZoneMigration,l as buildQueryParams,hi as coerceXmlValues,bS as completeWithClaude,oc as configOrigins,wS as containsPii,Wf as countFacesInS3Image,QS as createDeliveryReceiptHandler,D as createDnsProvider,_s as createGoDaddyValidator,bs as createObjectStorageClient,Os as createPorkbunValidator,zS as createRecordingHandler,Ls as createRoute53Validator,PS as createSSML,FS as createScheduledSmsHandler,US as createSmsClient,MS as createSmsInboxHandler,ng as createSmsInfrastructure,KS as createVoiceClient,jS as createVoicemailHandler,fr as delegateZone,ws as delegateZoneFromConfig,Rs as describeDelegation,Ps as describeZoneSettings,bh as detectCredentialSource,dc as detectDnsProvider,Kf as detectLabelsFromS3,TS as detectLanguage,lc as dnsProviders,rh as email,Ns as exportRoute53Zone,vS as extractEntities,Yf as extractFormsFromS3,Zf as extractTablesFromS3,Xf as extractTextFromS3,HS as formatPhoneNumber,CS as generateEmbeddings,VS as getCountryCode,xS as getRecommendations,OS as getSimilarItems,rg as getSmsInfrastructureStatus,Jf as isContentSafe,pr as isNameserverRegistrar,qS as isSamePhoneNumber,GS as isValidPhoneNumber,mr as isZoneHost,Is as keyMatchesFilters,IS as listClaudeModels,BS as listLanguages,DS as listVoices,Yu as migrateObjectStorage,ce as normalizePhoneNumber,ks as planZoneMigration,_t as policyTag,Wa as providerEndpoint,xn as qualifyName,Ts as reconcileDeclaredRecords,Ss as remapKey,SS as requestModelAccess,vs as resolveDeclaredRecords,Ja as resolveObjectStorage,kr as resolveS3Endpoint,th as retrieveForRag,$e as s3OriginBucket,On as sameNameservers,eh as search,ic as setupSmsInfrastructure,LS as startImapServer,$S as startSmtpServer,RS as textToSpeech,_S as trackEvent,NS as translate,kS as translateToMultiple,xs as verifyZoneParity};
1
+ import{ye,ar,Ss,Is,eg,Wa,Ja,bs,Cs,Xa,nt,K,it,oe,E,Se,vn,Ya,_e,Za,Tn,tg,Xf,ec,tc,wn,Rn,Yf,Zf,TS,wS,RS,DS,kt,PS,NS,kS,BS,Bt,eh,th,rh,xt,nh,ih,sh,Dn,xS,OS,_S,cr,LS,$S,MS,rc,nc,rg,FS,US,QS,dr,oh,ah,lr,st,Pn,ic,ng,HS,ig,GS,Ot,VS,qS,jS,zS,ce,KS,WS,JS,XS,ur,YS,ZS,eI,Nn,sc,oc,sg,og,ac,gr}from"../chunk-0rvnerbw.js";import{Ie,ot,kn,ch}from"../chunk-n8g8t8hf.js";import{cc,Le,S}from"../chunk-n1r9313b.js";import{$e}from"../chunk-kyn6a4zf.js";import{W}from"../chunk-p4rknh9f.js";import{at,de,Me,be,_t,xn,vs,Ts,pr,mr,On,fr,ws,Rs,Ds,Ps,J,Ns,ks,Bs,xs,le,Os,_s,Ls,D,uc,_n,gc,ue,hr}from"../chunk-5vk7nss8.js";import{I}from"../chunk-2n4ktft4.js";import{Pr,Re}from"../chunk-j1aq97br.js";import{h}from"../chunk-zvyrpmvd.js";import{o}from"../chunk-xr7ew64s.js";import{kr,Wg,Jg,hi,n,l,Rh}from"../chunk-dg834141.js";export{ue as ACMClient,hr as ACMDnsValidator,n as AWSClient,ic as ApplicationAutoScalingClient,ar as AwsBackupClient,Zf as BedrockAgentClient,Yf as BedrockAgentRuntimeClient,Rn as BedrockClient,wn as BedrockRuntimeClient,h as CloudFormationClient,S as CloudFrontClient,Se as CloudWatchLogsClient,be as CloudflareProvider,kt as ComprehendClient,vn as ConnectClient,Cs as CostExplorerClient,_n as DnsProviderFactory,_e as DynamoDBClient,Pr as EC2Client,$e as ECRClient,nt as ECSClient,gr as EFSClient,Ya as ELBv2Client,st as ElastiCacheClient,kn as EmailClient,lr as EventBridgeClient,Me as GoDaddyProvider,Ie as IAMClient,ng as ImapServer,dr as KendraClient,E as LambdaClient,Za as OpenSearchClient,at as PROXIABLE_RECORD_TYPES,rc as PersonalizeClient,rg as PersonalizeEventsClient,nc as PersonalizeRuntimeClient,Dn as PollyClient,de as PorkbunProvider,W as RDSClient,Bt as RekognitionClient,I as Route53Client,Xa as Route53DomainsClient,J as Route53Provider,o as S3Client,ot as SESClient,it as SNSClient,oe as SQSClient,Re as SSMClient,ye as STSClient,Pn as SchedulerClient,K as SecretsManagerClient,Ot as SmsClient,ac as SmsVoiceClient,ig as SmtpServer,Nn as SupportClient,sc as SupportTemplates,xt as TextractClient,Tn as TranscribeClient,cr as TranslateClient,le as UnifiedDnsValidator,ur as VoiceClient,PS as analyzeSentiment,Ds as applyDeclaredZoneSettings,Bs as applyZoneMigration,l as buildQueryParams,Jg as canonicalUriFor,hi as coerceXmlValues,RS as completeWithClaude,cc as configOrigins,BS as containsPii,th as countFacesInS3Image,tg as crc32,zS as createDeliveryReceiptHandler,D as createDnsProvider,_s as createGoDaddyValidator,bs as createObjectStorageClient,Os as createPorkbunValidator,ZS as createRecordingHandler,Ls as createRoute53Validator,_S as createSSML,qS as createScheduledSmsHandler,jS as createSmsClient,VS as createSmsInboxHandler,og as createSmsInfrastructure,eI as createVoiceClient,YS as createVoicemailHandler,ec as decodeEventStream,Xf as decodeEventStreamMessage,fr as delegateZone,ws as delegateZoneFromConfig,Rs as describeDelegation,Ps as describeZoneSettings,Rh as detectCredentialSource,uc as detectDnsProvider,eh as detectLabelsFromS3,kS as detectLanguage,gc as dnsProviders,ch as email,tc as eventStreamError,Ns as exportRoute53Zone,NS as extractEntities,ih as extractFormsFromS3,sh as extractTablesFromS3,nh as extractTextFromS3,KS as formatPhoneNumber,DS as generateEmbeddings,JS as getCountryCode,FS as getRecommendations,US as getSimilarItems,sg as getSmsInfrastructureStatus,rh as isContentSafe,pr as isNameserverRegistrar,XS as isSamePhoneNumber,WS as isValidPhoneNumber,mr as isZoneHost,Is as keyMatchesFilters,wS as listClaudeModels,MS as listLanguages,OS as listVoices,eg as migrateObjectStorage,ce as normalizePhoneNumber,ks as planZoneMigration,_t as policyTag,Wa as providerEndpoint,xn as qualifyName,Ts as reconcileDeclaredRecords,Ss as remapKey,TS as requestModelAccess,vs as resolveDeclaredRecords,Ja as resolveObjectStorage,kr as resolveS3Endpoint,ah as retrieveForRag,Le as s3OriginBucket,On as sameNameservers,oh as search,oc as setupSmsInfrastructure,Wg as signingNameFor,HS as startImapServer,GS as startSmtpServer,xS as textToSpeech,QS as trackEvent,LS as translate,$S as translateToMultiple,xs as verifyZoneParity};
@@ -1,8 +1,8 @@
1
- var l={mode:"detection",paranoiaLevel:1,inboundThreshold:5,outboundThreshold:4,maxBodyBytes:13107200,rejectOversizedBody:!0,auditLogPath:"/var/log/ts-cloud/waf-audit.log",blockStatus:403},d={bypassBase:1e5,exclusionBase:101000,rateLimitBase:102000,customBase:109000};function We(e){return e.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/[\r\n]+/g," ")}function oo(e){if(e.length>1000)return!1;if(/\([^)]*[+*]\)[+*]/.test(e))return!1;if(/\[[^\]]*\][+*]\{/.test(e))return!1;try{return new RegExp(e),!0}catch{return!1}}function b(e,r){let t=[],o=[],s=r;for(let n of e){if(n.enabled===!1)continue;if(n.key&&(n.key.source==="cookie"||n.key.source==="header")&&!n.key.name){o.push({ruleId:n.id,reason:"The rule keys on a header or cookie but names none."});continue}let c=n.path?uc(n.path):".*";if(!oo(c)){o.push({ruleId:n.id,reason:"The path pattern compiles to an unsafe regular expression."});continue}let u=[`SecRule REQUEST_URI "@rx ${We(c)}"`];if(n.methods?.length)u.push(` "chain,id:${s},phase:1,pass,nolog,setvar:'tx.ts_cloud_ratelimit=${We(n.id)}'"`);else u.push(` "id:${s},phase:1,pass,nolog,setvar:'tx.ts_cloud_ratelimit=${We(n.id)}'"`);if(t.push(`# Marks requests governed by the ts-cloud rate limit "${We(n.id)}".`),t.push(u.join(" \\\n")),n.methods?.length)t.push(` SecRule REQUEST_METHOD "@within ${We(n.methods.join(" ").toUpperCase())}" "t:none"`);t.push(""),s++}return{lines:t,unmapped:o}}function uc(e){return`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,"\x01").replace(/\*/g,"[^/]*").replace(/\u0001/g,".*")}$`}function ci(e={},r=[]){let t=e.mode??l.mode,o=[],s=e.paranoiaLevel??l.paranoiaLevel,n=e.inboundThreshold??l.inboundThreshold,c=e.outboundThreshold??l.outboundThreshold,u=e.maxBodyBytes??l.maxBodyBytes,h=e.rejectOversizedBody!==!1;if(t==="blocking"&&s>=3)o.push(`Paranoia level ${s} blocks legitimate traffic on most applications until it is tuned. Run it in detection mode first.`);if(t==="blocking")o.push("zig-waf is pre-alpha. Blocking mode makes it a failure path for every request.");if(!h)o.push("Oversized bodies are passed through uninspected, so padding a request bypasses every rule.");if(e.bypassPaths?.length)o.push(`${e.bypassPaths.length} path(s) bypass inspection entirely.`);let i=["# Managed by ts-cloud. Edits are overwritten on the next deploy.",`# Mode: ${t}. Paranoia level: ${s}.`,""];if(t==="off")return i.push("SecRuleEngine Off",""),{config:`${i.join(`
1
+ var l={mode:"detection",paranoiaLevel:1,inboundThreshold:5,outboundThreshold:4,maxBodyBytes:13107200,rejectOversizedBody:!0,auditLogPath:"/var/log/ts-cloud/waf-audit.log",blockStatus:403},d={bypassBase:1e5,exclusionBase:101000,rateLimitBase:102000,customBase:109000};function We(e){return e.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/[\r\n]+/g," ")}function as(e){if(e.length>1000)return!1;if(/\([^)]*[+*]\)[+*]/.test(e))return!1;if(/\[[^\]]*\][+*]\{/.test(e))return!1;try{return new RegExp(e),!0}catch{return!1}}function b(e,r){let t=[],o=[],s=r;for(let n of e){if(n.enabled===!1)continue;if(n.key&&(n.key.source==="cookie"||n.key.source==="header")&&!n.key.name){o.push({ruleId:n.id,reason:"The rule keys on a header or cookie but names none."});continue}let c=n.path?uc(n.path):".*";if(!as(c)){o.push({ruleId:n.id,reason:"The path pattern compiles to an unsafe regular expression."});continue}let u=[`SecRule REQUEST_URI "@rx ${We(c)}"`];if(n.methods?.length)u.push(` "chain,id:${s},phase:1,pass,nolog,setvar:'tx.ts_cloud_ratelimit=${We(n.id)}'"`);else u.push(` "id:${s},phase:1,pass,nolog,setvar:'tx.ts_cloud_ratelimit=${We(n.id)}'"`);if(t.push(`# Marks requests governed by the ts-cloud rate limit "${We(n.id)}".`),t.push(u.join(" \\\n")),n.methods?.length)t.push(` SecRule REQUEST_METHOD "@within ${We(n.methods.join(" ").toUpperCase())}" "t:none"`);t.push(""),s++}return{lines:t,unmapped:o}}function uc(e){return`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,"\x01").replace(/\*/g,"[^/]*").replace(/\u0001/g,".*")}$`}function ci(e={},r=[]){let t=e.mode??l.mode,o=[],s=e.paranoiaLevel??l.paranoiaLevel,n=e.inboundThreshold??l.inboundThreshold,c=e.outboundThreshold??l.outboundThreshold,u=e.maxBodyBytes??l.maxBodyBytes,h=e.rejectOversizedBody!==!1;if(t==="blocking"&&s>=3)o.push(`Paranoia level ${s} blocks legitimate traffic on most applications until it is tuned. Run it in detection mode first.`);if(t==="blocking")o.push("zig-waf is pre-alpha. Blocking mode makes it a failure path for every request.");if(!h)o.push("Oversized bodies are passed through uninspected, so padding a request bypasses every rule.");if(e.bypassPaths?.length)o.push(`${e.bypassPaths.length} path(s) bypass inspection entirely.`);let i=["# Managed by ts-cloud. Edits are overwritten on the next deploy.",`# Mode: ${t}. Paranoia level: ${s}.`,""];if(t==="off")return i.push("SecRuleEngine Off",""),{config:`${i.join(`
2
2
  `)}
3
- `,unmappedRateLimits:[],warnings:o,mode:t};i.push(`SecRuleEngine ${t==="blocking"?"On":"DetectionOnly"}`,"SecRequestBodyAccess On","SecResponseBodyAccess Off",`SecRequestBodyLimit ${u}`,`SecRequestBodyNoFilesLimit ${Math.min(u,131072)}`,`SecRequestBodyLimitAction ${h?"Reject":"ProcessPartial"}`,"SecRequestBodyInMemoryLimit 131072",`SecAuditEngine ${t==="blocking"?"RelevantOnly":"On"}`,"SecAuditLogParts ABIJDEFHZ",`SecAuditLog ${We(e.auditLogPath??l.auditLogPath)}`,"SecAuditLogType Serial",`SecDefaultAction "phase:1,log,auditlog,${t==="blocking"?`deny,status:${e.blockStatus??l.blockStatus}`:"pass"}"`,"","# CRS anomaly scoring setup.",`SecAction "id:900000,phase:1,pass,nolog,t:none,setvar:tx.paranoia_level=${s}"`,`SecAction "id:900001,phase:1,pass,nolog,t:none,setvar:tx.inbound_anomaly_score_threshold=${n}"`,`SecAction "id:900002,phase:1,pass,nolog,t:none,setvar:tx.outbound_anomaly_score_threshold=${c}"`,'SecAction "id:900003,phase:1,pass,nolog,t:none,setvar:tx.critical_anomaly_score=5,setvar:tx.error_anomaly_score=4,setvar:tx.warning_anomaly_score=3,setvar:tx.notice_anomaly_score=2"','SecAction "id:900004,phase:1,pass,nolog,t:none,setvar:tx.anomaly_score=0"',"");let g=d.bypassBase;for(let a of e.bypassPaths??[]){let y=uc(a);if(!oo(y)){o.push(`Bypass path "${a}" was dropped: it compiles to an unsafe regular expression.`);continue}i.push(`# Inspection bypass for ${We(a)}. Every bypass is an unguarded route.`,`SecRule REQUEST_URI "@rx ${We(y)}" "id:${g},phase:1,pass,nolog,ctl:ruleEngine=Off"`,""),g++}let m=d.exclusionBase;for(let a of e.exclusions??[]){if(!Number.isInteger(a.ruleId)||a.ruleId<=0){o.push(`Exclusion with rule id "${a.ruleId}" was dropped: the id is not a positive integer.`);continue}if(i.push(`# ${We(a.reason)}`),a.pathPattern){if(!oo(a.pathPattern)){o.push(`Exclusion for rule ${a.ruleId} was dropped: its path pattern is unsafe.`);continue}i.push(`SecRule REQUEST_URI "@rx ${We(a.pathPattern)}" "id:${m},phase:1,pass,nolog,ctl:ruleRemoveById=${a.ruleId}"`),m++}else i.push(`SecRuleRemoveById ${a.ruleId}`);i.push("")}let p=b(r,d.rateLimitBase);if(p.lines.length>0)i.push("# Rate-limit route markers. SecLang has no counters, so the tag is set","# here and the counting stays in the ts-cloud limiter.",...p.lines);let f=d.customBase;for(let a of e.customRules??[])i.push(`# Operator-supplied rule ${f}.`,a.trim(),""),f++;if(t==="blocking")i.push("# Blocking decision: one rule, at the end, on the accumulated score.",`SecRule TX:ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" "id:949110,phase:2,deny,status:${e.blockStatus??l.blockStatus},log,msg:'Inbound anomaly score exceeded (total: %{tx.anomaly_score})'"`,"");return{config:`${i.join(`
3
+ `,unmappedRateLimits:[],warnings:o,mode:t};i.push(`SecRuleEngine ${t==="blocking"?"On":"DetectionOnly"}`,"SecRequestBodyAccess On","SecResponseBodyAccess Off",`SecRequestBodyLimit ${u}`,`SecRequestBodyNoFilesLimit ${Math.min(u,131072)}`,`SecRequestBodyLimitAction ${h?"Reject":"ProcessPartial"}`,"SecRequestBodyInMemoryLimit 131072",`SecAuditEngine ${t==="blocking"?"RelevantOnly":"On"}`,"SecAuditLogParts ABIJDEFHZ",`SecAuditLog ${We(e.auditLogPath??l.auditLogPath)}`,"SecAuditLogType Serial",`SecDefaultAction "phase:1,log,auditlog,${t==="blocking"?`deny,status:${e.blockStatus??l.blockStatus}`:"pass"}"`,"","# CRS anomaly scoring setup.",`SecAction "id:900000,phase:1,pass,nolog,t:none,setvar:tx.paranoia_level=${s}"`,`SecAction "id:900001,phase:1,pass,nolog,t:none,setvar:tx.inbound_anomaly_score_threshold=${n}"`,`SecAction "id:900002,phase:1,pass,nolog,t:none,setvar:tx.outbound_anomaly_score_threshold=${c}"`,'SecAction "id:900003,phase:1,pass,nolog,t:none,setvar:tx.critical_anomaly_score=5,setvar:tx.error_anomaly_score=4,setvar:tx.warning_anomaly_score=3,setvar:tx.notice_anomaly_score=2"','SecAction "id:900004,phase:1,pass,nolog,t:none,setvar:tx.anomaly_score=0"',"");let g=d.bypassBase;for(let a of e.bypassPaths??[]){let y=uc(a);if(!as(y)){o.push(`Bypass path "${a}" was dropped: it compiles to an unsafe regular expression.`);continue}i.push(`# Inspection bypass for ${We(a)}. Every bypass is an unguarded route.`,`SecRule REQUEST_URI "@rx ${We(y)}" "id:${g},phase:1,pass,nolog,ctl:ruleEngine=Off"`,""),g++}let m=d.exclusionBase;for(let a of e.exclusions??[]){if(!Number.isInteger(a.ruleId)||a.ruleId<=0){o.push(`Exclusion with rule id "${a.ruleId}" was dropped: the id is not a positive integer.`);continue}if(i.push(`# ${We(a.reason)}`),a.pathPattern){if(!as(a.pathPattern)){o.push(`Exclusion for rule ${a.ruleId} was dropped: its path pattern is unsafe.`);continue}i.push(`SecRule REQUEST_URI "@rx ${We(a.pathPattern)}" "id:${m},phase:1,pass,nolog,ctl:ruleRemoveById=${a.ruleId}"`),m++}else i.push(`SecRuleRemoveById ${a.ruleId}`);i.push("")}let p=b(r,d.rateLimitBase);if(p.lines.length>0)i.push("# Rate-limit route markers. SecLang has no counters, so the tag is set","# here and the counting stays in the ts-cloud limiter.",...p.lines);let f=d.customBase;for(let a of e.customRules??[])i.push(`# Operator-supplied rule ${f}.`,a.trim(),""),f++;if(t==="blocking")i.push("# Blocking decision: one rule, at the end, on the accumulated score.",`SecRule TX:ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" "id:949110,phase:2,deny,status:${e.blockStatus??l.blockStatus},log,msg:'Inbound anomaly score exceeded (total: %{tx.anomaly_score})'"`,"");return{config:`${i.join(`
4
4
  `)}
5
- `,unmappedRateLimits:p.unmapped,warnings:o,mode:t}}function ao(e={},r=[],t={}){let o=t.binary??"/usr/local/bin/zig-waf",s=t.configPath??"/etc/ts-cloud/waf.conf",n=ci(e,r);return`#!/usr/bin/env bash
5
+ `,unmappedRateLimits:p.unmapped,warnings:o,mode:t}}function cs(e={},r=[],t={}){let o=t.binary??"/usr/local/bin/zig-waf",s=t.configPath??"/etc/ts-cloud/waf.conf",n=ci(e,r);return`#!/usr/bin/env bash
6
6
  # Managed by ts-cloud. Installs the zig-waf ruleset.
7
7
  set -euo pipefail
8
8
 
@@ -33,5 +33,5 @@ fi
33
33
 
34
34
  mv "${s}.new" "${s}"
35
35
  echo "ts-cloud: WAF config installed (mode: ${n.mode})"
36
- `}function Up(e,r){return e.map((t)=>({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,kind:"event",source:"zig-waf",name:t.action==="blocked"?"waf.blocked":"waf.matched",timestamp:t.timestamp,value:1,host:t.host,pathTemplate:t.path,method:t.method,attributes:{ruleId:t.ruleId??null,anomalyScore:t.anomalyScore,action:t.action,messages:t.messages.slice(0,5)}}))}
37
- export{We,oo,uc,ci,ao,Up};
36
+ `}function Bp(e,r){return e.map((t)=>({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,kind:"event",source:"zig-waf",name:t.action==="blocked"?"waf.blocked":"waf.matched",timestamp:t.timestamp,value:1,host:t.host,pathTemplate:t.path,method:t.method,attributes:{ruleId:t.ruleId??null,anomalyScore:t.anomalyScore,action:t.action,messages:t.messages.slice(0,5)}}))}
37
+ export{We,as,uc,ci,cs,Bp};
@@ -1,4 +1,4 @@
1
- import{on,W,bs,Ft,M}from"./chunk-gbpmgae9.js";import{v}from"./chunk-v4gpkkzh.js";import{Tr,E}from"./chunk-6r35j09y.js";import{g}from"./chunk-f76wtb7d.js";import{F}from"./chunk-ymfnqae6.js";function H(t){let{bucketName:i,domain:a,aliases:e,certificateArn:d,defaultRootObject:o="index.html",errorDocument:n="404.html",passthroughUrls:r=!1,singlePageApp:l=!1,dynamicApp:m=!1,computeOriginDomain:D,computeOriginPort:P=3008,computeOriginId:N="app-compute",retainOnStackDelete:O=!1}=t,C=O?{DeletionPolicy:"Retain",UpdateReplacePolicy:"Retain"}:{},w=m&&!!D,T=w?["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"]:["GET","HEAD"],R=w?["GET","HEAD"]:["GET","HEAD"],y={},I={};y.S3Bucket={Type:"AWS::S3::Bucket",...C,Properties:{BucketName:i,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!1,IgnorePublicAcls:!0,RestrictPublicBuckets:!1},WebsiteConfiguration:{IndexDocument:o,ErrorDocument:n}}},I.BucketName={Description:"S3 Bucket Name",Value:{Ref:"S3Bucket"}},I.BucketArn={Description:"S3 Bucket ARN",Value:{"Fn::GetAtt":["S3Bucket","Arn"]}},y.CloudFrontOAC={Type:"AWS::CloudFront::OriginAccessControl",...C,Properties:{OriginAccessControlConfig:{Name:`OAC-${i}`,Description:`OAC for ${i}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}};let A;if(r&&w)A="InstallRootRedirectFunction",y[A]={Type:"AWS::CloudFront::Function",Properties:{Name:{"Fn::Sub":"${AWS::StackName}-install-root-redirect"},AutoPublish:!0,FunctionConfig:{Comment:"Redirect curl pantry.dev | bash (GET /) to /install.sh on S3",Runtime:"cloudfront-js-2.0"},FunctionCode:`function handler(event) {
1
+ import{sn,W,So,Ft,M}from"./chunk-w8jfw39t.js";import{v}from"./chunk-0ynfqf9t.js";import{Tr,E}from"./chunk-5wqjqh6c.js";import{g}from"./chunk-tt3m3fda.js";import{F}from"./chunk-gc8p1tdr.js";function H(t){let{bucketName:i,domain:a,aliases:e,certificateArn:d,defaultRootObject:o="index.html",errorDocument:n="404.html",passthroughUrls:r=!1,singlePageApp:l=!1,dynamicApp:m=!1,computeOriginDomain:D,computeOriginPort:P=3008,computeOriginId:N="app-compute",retainOnStackDelete:O=!1}=t,C=O?{DeletionPolicy:"Retain",UpdateReplacePolicy:"Retain"}:{},w=m&&!!D,T=w?["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"]:["GET","HEAD"],R=w?["GET","HEAD"]:["GET","HEAD"],y={},I={};y.S3Bucket={Type:"AWS::S3::Bucket",...C,Properties:{BucketName:i,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!1,IgnorePublicAcls:!0,RestrictPublicBuckets:!1},WebsiteConfiguration:{IndexDocument:o,ErrorDocument:n}}},I.BucketName={Description:"S3 Bucket Name",Value:{Ref:"S3Bucket"}},I.BucketArn={Description:"S3 Bucket ARN",Value:{"Fn::GetAtt":["S3Bucket","Arn"]}},y.CloudFrontOAC={Type:"AWS::CloudFront::OriginAccessControl",...C,Properties:{OriginAccessControlConfig:{Name:`OAC-${i}`,Description:`OAC for ${i}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}};let A;if(r&&w)A="InstallRootRedirectFunction",y[A]={Type:"AWS::CloudFront::Function",Properties:{Name:{"Fn::Sub":"${AWS::StackName}-install-root-redirect"},AutoPublish:!0,FunctionConfig:{Comment:"Redirect curl pantry.dev | bash (GET /) to /install.sh on S3",Runtime:"cloudfront-js-2.0"},FunctionCode:`function handler(event) {
2
2
  var request = event.request;
3
3
  if (request.uri === '/' || request.uri === '') {
4
4
  return {
@@ -42,7 +42,7 @@ import{on,W,bs,Ft,M}from"./chunk-gbpmgae9.js";import{v}from"./chunk-v4gpkkzh.js"
42
42
  │ │
43
43
  │ Verification typically takes 1-2 business days. │
44
44
  │ After verification, re-run: bunx bunpress deploy │
45
- └─────────────────────────────────────────────────────────────────────────────┘`),{success:!1,stackId:I,stackName:o,bucket:w,message:"CloudFront account verification required. Please contact AWS Support."}}return{success:!1,stackId:I,stackName:o,bucket:w,message:`Stack deployment failed: ${s.message}`}}let c=(await n.describeStacks({stackName:o})).Stacks[0]?.Outputs||[],S=(s)=>c.find((u)=>u.OutputKey===s)?.OutputValue,p=S("DistributionDomain");if(p&&l)console.log(`Creating DNS records via ${l.name}...`),await V(l,e,p);else if(p&&!l)console.log("Skipping DNS record creation (DNS verification was skipped)");return{success:!0,stackId:I,stackName:o,bucket:S("BucketName")||w,distributionId:S("DistributionId"),distributionDomain:p,domain:e,certificateArn:m,message:"Static site infrastructure deployed successfully with external DNS"}}async function V(t,i,a){if(!t){console.log("Skipping DNS record creation (DNS verification was skipped)");return}if(i.split(".").length===2)if(t instanceof on){console.log(`Creating Route53 alias record for apex domain ${i} -> ${a}`);let o=await t.createCloudFrontAlias({domain:i,name:i,cloudFrontDomainName:a});if(!o.success)console.warn(`Warning: Could not create Route53 alias record: ${o.message}`),console.warn("Please manually create an A-record alias in Route53:"),console.warn(` ${i} -> ${a}`);else console.log(`Created Route53 alias record: ${i} -> ${a}`);let n=`www.${i}`;console.log(`Creating Route53 alias record for ${n} -> ${a}`);let r=await t.createCloudFrontAlias({domain:i,name:n,cloudFrontDomainName:a});if(!r.success)console.warn(`Warning: Could not create www Route53 alias: ${r.message}`),console.warn("Please manually create an A-record alias in Route53:"),console.warn(` ${n} -> ${a}`);else console.log(`Created Route53 alias record: ${n} -> ${a}`)}else{try{let l=await t.listRecords(i,"A");if(l.success)for(let m of l.records){let D=m.name.replace(/\.$/,"");if(D===i||D==="")console.log(`Removing existing root A record (${m.content}) to make room for ALIAS...`),await t.deleteRecord(i,{name:i,type:"A",content:m.content})}}catch(l){console.log(`Note: Could not check for conflicting A records: ${l instanceof Error?l.message:l}`)}console.log(`Creating ALIAS record for apex domain ${i} -> ${a}`);let o=await t.upsertRecord(i,{name:i,type:"ALIAS",content:a,ttl:600});if(!o.success)console.warn(`Warning: Could not create ALIAS record: ${o.message}`),console.warn("Please manually create an ALIAS record in your DNS provider:"),console.warn(` ${i} -> ${a}`);else console.log(`Created ALIAS record: ${i} -> ${a}`);let n=`www.${i}`;console.log(`Creating CNAME record for ${n} -> ${a}`);let r=await t.upsertRecord(i,{name:n,type:"CNAME",content:a,ttl:600});if(!r.success)console.warn(`Warning: Could not create www DNS record: ${r.message}`),console.warn("Please manually create a CNAME record:"),console.warn(` ${n} -> ${a}`);else console.log(`Created CNAME record: ${n} -> ${a}`)}else{console.log(`Creating CNAME record for ${i} -> ${a}`);let o=await t.upsertRecord(i,{name:i,type:"CNAME",content:a,ttl:600});if(!o.success)console.warn(`Warning: Could not create DNS record: ${o.message}`),console.warn("Please manually create a CNAME record:"),console.warn(` ${i} -> ${a}`);else console.log(`Created CNAME record: ${i} -> ${a}`)}}async function Fi(t){let{sourceDir:i,cleanBucket:a=!1,onProgress:e,...d}=t;e?.("infrastructure","Deploying CloudFormation stack...");let o=await j(d);if(!o.success)return o;if(a){e?.("clean","Cleaning old files from S3...");try{await new g(d.region||"us-east-1").emptyBucket(o.bucket)}catch(m){console.log(`Note: Could not clean bucket: ${m.message}`)}}e?.("upload","Uploading files to S3...");let{uploadStaticFiles:n}=await import("./chunk-tkz95bkg.js"),r=await n({sourceDir:i,bucket:o.bucket,region:d.region||"us-east-1",cacheControl:d.cacheControl,onProgress:(m,D,P)=>{e?.("upload",`${m}/${D}: ${P}`)}});if(r.errors.length>0)return{...o,success:!1,message:`Upload errors: ${r.errors.join(", ")}`,filesUploaded:r.uploaded};if(o.distributionId&&r.uploaded>0){e?.("invalidate","Invalidating CloudFront cache...");let{invalidateCache:m}=await import("./chunk-tkz95bkg.js");await m(o.distributionId)}e?.("complete","Deployment complete!");let l=r.skipped>0?`Deployed ${r.uploaded} files (${r.skipped} unchanged) with external DNS`:`Deployed ${r.uploaded} files successfully with external DNS`;return{...o,filesUploaded:r.uploaded,filesSkipped:r.skipped,message:l}}function bd(t){let{bucketName:i,domain:a,certificateArn:e,hostedZoneId:d,defaultRootObject:o="index.html",errorDocument:n="404.html"}=t,r={},l={};r.S3Bucket={Type:"AWS::S3::Bucket",Properties:{BucketName:i,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!1,IgnorePublicAcls:!0,RestrictPublicBuckets:!1},WebsiteConfiguration:{IndexDocument:o,ErrorDocument:n}}},l.BucketName={Description:"S3 Bucket Name",Value:{Ref:"S3Bucket"}},l.BucketArn={Description:"S3 Bucket ARN",Value:{"Fn::GetAtt":["S3Bucket","Arn"]}},r.CloudFrontOAC={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`OAC-${i}`,Description:`OAC for ${i}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},r.UrlRewriteFunction={Type:"AWS::CloudFront::Function",Properties:{Name:{"Fn::Sub":"${AWS::StackName}-url-rewrite"},AutoPublish:!0,FunctionConfig:{Comment:"Append .html extension to URLs without extensions",Runtime:"cloudfront-js-2.0"},FunctionCode:`function handler(event) {
45
+ └─────────────────────────────────────────────────────────────────────────────┘`),{success:!1,stackId:I,stackName:o,bucket:w,message:"CloudFront account verification required. Please contact AWS Support."}}return{success:!1,stackId:I,stackName:o,bucket:w,message:`Stack deployment failed: ${s.message}`}}let c=(await n.describeStacks({stackName:o})).Stacks[0]?.Outputs||[],S=(s)=>c.find((u)=>u.OutputKey===s)?.OutputValue,p=S("DistributionDomain");if(p&&l)console.log(`Creating DNS records via ${l.name}...`),await V(l,e,p);else if(p&&!l)console.log("Skipping DNS record creation (DNS verification was skipped)");return{success:!0,stackId:I,stackName:o,bucket:S("BucketName")||w,distributionId:S("DistributionId"),distributionDomain:p,domain:e,certificateArn:m,message:"Static site infrastructure deployed successfully with external DNS"}}async function V(t,i,a){if(!t){console.log("Skipping DNS record creation (DNS verification was skipped)");return}if(i.split(".").length===2)if(t instanceof sn){console.log(`Creating Route53 alias record for apex domain ${i} -> ${a}`);let o=await t.createCloudFrontAlias({domain:i,name:i,cloudFrontDomainName:a});if(!o.success)console.warn(`Warning: Could not create Route53 alias record: ${o.message}`),console.warn("Please manually create an A-record alias in Route53:"),console.warn(` ${i} -> ${a}`);else console.log(`Created Route53 alias record: ${i} -> ${a}`);let n=`www.${i}`;console.log(`Creating Route53 alias record for ${n} -> ${a}`);let r=await t.createCloudFrontAlias({domain:i,name:n,cloudFrontDomainName:a});if(!r.success)console.warn(`Warning: Could not create www Route53 alias: ${r.message}`),console.warn("Please manually create an A-record alias in Route53:"),console.warn(` ${n} -> ${a}`);else console.log(`Created Route53 alias record: ${n} -> ${a}`)}else{try{let l=await t.listRecords(i,"A");if(l.success)for(let m of l.records){let D=m.name.replace(/\.$/,"");if(D===i||D==="")console.log(`Removing existing root A record (${m.content}) to make room for ALIAS...`),await t.deleteRecord(i,{name:i,type:"A",content:m.content})}}catch(l){console.log(`Note: Could not check for conflicting A records: ${l instanceof Error?l.message:l}`)}console.log(`Creating ALIAS record for apex domain ${i} -> ${a}`);let o=await t.upsertRecord(i,{name:i,type:"ALIAS",content:a,ttl:600});if(!o.success)console.warn(`Warning: Could not create ALIAS record: ${o.message}`),console.warn("Please manually create an ALIAS record in your DNS provider:"),console.warn(` ${i} -> ${a}`);else console.log(`Created ALIAS record: ${i} -> ${a}`);let n=`www.${i}`;console.log(`Creating CNAME record for ${n} -> ${a}`);let r=await t.upsertRecord(i,{name:n,type:"CNAME",content:a,ttl:600});if(!r.success)console.warn(`Warning: Could not create www DNS record: ${r.message}`),console.warn("Please manually create a CNAME record:"),console.warn(` ${n} -> ${a}`);else console.log(`Created CNAME record: ${n} -> ${a}`)}else{console.log(`Creating CNAME record for ${i} -> ${a}`);let o=await t.upsertRecord(i,{name:i,type:"CNAME",content:a,ttl:600});if(!o.success)console.warn(`Warning: Could not create DNS record: ${o.message}`),console.warn("Please manually create a CNAME record:"),console.warn(` ${i} -> ${a}`);else console.log(`Created CNAME record: ${i} -> ${a}`)}}async function Fi(t){let{sourceDir:i,cleanBucket:a=!1,onProgress:e,...d}=t;e?.("infrastructure","Deploying CloudFormation stack...");let o=await j(d);if(!o.success)return o;if(a){e?.("clean","Cleaning old files from S3...");try{await new g(d.region||"us-east-1").emptyBucket(o.bucket)}catch(m){console.log(`Note: Could not clean bucket: ${m.message}`)}}e?.("upload","Uploading files to S3...");let{uploadStaticFiles:n}=await import("./chunk-fh5bjm3d.js"),r=await n({sourceDir:i,bucket:o.bucket,region:d.region||"us-east-1",cacheControl:d.cacheControl,onProgress:(m,D,P)=>{e?.("upload",`${m}/${D}: ${P}`)}});if(r.errors.length>0)return{...o,success:!1,message:`Upload errors: ${r.errors.join(", ")}`,filesUploaded:r.uploaded};if(o.distributionId&&r.uploaded>0){e?.("invalidate","Invalidating CloudFront cache...");let{invalidateCache:m}=await import("./chunk-fh5bjm3d.js");await m(o.distributionId)}e?.("complete","Deployment complete!");let l=r.skipped>0?`Deployed ${r.uploaded} files (${r.skipped} unchanged) with external DNS`:`Deployed ${r.uploaded} files successfully with external DNS`;return{...o,filesUploaded:r.uploaded,filesSkipped:r.skipped,message:l}}function bd(t){let{bucketName:i,domain:a,certificateArn:e,hostedZoneId:d,defaultRootObject:o="index.html",errorDocument:n="404.html"}=t,r={},l={};r.S3Bucket={Type:"AWS::S3::Bucket",Properties:{BucketName:i,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!1,IgnorePublicAcls:!0,RestrictPublicBuckets:!1},WebsiteConfiguration:{IndexDocument:o,ErrorDocument:n}}},l.BucketName={Description:"S3 Bucket Name",Value:{Ref:"S3Bucket"}},l.BucketArn={Description:"S3 Bucket ARN",Value:{"Fn::GetAtt":["S3Bucket","Arn"]}},r.CloudFrontOAC={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`OAC-${i}`,Description:`OAC for ${i}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},r.UrlRewriteFunction={Type:"AWS::CloudFront::Function",Properties:{Name:{"Fn::Sub":"${AWS::StackName}-url-rewrite"},AutoPublish:!0,FunctionConfig:{Comment:"Append .html extension to URLs without extensions",Runtime:"cloudfront-js-2.0"},FunctionCode:`function handler(event) {
46
46
  const request = event.request;
47
47
  var uri = request.uri;
48
48
 
@@ -56,5 +56,5 @@ import{on,W,bs,Ft,M}from"./chunk-gbpmgae9.js";import{v}from"./chunk-v4gpkkzh.js"
56
56
  }
57
57
 
58
58
  return request;
59
- }`}};let m={Enabled:!0,DefaultRootObject:o,HttpVersion:"http2and3",IPV6Enabled:!0,PriceClass:"PriceClass_100",Origins:[{Id:`S3-${i}`,DomainName:{"Fn::GetAtt":["S3Bucket","RegionalDomainName"]},S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{"Fn::GetAtt":["CloudFrontOAC","Id"]}}],DefaultCacheBehavior:{TargetOriginId:`S3-${i}`,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD"],CachedMethods:["GET","HEAD"],Compress:!0,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6",FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":["UrlRewriteFunction","FunctionARN"]}}]},CustomErrorResponses:[{ErrorCode:403,ResponseCode:200,ResponsePagePath:`/${o}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:404,ResponsePagePath:`/${n}`,ErrorCachingMinTTL:300}]};if(a&&e)m.Aliases=[a],m.ViewerCertificate={AcmCertificateArn:e,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};else m.ViewerCertificate={CloudFrontDefaultCertificate:!0};if(r.CloudFrontDistribution={Type:"AWS::CloudFront::Distribution",DependsOn:["S3Bucket","CloudFrontOAC","UrlRewriteFunction"],Properties:{DistributionConfig:m}},l.DistributionId={Description:"CloudFront Distribution ID",Value:{Ref:"CloudFrontDistribution"}},l.DistributionDomain={Description:"CloudFront Distribution Domain",Value:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]}},r.S3BucketPolicy={Type:"AWS::S3::BucketPolicy",DependsOn:["S3Bucket","CloudFrontDistribution"],Properties:{Bucket:{Ref:"S3Bucket"},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":"arn:aws:s3:::${S3Bucket}/*"},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":"arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}"}}}}]}}},a&&d)r.DNSRecord={Type:"AWS::Route53::RecordSet",DependsOn:"CloudFrontDistribution",Properties:{HostedZoneId:d,Name:a,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}},r.DNSRecordIPv6={Type:"AWS::Route53::RecordSet",DependsOn:"CloudFrontDistribution",Properties:{HostedZoneId:d,Name:a,Type:"AAAA",AliasTarget:{DNSName:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}},l.SiteUrl={Description:"Site URL",Value:{"Fn::Sub":"https://${DNSRecord}"}};return{AWSTemplateFormatVersion:"2010-09-09",Description:`Static site infrastructure for ${a||i}`,Resources:r,Outputs:l}}async function Sd(t){if(t.dnsProvider&&t.dnsProvider.provider!=="route53"){let c=t.domain||(t.subdomain&&t.baseDomain?`${t.subdomain}.${t.baseDomain}`:void 0);if(!c)return{success:!1,stackName:t.stackName||`${t.siteName}-static-site`,bucket:t.bucket||`${t.siteName}-${Date.now()}`,message:"Domain is required when using external DNS provider"};return j({siteName:t.siteName,region:t.region,domain:c,bucket:t.bucket,certificateArn:t.certificateArn,stackName:t.stackName,defaultRootObject:t.defaultRootObject,errorDocument:t.errorDocument,cacheControl:t.cacheControl,tags:t.tags,dnsProvider:t.dnsProvider})}let i=t.region||"us-east-1",a="us-east-1",e;if(t.domain)e=t.domain;else if(t.subdomain&&t.baseDomain)e=`${t.subdomain}.${t.baseDomain}`;let d=t.bucket||(e?e.replace(/\./g,"-"):`${t.siteName}-${Date.now()}`),o=t.stackName||`${t.siteName}-static-site`,n=new v(a),r=new F,l=new W("us-east-1"),m=new bs("us-east-1"),{hostedZoneId:D,certificateArn:P}=t;if(e&&!D){let c=await r.findHostedZoneForDomain(e);if(c)D=c.Id.replace("/hostedzone/","");else return{success:!1,stackName:o,bucket:d,message:`No Route53 hosted zone found for ${t.baseDomain||e}. Please create one first.`}}if(e&&!P&&D){let c=await l.findCertificateByDomain(e);if(c&&c.Status==="ISSUED")P=c.CertificateArn;else P=(await m.requestAndValidate({domainName:e,hostedZoneId:D,waitForValidation:!0,maxWaitMinutes:10})).certificateArn}let N=!1,O;try{let c=await n.describeStacks({stackName:o});if(c.Stacks.length>0){let S=c.Stacks[0],p=S.StackStatus;if(p==="DELETE_IN_PROGRESS")console.log("Previous stack is still being deleted, waiting..."),await n.waitForStack(o,"stack-delete-complete"),N=!1;else if(p==="DELETE_COMPLETE")N=!1;else N=!0,O=(S.Outputs||[]).find((u)=>u.OutputKey==="BucketName")?.OutputValue}}catch(c){if(c.message?.includes("does not exist")||c.code==="ValidationError")N=!1;else throw c}let C=O||d;if(!N){let c=new g(i),S=new E,p=!1;if(e){try{console.log(`Checking for existing CloudFront distribution for ${e}...`);let s=await S.listDistributions();for(let u of s)if((u.Aliases?.Items??[]).includes(e)){p=!0,console.log(`Found existing CloudFront distribution ${u.Id} for ${e}`);let k=await S.getDistributionConfig(u.Id),f=Tr(k.DistributionConfig);if(f){let x=e.replace(/\./g,"-");if(!f.startsWith(x)&&!f.includes(t.siteName)){console.log(`Warning: Found distribution with mismatched bucket ${f}, skipping...`);continue}if(console.log(`Using existing S3 bucket: ${f}`),D&&u.DomainName)try{console.log(`Ensuring Route53 records exist for ${e}...`),await r.createAliasRecord({HostedZoneId:D,Name:e,Type:"A",TargetHostedZoneId:F.CloudFrontHostedZoneId,TargetDNSName:u.DomainName,EvaluateTargetHealth:!1}),await r.createAliasRecord({HostedZoneId:D,Name:e,Type:"AAAA",TargetHostedZoneId:F.CloudFrontHostedZoneId,TargetDNSName:u.DomainName,EvaluateTargetHealth:!1}),console.log(`Route53 records ensured for ${e}`)}catch(U){console.log(`Note: Could not update Route53 records: ${U.message}`)}return{success:!0,stackName:`existing-${u.Id}`,bucket:f,distributionId:u.Id,distributionDomain:u.DomainName,domain:e,certificateArn:P,message:"Using existing CloudFront distribution"}}}}catch{}if(D)try{let u=(await r.listResourceRecordSets({HostedZoneId:D})).ResourceRecordSets||[];for(let b of u)if(b.Name===`${e}.`&&(b.Type==="A"||b.Type==="AAAA")){if(b.AliasTarget){console.log(`Found orphaned Route53 ${b.Type} record for ${e}, cleaning up...`);try{await r.deleteRecord({HostedZoneId:D,RecordSet:b}),console.log(`Deleted orphaned Route53 ${b.Type} record for ${e}`)}catch(k){console.log(`Note: Could not delete Route53 record: ${k.message}`)}}}}catch{}}if(!p)try{if((await c.headBucket(d)).exists){console.log(`Found orphaned S3 bucket ${d}, cleaning up...`);try{let u=c.emptyBucket(d).then(()=>c.deleteBucket(d)),b=new Promise((k,f)=>setTimeout(()=>f(Error("Bucket cleanup timeout")),30000));await Promise.race([u,b]),console.log(`Deleted orphaned S3 bucket ${d}`)}catch(u){console.log(`Note: Could not clean up S3 bucket: ${u.message}`);let b=Date.now().toString(36);C=`${d}-${b}`,console.log(`Using alternative bucket name: ${C}`)}}}catch{}}let w=bd({bucketName:C,domain:e,certificateArn:P,hostedZoneId:D,defaultRootObject:t.defaultRootObject,errorDocument:t.errorDocument}),T=Object.entries(t.tags||{}).map(([c,S])=>({Key:c,Value:S}));T.push({Key:"ManagedBy",Value:"ts-cloud"}),T.push({Key:"Application",Value:t.siteName});let R,y=!1;if(N){y=!0,console.log(`Updating CloudFormation stack: ${o}`),console.log(`Using existing bucket: ${C}`),console.log(`Domain: ${e||"not specified"}`),console.log(`Certificate ARN: ${P||"not specified"}`);try{R=(await n.updateStack({stackName:o,templateBody:JSON.stringify(w),capabilities:["CAPABILITY_IAM"],tags:T})).StackId,console.log(`Update initiated, stack ID: ${R}`)}catch(c){if(c.message?.includes("No updates are to be performed")){let S=await n.describeStacks({stackName:o});R=S.Stacks[0].StackId;let p=S.Stacks[0]?.Outputs||[],s=(u)=>p.find((b)=>b.OutputKey===u)?.OutputValue;return{success:!0,stackId:R,stackName:o,bucket:s("BucketName")||C,distributionId:s("DistributionId"),distributionDomain:s("DistributionDomain"),domain:e,certificateArn:P,message:"Static site infrastructure is already up to date"}}else throw c}}else console.log(`Creating CloudFormation stack: ${o}`),console.log(`Bucket name: ${C}`),console.log(`Domain: ${e||"not specified"}`),console.log(`Certificate ARN: ${P||"not specified"}`),console.log("Stack does not exist, creating..."),R=(await n.createStack({stackName:o,templateBody:JSON.stringify(w),capabilities:["CAPABILITY_IAM"],tags:T,onFailure:"DELETE"})).StackId,console.log(`Create initiated, stack ID: ${R}`);console.log(`Waiting for stack to reach ${y?"stack-update-complete":"stack-create-complete"}...`);try{await n.waitForStack(o,y?"stack-update-complete":"stack-create-complete"),console.log("Stack operation completed successfully!")}catch(c){if(c.message?.includes("must be verified")||c.message?.includes("Access denied for operation")||c.message?.includes("failed")){console.log("CloudFormation deployment failed, trying direct API creation...");let S=new E;if(e)try{let p=await S.listDistributions();for(let s of p)if((s.Aliases?.Items??[]).includes(e)){console.log(`Found existing CloudFront distribution ${s.Id} with alias ${e}`);let b=await S.getDistributionConfig(s.Id),k=Tr(b.DistributionConfig);if(k)return console.log(`Using existing S3 bucket: ${k}`),{success:!0,stackName:`existing-${s.Id}`,bucket:k,distributionId:s.Id,distributionDomain:s.DomainName,domain:e,certificateArn:P,message:"Using existing CloudFront distribution (account verification pending for new distributions)"}}}catch{}console.log("No existing infrastructure found, creating via direct API calls...");try{let p=new g(i);if((await p.headBucket(C)).exists)console.log(`Using existing S3 bucket: ${C}`);else console.log(`Creating S3 bucket: ${C}...`),await p.createBucket(C);await p.putBucketWebsite(C,{IndexDocument:t.defaultRootObject||"index.html",ErrorDocument:t.errorDocument||"404.html"}),await p.putPublicAccessBlock(C,{BlockPublicAcls:!0,IgnorePublicAcls:!0,BlockPublicPolicy:!1,RestrictPublicBuckets:!1}),console.log(`S3 bucket ${C} configured`);let u=`OAC-${C}`;console.log(`Creating Origin Access Control: ${u}...`);let b=await S.findOrCreateOriginAccessControl(u);console.log(`Origin Access Control ${b.Id} ready`),console.log("Creating CloudFront distribution...");let k=await S.createDistributionForS3({bucketName:C,bucketRegion:i,originAccessControlId:b.Id,aliases:e?[e]:[],certificateArn:P,defaultRootObject:t.defaultRootObject||"index.html",comment:`Distribution for ${e||C}`});console.log(`CloudFront distribution ${k.Id} created`),console.log("Updating S3 bucket policy...");let f=E.getS3BucketPolicyForCloudFront(C,k.ARN);if(await p.putBucketPolicy(C,f),console.log("S3 bucket policy updated"),e&&D){console.log(`Creating Route53 records for ${e}...`);try{await r.createAliasRecord({HostedZoneId:D,Name:e,Type:"A",TargetHostedZoneId:F.CloudFrontHostedZoneId,TargetDNSName:k.DomainName,EvaluateTargetHealth:!1}),await r.createAliasRecord({HostedZoneId:D,Name:e,Type:"AAAA",TargetHostedZoneId:F.CloudFrontHostedZoneId,TargetDNSName:k.DomainName,EvaluateTargetHealth:!1}),console.log(`Route53 records created for ${e}`)}catch(x){console.log(`Note: Could not create Route53 records: ${x.message}`)}}return{success:!0,stackName:`direct-${k.Id}`,bucket:C,distributionId:k.Id,distributionDomain:k.DomainName,domain:e,certificateArn:P,message:"Static site infrastructure created via direct API calls"}}catch(p){return console.log(`Direct API creation failed: ${p.message}`),{success:!1,stackId:R,stackName:o,bucket:C,message:`Deployment failed: ${p.message}`}}}return{success:!1,stackId:R,stackName:o,bucket:C,message:`Stack deployment failed: ${c.message}`}}let A=(await n.describeStacks({stackName:o})).Stacks[0]?.Outputs||[],h=(c)=>A.find((S)=>S.OutputKey===c)?.OutputValue;return{success:!0,stackId:R,stackName:o,bucket:h("BucketName")||C,distributionId:h("DistributionId"),distributionDomain:h("DistributionDomain"),domain:e,certificateArn:P,message:"Static site infrastructure deployed successfully"}}async function vd(t){let{sourceDir:i,bucket:a,region:e,cacheControl:d="max-age=31536000, public",onProgress:o}=t,n=new g(e),{readdir:r}=await import("node:fs/promises"),{join:l,relative:m}=await import("node:path"),{createHash:D}=await import("node:crypto");async function P(A){let h=[],c=await r(A,{withFileTypes:!0});for(let S of c){let p=l(A,S.name);if(S.isDirectory())h.push(...await P(p));else h.push(p)}return h}function N(A){let h=A.split(".").pop()?.toLowerCase();return{html:"text/html; charset=utf-8",css:"text/css; charset=utf-8",js:"application/javascript; charset=utf-8",json:"application/json; charset=utf-8",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",svg:"image/svg+xml",ico:"image/x-icon",webp:"image/webp",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",xml:"application/xml",txt:"text/plain; charset=utf-8",sh:"text/plain; charset=utf-8",bash:"text/plain; charset=utf-8",ps1:"text/plain; charset=utf-8"}[h||""]||"application/octet-stream"}function O(A){return D("md5").update(A).digest("hex")}async function C(){let A=new Map,h;do{let c=await n.listObjects({bucket:a,maxKeys:1000,continuationToken:h});for(let S of c.objects){let p=S.ETag?.replace(/"/g,"")||"";A.set(S.Key,p)}h=c.nextContinuationToken}while(h);return A}let w=await P(i),T=[],R=0,y=0,I=await C();for(let A of w){let h=m(i,A),c=N(A),S=A.endsWith(".html")?"max-age=3600, public":d;try{let p=Buffer.from(await Bun.file(A).arrayBuffer()),s=O(p),u=I.get(h);if(u&&u===s){y++,o?.(R+y,w.length,h);continue}await n.putObject({bucket:a,key:h,body:p,contentType:c,cacheControl:S}),R++,o?.(R+y,w.length,h)}catch(p){T.push(`Failed to upload ${h}: ${p.message}`)}}return{uploaded:R,skipped:y,errors:T}}async function Cd(t){return{invalidationId:(await new E().invalidateAll(t)).Id}}async function xp(t,i="us-east-1"){let a=new v(i);try{let n=((await a.describeStacks({stackName:t})).Stacks[0]?.Outputs||[]).find((r)=>r.OutputKey==="BucketName")?.OutputValue;if(n)await new g(i).emptyBucket(n)}catch{}await a.deleteStack(t);let e=await a.waitForStackComplete(t,60,1e4);return{success:e.success||e.status==="DELETE_COMPLETE",message:e.success?"Static site deleted successfully":`Deletion failed: ${e.status}`}}async function _p(t){let{sourceDir:i,cleanBucket:a=!1,onProgress:e,...d}=t;e?.("infrastructure","Deploying CloudFormation stack...");let o=await Sd(d);if(!o.success)return o;if(a){e?.("clean","Cleaning old files from S3...");try{await new g(d.region||"us-east-1").emptyBucket(o.bucket)}catch(l){console.log(`Note: Could not clean bucket: ${l.message}`)}}e?.("upload","Uploading files to S3...");let n=await vd({sourceDir:i,bucket:o.bucket,region:d.region||"us-east-1",cacheControl:d.cacheControl,onProgress:(l,m,D)=>{e?.("upload",`${l}/${m}: ${D}`)}});if(n.errors.length>0)return{...o,success:!1,message:`Upload errors: ${n.errors.join(", ")}`,filesUploaded:n.uploaded};if(o.distributionId&&n.uploaded>0)e?.("invalidate","Invalidating CloudFront cache..."),await Cd(o.distributionId);e?.("complete","Deployment complete!");let r=n.skipped>0?`Deployed ${n.uploaded} files (${n.skipped} unchanged)`:`Deployed ${n.uploaded} files successfully`;return{...o,filesUploaded:n.uploaded,filesSkipped:n.skipped,message:r}}
60
- export{bd,Sd,vd,Cd,xp,_p,Fi};
59
+ }`}};let m={Enabled:!0,DefaultRootObject:o,HttpVersion:"http2and3",IPV6Enabled:!0,PriceClass:"PriceClass_100",Origins:[{Id:`S3-${i}`,DomainName:{"Fn::GetAtt":["S3Bucket","RegionalDomainName"]},S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{"Fn::GetAtt":["CloudFrontOAC","Id"]}}],DefaultCacheBehavior:{TargetOriginId:`S3-${i}`,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD"],CachedMethods:["GET","HEAD"],Compress:!0,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6",FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":["UrlRewriteFunction","FunctionARN"]}}]},CustomErrorResponses:[{ErrorCode:403,ResponseCode:200,ResponsePagePath:`/${o}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:404,ResponsePagePath:`/${n}`,ErrorCachingMinTTL:300}]};if(a&&e)m.Aliases=[a],m.ViewerCertificate={AcmCertificateArn:e,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};else m.ViewerCertificate={CloudFrontDefaultCertificate:!0};if(r.CloudFrontDistribution={Type:"AWS::CloudFront::Distribution",DependsOn:["S3Bucket","CloudFrontOAC","UrlRewriteFunction"],Properties:{DistributionConfig:m}},l.DistributionId={Description:"CloudFront Distribution ID",Value:{Ref:"CloudFrontDistribution"}},l.DistributionDomain={Description:"CloudFront Distribution Domain",Value:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]}},r.S3BucketPolicy={Type:"AWS::S3::BucketPolicy",DependsOn:["S3Bucket","CloudFrontDistribution"],Properties:{Bucket:{Ref:"S3Bucket"},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":"arn:aws:s3:::${S3Bucket}/*"},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":"arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}"}}}}]}}},a&&d)r.DNSRecord={Type:"AWS::Route53::RecordSet",DependsOn:"CloudFrontDistribution",Properties:{HostedZoneId:d,Name:a,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}},r.DNSRecordIPv6={Type:"AWS::Route53::RecordSet",DependsOn:"CloudFrontDistribution",Properties:{HostedZoneId:d,Name:a,Type:"AAAA",AliasTarget:{DNSName:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}},l.SiteUrl={Description:"Site URL",Value:{"Fn::Sub":"https://${DNSRecord}"}};return{AWSTemplateFormatVersion:"2010-09-09",Description:`Static site infrastructure for ${a||i}`,Resources:r,Outputs:l}}async function Sd(t){if(t.dnsProvider&&t.dnsProvider.provider!=="route53"){let c=t.domain||(t.subdomain&&t.baseDomain?`${t.subdomain}.${t.baseDomain}`:void 0);if(!c)return{success:!1,stackName:t.stackName||`${t.siteName}-static-site`,bucket:t.bucket||`${t.siteName}-${Date.now()}`,message:"Domain is required when using external DNS provider"};return j({siteName:t.siteName,region:t.region,domain:c,bucket:t.bucket,certificateArn:t.certificateArn,stackName:t.stackName,defaultRootObject:t.defaultRootObject,errorDocument:t.errorDocument,cacheControl:t.cacheControl,tags:t.tags,dnsProvider:t.dnsProvider})}let i=t.region||"us-east-1",a="us-east-1",e;if(t.domain)e=t.domain;else if(t.subdomain&&t.baseDomain)e=`${t.subdomain}.${t.baseDomain}`;let d=t.bucket||(e?e.replace(/\./g,"-"):`${t.siteName}-${Date.now()}`),o=t.stackName||`${t.siteName}-static-site`,n=new v(a),r=new F,l=new W("us-east-1"),m=new So("us-east-1"),{hostedZoneId:D,certificateArn:P}=t;if(e&&!D){let c=await r.findHostedZoneForDomain(e);if(c)D=c.Id.replace("/hostedzone/","");else return{success:!1,stackName:o,bucket:d,message:`No Route53 hosted zone found for ${t.baseDomain||e}. Please create one first.`}}if(e&&!P&&D){let c=await l.findCertificateByDomain(e);if(c&&c.Status==="ISSUED")P=c.CertificateArn;else P=(await m.requestAndValidate({domainName:e,hostedZoneId:D,waitForValidation:!0,maxWaitMinutes:10})).certificateArn}let N=!1,O;try{let c=await n.describeStacks({stackName:o});if(c.Stacks.length>0){let S=c.Stacks[0],p=S.StackStatus;if(p==="DELETE_IN_PROGRESS")console.log("Previous stack is still being deleted, waiting..."),await n.waitForStack(o,"stack-delete-complete"),N=!1;else if(p==="DELETE_COMPLETE")N=!1;else N=!0,O=(S.Outputs||[]).find((u)=>u.OutputKey==="BucketName")?.OutputValue}}catch(c){if(c.message?.includes("does not exist")||c.code==="ValidationError")N=!1;else throw c}let C=O||d;if(!N){let c=new g(i),S=new E,p=!1;if(e){try{console.log(`Checking for existing CloudFront distribution for ${e}...`);let s=await S.listDistributions();for(let u of s)if((u.Aliases?.Items??[]).includes(e)){p=!0,console.log(`Found existing CloudFront distribution ${u.Id} for ${e}`);let k=await S.getDistributionConfig(u.Id),f=Tr(k.DistributionConfig);if(f){let x=e.replace(/\./g,"-");if(!f.startsWith(x)&&!f.includes(t.siteName)){console.log(`Warning: Found distribution with mismatched bucket ${f}, skipping...`);continue}if(console.log(`Using existing S3 bucket: ${f}`),D&&u.DomainName)try{console.log(`Ensuring Route53 records exist for ${e}...`),await r.createAliasRecord({HostedZoneId:D,Name:e,Type:"A",TargetHostedZoneId:F.CloudFrontHostedZoneId,TargetDNSName:u.DomainName,EvaluateTargetHealth:!1}),await r.createAliasRecord({HostedZoneId:D,Name:e,Type:"AAAA",TargetHostedZoneId:F.CloudFrontHostedZoneId,TargetDNSName:u.DomainName,EvaluateTargetHealth:!1}),console.log(`Route53 records ensured for ${e}`)}catch(U){console.log(`Note: Could not update Route53 records: ${U.message}`)}return{success:!0,stackName:`existing-${u.Id}`,bucket:f,distributionId:u.Id,distributionDomain:u.DomainName,domain:e,certificateArn:P,message:"Using existing CloudFront distribution"}}}}catch{}if(D)try{let u=(await r.listResourceRecordSets({HostedZoneId:D})).ResourceRecordSets||[];for(let b of u)if(b.Name===`${e}.`&&(b.Type==="A"||b.Type==="AAAA")){if(b.AliasTarget){console.log(`Found orphaned Route53 ${b.Type} record for ${e}, cleaning up...`);try{await r.deleteRecord({HostedZoneId:D,RecordSet:b}),console.log(`Deleted orphaned Route53 ${b.Type} record for ${e}`)}catch(k){console.log(`Note: Could not delete Route53 record: ${k.message}`)}}}}catch{}}if(!p)try{if((await c.headBucket(d)).exists){console.log(`Found orphaned S3 bucket ${d}, cleaning up...`);try{let u=c.emptyBucket(d).then(()=>c.deleteBucket(d)),b=new Promise((k,f)=>setTimeout(()=>f(Error("Bucket cleanup timeout")),30000));await Promise.race([u,b]),console.log(`Deleted orphaned S3 bucket ${d}`)}catch(u){console.log(`Note: Could not clean up S3 bucket: ${u.message}`);let b=Date.now().toString(36);C=`${d}-${b}`,console.log(`Using alternative bucket name: ${C}`)}}}catch{}}let w=bd({bucketName:C,domain:e,certificateArn:P,hostedZoneId:D,defaultRootObject:t.defaultRootObject,errorDocument:t.errorDocument}),T=Object.entries(t.tags||{}).map(([c,S])=>({Key:c,Value:S}));T.push({Key:"ManagedBy",Value:"ts-cloud"}),T.push({Key:"Application",Value:t.siteName});let R,y=!1;if(N){y=!0,console.log(`Updating CloudFormation stack: ${o}`),console.log(`Using existing bucket: ${C}`),console.log(`Domain: ${e||"not specified"}`),console.log(`Certificate ARN: ${P||"not specified"}`);try{R=(await n.updateStack({stackName:o,templateBody:JSON.stringify(w),capabilities:["CAPABILITY_IAM"],tags:T})).StackId,console.log(`Update initiated, stack ID: ${R}`)}catch(c){if(c.message?.includes("No updates are to be performed")){let S=await n.describeStacks({stackName:o});R=S.Stacks[0].StackId;let p=S.Stacks[0]?.Outputs||[],s=(u)=>p.find((b)=>b.OutputKey===u)?.OutputValue;return{success:!0,stackId:R,stackName:o,bucket:s("BucketName")||C,distributionId:s("DistributionId"),distributionDomain:s("DistributionDomain"),domain:e,certificateArn:P,message:"Static site infrastructure is already up to date"}}else throw c}}else console.log(`Creating CloudFormation stack: ${o}`),console.log(`Bucket name: ${C}`),console.log(`Domain: ${e||"not specified"}`),console.log(`Certificate ARN: ${P||"not specified"}`),console.log("Stack does not exist, creating..."),R=(await n.createStack({stackName:o,templateBody:JSON.stringify(w),capabilities:["CAPABILITY_IAM"],tags:T,onFailure:"DELETE"})).StackId,console.log(`Create initiated, stack ID: ${R}`);console.log(`Waiting for stack to reach ${y?"stack-update-complete":"stack-create-complete"}...`);try{await n.waitForStack(o,y?"stack-update-complete":"stack-create-complete"),console.log("Stack operation completed successfully!")}catch(c){if(c.message?.includes("must be verified")||c.message?.includes("Access denied for operation")||c.message?.includes("failed")){console.log("CloudFormation deployment failed, trying direct API creation...");let S=new E;if(e)try{let p=await S.listDistributions();for(let s of p)if((s.Aliases?.Items??[]).includes(e)){console.log(`Found existing CloudFront distribution ${s.Id} with alias ${e}`);let b=await S.getDistributionConfig(s.Id),k=Tr(b.DistributionConfig);if(k)return console.log(`Using existing S3 bucket: ${k}`),{success:!0,stackName:`existing-${s.Id}`,bucket:k,distributionId:s.Id,distributionDomain:s.DomainName,domain:e,certificateArn:P,message:"Using existing CloudFront distribution (account verification pending for new distributions)"}}}catch{}console.log("No existing infrastructure found, creating via direct API calls...");try{let p=new g(i);if((await p.headBucket(C)).exists)console.log(`Using existing S3 bucket: ${C}`);else console.log(`Creating S3 bucket: ${C}...`),await p.createBucket(C);await p.putBucketWebsite(C,{IndexDocument:t.defaultRootObject||"index.html",ErrorDocument:t.errorDocument||"404.html"}),await p.putPublicAccessBlock(C,{BlockPublicAcls:!0,IgnorePublicAcls:!0,BlockPublicPolicy:!1,RestrictPublicBuckets:!1}),console.log(`S3 bucket ${C} configured`);let u=`OAC-${C}`;console.log(`Creating Origin Access Control: ${u}...`);let b=await S.findOrCreateOriginAccessControl(u);console.log(`Origin Access Control ${b.Id} ready`),console.log("Creating CloudFront distribution...");let k=await S.createDistributionForS3({bucketName:C,bucketRegion:i,originAccessControlId:b.Id,aliases:e?[e]:[],certificateArn:P,defaultRootObject:t.defaultRootObject||"index.html",comment:`Distribution for ${e||C}`});console.log(`CloudFront distribution ${k.Id} created`),console.log("Updating S3 bucket policy...");let f=E.getS3BucketPolicyForCloudFront(C,k.ARN);if(await p.putBucketPolicy(C,f),console.log("S3 bucket policy updated"),e&&D){console.log(`Creating Route53 records for ${e}...`);try{await r.createAliasRecord({HostedZoneId:D,Name:e,Type:"A",TargetHostedZoneId:F.CloudFrontHostedZoneId,TargetDNSName:k.DomainName,EvaluateTargetHealth:!1}),await r.createAliasRecord({HostedZoneId:D,Name:e,Type:"AAAA",TargetHostedZoneId:F.CloudFrontHostedZoneId,TargetDNSName:k.DomainName,EvaluateTargetHealth:!1}),console.log(`Route53 records created for ${e}`)}catch(x){console.log(`Note: Could not create Route53 records: ${x.message}`)}}return{success:!0,stackName:`direct-${k.Id}`,bucket:C,distributionId:k.Id,distributionDomain:k.DomainName,domain:e,certificateArn:P,message:"Static site infrastructure created via direct API calls"}}catch(p){return console.log(`Direct API creation failed: ${p.message}`),{success:!1,stackId:R,stackName:o,bucket:C,message:`Deployment failed: ${p.message}`}}}return{success:!1,stackId:R,stackName:o,bucket:C,message:`Stack deployment failed: ${c.message}`}}let A=(await n.describeStacks({stackName:o})).Stacks[0]?.Outputs||[],h=(c)=>A.find((S)=>S.OutputKey===c)?.OutputValue;return{success:!0,stackId:R,stackName:o,bucket:h("BucketName")||C,distributionId:h("DistributionId"),distributionDomain:h("DistributionDomain"),domain:e,certificateArn:P,message:"Static site infrastructure deployed successfully"}}async function vd(t){let{sourceDir:i,bucket:a,region:e,cacheControl:d="max-age=31536000, public",onProgress:o}=t,n=new g(e),{readdir:r}=await import("node:fs/promises"),{join:l,relative:m}=await import("node:path"),{createHash:D}=await import("node:crypto");async function P(A){let h=[],c=await r(A,{withFileTypes:!0});for(let S of c){let p=l(A,S.name);if(S.isDirectory())h.push(...await P(p));else h.push(p)}return h}function N(A){let h=A.split(".").pop()?.toLowerCase();return{html:"text/html; charset=utf-8",css:"text/css; charset=utf-8",js:"application/javascript; charset=utf-8",json:"application/json; charset=utf-8",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",svg:"image/svg+xml",ico:"image/x-icon",webp:"image/webp",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",xml:"application/xml",txt:"text/plain; charset=utf-8",sh:"text/plain; charset=utf-8",bash:"text/plain; charset=utf-8",ps1:"text/plain; charset=utf-8"}[h||""]||"application/octet-stream"}function O(A){return D("md5").update(A).digest("hex")}async function C(){let A=new Map,h;do{let c=await n.listObjects({bucket:a,maxKeys:1000,continuationToken:h});for(let S of c.objects){let p=S.ETag?.replace(/"/g,"")||"";A.set(S.Key,p)}h=c.nextContinuationToken}while(h);return A}let w=await P(i),T=[],R=0,y=0,I=await C();for(let A of w){let h=m(i,A),c=N(A),S=A.endsWith(".html")?"max-age=3600, public":d;try{let p=Buffer.from(await Bun.file(A).arrayBuffer()),s=O(p),u=I.get(h);if(u&&u===s){y++,o?.(R+y,w.length,h);continue}await n.putObject({bucket:a,key:h,body:p,contentType:c,cacheControl:S}),R++,o?.(R+y,w.length,h)}catch(p){T.push(`Failed to upload ${h}: ${p.message}`)}}return{uploaded:R,skipped:y,errors:T}}async function Cd(t){return{invalidationId:(await new E().invalidateAll(t)).Id}}async function Op(t,i="us-east-1"){let a=new v(i);try{let n=((await a.describeStacks({stackName:t})).Stacks[0]?.Outputs||[]).find((r)=>r.OutputKey==="BucketName")?.OutputValue;if(n)await new g(i).emptyBucket(n)}catch{}await a.deleteStack(t);let e=await a.waitForStackComplete(t,60,1e4);return{success:e.success||e.status==="DELETE_COMPLETE",message:e.success?"Static site deleted successfully":`Deletion failed: ${e.status}`}}async function $p(t){let{sourceDir:i,cleanBucket:a=!1,onProgress:e,...d}=t;e?.("infrastructure","Deploying CloudFormation stack...");let o=await Sd(d);if(!o.success)return o;if(a){e?.("clean","Cleaning old files from S3...");try{await new g(d.region||"us-east-1").emptyBucket(o.bucket)}catch(l){console.log(`Note: Could not clean bucket: ${l.message}`)}}e?.("upload","Uploading files to S3...");let n=await vd({sourceDir:i,bucket:o.bucket,region:d.region||"us-east-1",cacheControl:d.cacheControl,onProgress:(l,m,D)=>{e?.("upload",`${l}/${m}: ${D}`)}});if(n.errors.length>0)return{...o,success:!1,message:`Upload errors: ${n.errors.join(", ")}`,filesUploaded:n.uploaded};if(o.distributionId&&n.uploaded>0)e?.("invalidate","Invalidating CloudFront cache..."),await Cd(o.distributionId);e?.("complete","Deployment complete!");let r=n.skipped>0?`Deployed ${n.uploaded} files (${n.skipped} unchanged)`:`Deployed ${n.uploaded} files successfully`;return{...o,filesUploaded:n.uploaded,filesSkipped:n.skipped,message:r}}
60
+ export{bd,Sd,vd,Cd,Op,$p,Fi};
@@ -0,0 +1 @@
1
+ import{ni}from"./chunk-4h60xsat.js";import"./chunk-sqmays54.js";import"./chunk-48nz63ab.js";import"./chunk-wga7gj0h.js";import"./chunk-e6mfcw0v.js";import"./chunk-0ynfqf9t.js";import"./chunk-tt3m3fda.js";import"./chunk-dmwfnbg0.js";import"./chunk-q8hp4dfy.js";import"./chunk-55cckkb2.js";export{ni as resolveDashboardData};
@@ -1,2 +1,2 @@
1
- import{u}from"./chunk-7rwc5bvv.js";import{_}from"./chunk-tv0rtc0s.js";class v{client;region;constructor(e="us-east-1",t){this.region=e,this.client=new u(void 0,{profile:t})}async createStack(e){let t={Action:"CreateStack",StackName:e.stackName,Version:"2010-05-15"};if(e.templateBody)t.TemplateBody=e.templateBody;else if(e.templateUrl)t.TemplateURL=e.templateUrl;else throw Error("Either templateBody or templateUrl must be provided");if(e.parameters)e.parameters.forEach((a,r)=>{t[`Parameters.member.${r+1}.ParameterKey`]=a.ParameterKey,t[`Parameters.member.${r+1}.ParameterValue`]=a.ParameterValue});if(e.capabilities)e.capabilities.forEach((a,r)=>{t[`Capabilities.member.${r+1}`]=a});if(e.roleArn)t.RoleARN=e.roleArn;if(e.tags)e.tags.forEach((a,r)=>{t[`Tags.member.${r+1}.Key`]=a.Key,t[`Tags.member.${r+1}.Value`]=a.Value});if(e.timeoutInMinutes)t.TimeoutInMinutes=e.timeoutInMinutes;if(e.onFailure)t.OnFailure=e.onFailure;let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{StackId:s.StackId||s.CreateStackResult?.StackId}}async updateStack(e){let t={Action:"UpdateStack",StackName:e.stackName,Version:"2010-05-15"};if(e.templateBody)t.TemplateBody=e.templateBody;else if(e.templateUrl)t.TemplateURL=e.templateUrl;if(e.parameters)e.parameters.forEach((a,r)=>{if(t[`Parameters.member.${r+1}.ParameterKey`]=a.ParameterKey,a.UsePreviousValue)t[`Parameters.member.${r+1}.UsePreviousValue`]="true";else t[`Parameters.member.${r+1}.ParameterValue`]=a.ParameterValue});if(e.capabilities)e.capabilities.forEach((a,r)=>{t[`Capabilities.member.${r+1}`]=a});if(e.roleArn)t.RoleARN=e.roleArn;if(e.tags)e.tags.forEach((a,r)=>{t[`Tags.member.${r+1}.Key`]=a.Key,t[`Tags.member.${r+1}.Value`]=a.Value});let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{StackId:s.StackId||s.UpdateStackResult?.StackId}}async deleteStack(e,t,s){let a={Action:"DeleteStack",StackName:e,Version:"2010-05-15"};if(t)a.RoleARN=t;if(s&&s.length>0)s.forEach((r,m)=>{a[`RetainResources.member.${m+1}`]=r});await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(a).toString()})}async describeStacks(e={}){let t={Action:"DescribeStacks",Version:"2010-05-15"};if(e.stackName)t.StackName=e.stackName;let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{Stacks:this.parseStacksResponse(s)}}async describeStackEvents(e){let t={Action:"DescribeStackEvents",StackName:e,Version:"2010-05-15"},s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{StackEvents:this.parseStackEvents(s)}}async listStackResources(e){let t={Action:"ListStackResources",StackName:e,Version:"2010-05-15"},a=(await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()}))?.ListStackResourcesResult?.StackResourceSummaries?.member,r=[];if(a)r=Array.isArray(a)?a:[a];return{StackResourceSummaries:r}}async waitForStack(e,t){let s={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},a=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],r=s[t],m=360,i=0;while(i<360)try{let c=await this.describeStacks({stackName:e});if(c.Stacks.length===0){if(t==="stack-delete-complete")return;if(i%10===0)console.log(`[waitForStack] Attempt ${i}: Stack not visible yet`);await new Promise((o)=>setTimeout(o,2000)),i++;continue}let n=c.Stacks[0];if(i%10===0)console.log(`[waitForStack] Attempt ${i}: Status = ${n.StackStatus}${n.StackStatusReason?` (${n.StackStatusReason})`:""}`);if(r.includes(n.StackStatus))return;if((t==="stack-create-complete"||t==="stack-update-complete")&&(n.StackStatus==="DELETE_IN_PROGRESS"||n.StackStatus==="DELETE_COMPLETE")){console.log("[waitForStack] Stack is being deleted (creation/update failed)");let o="";try{let S=await this.describeStackEvents(e);console.log("[waitForStack] Stack events (most recent first):");for(let k of S.StackEvents.slice(0,15))if(k.ResourceStatus.includes("FAILED")||k.ResourceStatusReason){if(console.log(` ${k.LogicalResourceId}: ${k.ResourceStatus} - ${k.ResourceStatusReason||"No reason provided"}`),k.ResourceStatus.includes("FAILED")&&k.ResourceStatusReason&&!o)o=k.ResourceStatusReason}}catch{}let l=o||n.StackStatusReason||"Check CloudFormation console for details.";throw Error(`Stack creation/update failed - stack is being deleted. Reason: ${l}`)}if(n.StackStatus==="DELETE_FAILED"&&t==="stack-delete-complete"){let o=Error("Stack deletion failed - may have resources that need to be retained");throw o.code="DELETE_FAILED",o.stackStatus=n.StackStatus,o.statusReason=n.StackStatusReason,o}if(a.includes(n.StackStatus))throw Error(`Stack reached failure status: ${n.StackStatus}`);await new Promise((o)=>setTimeout(o,5000)),i++}catch(c){if(t==="stack-delete-complete"&&c.message?.includes("does not exist"))return;if(t==="stack-create-complete"&&c.message?.includes("does not exist")){if(i%10===0)console.log(`[waitForStack] Attempt ${i}: Stack does not exist (error), retrying...`);await new Promise((n)=>setTimeout(n,2000)),i++;continue}throw console.log(`[waitForStack] Unexpected error: ${c.message}`),c}throw console.log(`[waitForStack] Timeout after ${i} attempts`),Error(`Timeout waiting for stack to reach ${t}`)}async validateTemplate(e){let t={Action:"ValidateTemplate",TemplateBody:e,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()})}async listStacks(e){let t={Action:"ListStacks",Version:"2010-05-15"};if(e)e.forEach((c,n)=>{t[`StackStatusFilter.member.${n+1}`]=c});let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()}),a=s.ListStacksResponse||s,r=a.ListStacksResult||a,m=r.StackSummaries?.member||r.StackSummaries||[];return{StackSummaries:(Array.isArray(m)?m:m?[m]:[]).map((c)=>({StackId:c.StackId||"",StackName:c.StackName||"",TemplateDescription:c.TemplateDescription,CreationTime:c.CreationTime||"",LastUpdatedTime:c.LastUpdatedTime,DeletionTime:c.DeletionTime,StackStatus:c.StackStatus||""}))}}async createChangeSet(e){let t={Action:"CreateChangeSet",StackName:e.stackName,ChangeSetName:e.changeSetName,Version:"2010-05-15"};if(e.templateBody)t.TemplateBody=e.templateBody;else if(e.templateUrl)t.TemplateURL=e.templateUrl;if(e.parameters)e.parameters.forEach((r,m)=>{t[`Parameters.member.${m+1}.ParameterKey`]=r.ParameterKey,t[`Parameters.member.${m+1}.ParameterValue`]=r.ParameterValue});if(e.capabilities)e.capabilities.forEach((r,m)=>{t[`Capabilities.member.${m+1}`]=r});if(e.changeSetType)t.ChangeSetType=e.changeSetType;let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()}),a=_(s,"CreateChangeSet");return{Id:a?.Id,StackId:a?.StackId}}async describeChangeSet(e,t){let s={Action:"DescribeChangeSet",StackName:e,ChangeSetName:t,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(s).toString()})}async executeChangeSet(e,t){let s={Action:"ExecuteChangeSet",StackName:e,ChangeSetName:t,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(s).toString()})}async deleteChangeSet(e,t){let s={Action:"DeleteChangeSet",StackName:e,ChangeSetName:t,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(s).toString()})}async getStackOutputs(e){let t=await this.describeStacks({stackName:e});if(!t.Stacks||t.Stacks.length===0)throw Error(`Stack ${e} not found`);let s=t.Stacks[0],a={};if(s.Outputs)for(let r of s.Outputs)a[r.OutputKey]=r.OutputValue;return a}async getTemplate(e){let t={Action:"GetTemplate",StackName:e,Version:"2010-05-15"},s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{TemplateBody:s?.GetTemplateResult?.TemplateBody||s?.TemplateBody||""}}parseStacksResponse(e){let t=[],s=e?.DescribeStacksResult?.Stacks?.member||e?.Stacks?.member||e?.Stacks||e;if(s&&!Array.isArray(s))s=[s];if(Array.isArray(s)){for(let a of s)if(a.StackId||a.StackName){let r;if(a.Outputs?.member)r=(Array.isArray(a.Outputs.member)?a.Outputs.member:[a.Outputs.member]).map((i)=>({OutputKey:i.OutputKey,OutputValue:i.OutputValue,Description:i.Description,ExportName:i.ExportName}));t.push({StackId:a.StackId,StackName:a.StackName,StackStatus:a.StackStatus,CreationTime:a.CreationTime,LastUpdatedTime:a.LastUpdatedTime,StackStatusReason:a.StackStatusReason,Outputs:r})}}else if(e.StackId)t.push({StackId:e.StackId,StackName:e.StackName,StackStatus:e.StackStatus,CreationTime:e.CreationTime,LastUpdatedTime:e.LastUpdatedTime});return t}parseStackEvents(e){let t=[],s=e?.DescribeStackEventsResult?.StackEvents?.member||e?.StackEvents?.member||e?.StackEvents||[];if(s&&!Array.isArray(s))s=[s];for(let a of s)if(a.LogicalResourceId)t.push({Timestamp:a.Timestamp,ResourceType:a.ResourceType,LogicalResourceId:a.LogicalResourceId,ResourceStatus:a.ResourceStatus,ResourceStatusReason:a.ResourceStatusReason});return t}async waitForStackWithProgress(e,t,s){let a={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},r=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],m=a[t],i=360,c=0,n=new Set;while(c<360)try{if(s)try{let k=[...(await this.describeStackEvents(e)).StackEvents||[]].reverse();for(let d of k){let g=`${d.LogicalResourceId}-${d.ResourceStatus}-${d.Timestamp}`;if(!n.has(g))n.add(g),s({resourceId:d.LogicalResourceId,resourceType:d.ResourceType,status:d.ResourceStatus,reason:d.ResourceStatusReason,timestamp:d.Timestamp})}}catch{}let o=await this.describeStacks({stackName:e});if(o.Stacks.length===0){if(t==="stack-delete-complete")return;await new Promise((S)=>setTimeout(S,2000)),c++;continue}let l=o.Stacks[0];if(m.includes(l.StackStatus))return;if(l.StackStatus==="DELETE_FAILED"&&t==="stack-delete-complete"){let S=Error("Stack deletion failed - may have resources that need to be retained");throw S.code="DELETE_FAILED",S.stackStatus=l.StackStatus,S.statusReason=l.StackStatusReason,S}if(r.includes(l.StackStatus))throw Error(`Stack reached failure status: ${l.StackStatus}`);await new Promise((S)=>setTimeout(S,3000)),c++}catch(o){if(t==="stack-delete-complete"&&o.message?.includes("does not exist"))return;if(t==="stack-create-complete"&&o.message?.includes("does not exist")){await new Promise((l)=>setTimeout(l,2000)),c++;continue}throw o}throw Error(`Timeout waiting for stack to reach ${t}`)}async waitForStackComplete(e,t=120,s=5000){let a=["CREATE_COMPLETE","UPDATE_COMPLETE","DELETE_COMPLETE"],r=["CREATE_FAILED","UPDATE_FAILED","DELETE_FAILED","ROLLBACK_COMPLETE","ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED"];for(let m=0;m<t;m++)try{let i=await this.describeStacks({stackName:e});if(i.Stacks.length===0)return{success:!0,status:"DELETE_COMPLETE"};let c=i.Stacks[0],n=c.StackStatus;if(a.includes(n))return{success:!0,status:n};if(r.includes(n))return{success:!1,status:n,reason:c.StackStatusReason};await new Promise((o)=>setTimeout(o,s))}catch(i){if(i.message?.includes("does not exist"))return{success:!0,status:"DELETE_COMPLETE"};throw i}return{success:!1,status:"TIMEOUT",reason:"Timeout waiting for stack operation"}}}
1
+ import{u}from"./chunk-dmwfnbg0.js";import{_}from"./chunk-cvc9bxd4.js";class v{client;region;constructor(e="us-east-1",t){this.region=e,this.client=new u(void 0,{profile:t})}async createStack(e){let t={Action:"CreateStack",StackName:e.stackName,Version:"2010-05-15"};if(e.templateBody)t.TemplateBody=e.templateBody;else if(e.templateUrl)t.TemplateURL=e.templateUrl;else throw Error("Either templateBody or templateUrl must be provided");if(e.parameters)e.parameters.forEach((a,r)=>{t[`Parameters.member.${r+1}.ParameterKey`]=a.ParameterKey,t[`Parameters.member.${r+1}.ParameterValue`]=a.ParameterValue});if(e.capabilities)e.capabilities.forEach((a,r)=>{t[`Capabilities.member.${r+1}`]=a});if(e.roleArn)t.RoleARN=e.roleArn;if(e.tags)e.tags.forEach((a,r)=>{t[`Tags.member.${r+1}.Key`]=a.Key,t[`Tags.member.${r+1}.Value`]=a.Value});if(e.timeoutInMinutes)t.TimeoutInMinutes=e.timeoutInMinutes;if(e.onFailure)t.OnFailure=e.onFailure;let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{StackId:s.StackId||s.CreateStackResult?.StackId}}async updateStack(e){let t={Action:"UpdateStack",StackName:e.stackName,Version:"2010-05-15"};if(e.templateBody)t.TemplateBody=e.templateBody;else if(e.templateUrl)t.TemplateURL=e.templateUrl;if(e.parameters)e.parameters.forEach((a,r)=>{if(t[`Parameters.member.${r+1}.ParameterKey`]=a.ParameterKey,a.UsePreviousValue)t[`Parameters.member.${r+1}.UsePreviousValue`]="true";else t[`Parameters.member.${r+1}.ParameterValue`]=a.ParameterValue});if(e.capabilities)e.capabilities.forEach((a,r)=>{t[`Capabilities.member.${r+1}`]=a});if(e.roleArn)t.RoleARN=e.roleArn;if(e.tags)e.tags.forEach((a,r)=>{t[`Tags.member.${r+1}.Key`]=a.Key,t[`Tags.member.${r+1}.Value`]=a.Value});let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{StackId:s.StackId||s.UpdateStackResult?.StackId}}async deleteStack(e,t,s){let a={Action:"DeleteStack",StackName:e,Version:"2010-05-15"};if(t)a.RoleARN=t;if(s&&s.length>0)s.forEach((r,m)=>{a[`RetainResources.member.${m+1}`]=r});await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(a).toString()})}async describeStacks(e={}){let t={Action:"DescribeStacks",Version:"2010-05-15"};if(e.stackName)t.StackName=e.stackName;let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{Stacks:this.parseStacksResponse(s)}}async describeStackEvents(e){let t={Action:"DescribeStackEvents",StackName:e,Version:"2010-05-15"},s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{StackEvents:this.parseStackEvents(s)}}async listStackResources(e){let t={Action:"ListStackResources",StackName:e,Version:"2010-05-15"},a=(await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()}))?.ListStackResourcesResult?.StackResourceSummaries?.member,r=[];if(a)r=Array.isArray(a)?a:[a];return{StackResourceSummaries:r}}async waitForStack(e,t){let s={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},a=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],r=s[t],m=360,i=0;while(i<360)try{let c=await this.describeStacks({stackName:e});if(c.Stacks.length===0){if(t==="stack-delete-complete")return;if(i%10===0)console.log(`[waitForStack] Attempt ${i}: Stack not visible yet`);await new Promise((o)=>setTimeout(o,2000)),i++;continue}let n=c.Stacks[0];if(i%10===0)console.log(`[waitForStack] Attempt ${i}: Status = ${n.StackStatus}${n.StackStatusReason?` (${n.StackStatusReason})`:""}`);if(r.includes(n.StackStatus))return;if((t==="stack-create-complete"||t==="stack-update-complete")&&(n.StackStatus==="DELETE_IN_PROGRESS"||n.StackStatus==="DELETE_COMPLETE")){console.log("[waitForStack] Stack is being deleted (creation/update failed)");let o="";try{let S=await this.describeStackEvents(e);console.log("[waitForStack] Stack events (most recent first):");for(let k of S.StackEvents.slice(0,15))if(k.ResourceStatus.includes("FAILED")||k.ResourceStatusReason){if(console.log(` ${k.LogicalResourceId}: ${k.ResourceStatus} - ${k.ResourceStatusReason||"No reason provided"}`),k.ResourceStatus.includes("FAILED")&&k.ResourceStatusReason&&!o)o=k.ResourceStatusReason}}catch{}let l=o||n.StackStatusReason||"Check CloudFormation console for details.";throw Error(`Stack creation/update failed - stack is being deleted. Reason: ${l}`)}if(n.StackStatus==="DELETE_FAILED"&&t==="stack-delete-complete"){let o=Error("Stack deletion failed - may have resources that need to be retained");throw o.code="DELETE_FAILED",o.stackStatus=n.StackStatus,o.statusReason=n.StackStatusReason,o}if(a.includes(n.StackStatus))throw Error(`Stack reached failure status: ${n.StackStatus}`);await new Promise((o)=>setTimeout(o,5000)),i++}catch(c){if(t==="stack-delete-complete"&&c.message?.includes("does not exist"))return;if(t==="stack-create-complete"&&c.message?.includes("does not exist")){if(i%10===0)console.log(`[waitForStack] Attempt ${i}: Stack does not exist (error), retrying...`);await new Promise((n)=>setTimeout(n,2000)),i++;continue}throw console.log(`[waitForStack] Unexpected error: ${c.message}`),c}throw console.log(`[waitForStack] Timeout after ${i} attempts`),Error(`Timeout waiting for stack to reach ${t}`)}async validateTemplate(e){let t={Action:"ValidateTemplate",TemplateBody:e,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()})}async listStacks(e){let t={Action:"ListStacks",Version:"2010-05-15"};if(e)e.forEach((c,n)=>{t[`StackStatusFilter.member.${n+1}`]=c});let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()}),a=s.ListStacksResponse||s,r=a.ListStacksResult||a,m=r.StackSummaries?.member||r.StackSummaries||[];return{StackSummaries:(Array.isArray(m)?m:m?[m]:[]).map((c)=>({StackId:c.StackId||"",StackName:c.StackName||"",TemplateDescription:c.TemplateDescription,CreationTime:c.CreationTime||"",LastUpdatedTime:c.LastUpdatedTime,DeletionTime:c.DeletionTime,StackStatus:c.StackStatus||""}))}}async createChangeSet(e){let t={Action:"CreateChangeSet",StackName:e.stackName,ChangeSetName:e.changeSetName,Version:"2010-05-15"};if(e.templateBody)t.TemplateBody=e.templateBody;else if(e.templateUrl)t.TemplateURL=e.templateUrl;if(e.parameters)e.parameters.forEach((r,m)=>{t[`Parameters.member.${m+1}.ParameterKey`]=r.ParameterKey,t[`Parameters.member.${m+1}.ParameterValue`]=r.ParameterValue});if(e.capabilities)e.capabilities.forEach((r,m)=>{t[`Capabilities.member.${m+1}`]=r});if(e.changeSetType)t.ChangeSetType=e.changeSetType;let s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()}),a=_(s,"CreateChangeSet");return{Id:a?.Id,StackId:a?.StackId}}async describeChangeSet(e,t){let s={Action:"DescribeChangeSet",StackName:e,ChangeSetName:t,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(s).toString()})}async executeChangeSet(e,t){let s={Action:"ExecuteChangeSet",StackName:e,ChangeSetName:t,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(s).toString()})}async deleteChangeSet(e,t){let s={Action:"DeleteChangeSet",StackName:e,ChangeSetName:t,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(s).toString()})}async getStackOutputs(e){let t=await this.describeStacks({stackName:e});if(!t.Stacks||t.Stacks.length===0)throw Error(`Stack ${e} not found`);let s=t.Stacks[0],a={};if(s.Outputs)for(let r of s.Outputs)a[r.OutputKey]=r.OutputValue;return a}async getTemplate(e){let t={Action:"GetTemplate",StackName:e,Version:"2010-05-15"},s=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(t).toString()});return{TemplateBody:s?.GetTemplateResult?.TemplateBody||s?.TemplateBody||""}}parseStacksResponse(e){let t=[],s=e?.DescribeStacksResult?.Stacks?.member||e?.Stacks?.member||e?.Stacks||e;if(s&&!Array.isArray(s))s=[s];if(Array.isArray(s)){for(let a of s)if(a.StackId||a.StackName){let r;if(a.Outputs?.member)r=(Array.isArray(a.Outputs.member)?a.Outputs.member:[a.Outputs.member]).map((i)=>({OutputKey:i.OutputKey,OutputValue:i.OutputValue,Description:i.Description,ExportName:i.ExportName}));t.push({StackId:a.StackId,StackName:a.StackName,StackStatus:a.StackStatus,CreationTime:a.CreationTime,LastUpdatedTime:a.LastUpdatedTime,StackStatusReason:a.StackStatusReason,Outputs:r})}}else if(e.StackId)t.push({StackId:e.StackId,StackName:e.StackName,StackStatus:e.StackStatus,CreationTime:e.CreationTime,LastUpdatedTime:e.LastUpdatedTime});return t}parseStackEvents(e){let t=[],s=e?.DescribeStackEventsResult?.StackEvents?.member||e?.StackEvents?.member||e?.StackEvents||[];if(s&&!Array.isArray(s))s=[s];for(let a of s)if(a.LogicalResourceId)t.push({Timestamp:a.Timestamp,ResourceType:a.ResourceType,LogicalResourceId:a.LogicalResourceId,ResourceStatus:a.ResourceStatus,ResourceStatusReason:a.ResourceStatusReason});return t}async waitForStackWithProgress(e,t,s){let a={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},r=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],m=a[t],i=360,c=0,n=new Set;while(c<360)try{if(s)try{let k=[...(await this.describeStackEvents(e)).StackEvents||[]].reverse();for(let d of k){let g=`${d.LogicalResourceId}-${d.ResourceStatus}-${d.Timestamp}`;if(!n.has(g))n.add(g),s({resourceId:d.LogicalResourceId,resourceType:d.ResourceType,status:d.ResourceStatus,reason:d.ResourceStatusReason,timestamp:d.Timestamp})}}catch{}let o=await this.describeStacks({stackName:e});if(o.Stacks.length===0){if(t==="stack-delete-complete")return;await new Promise((S)=>setTimeout(S,2000)),c++;continue}let l=o.Stacks[0];if(m.includes(l.StackStatus))return;if(l.StackStatus==="DELETE_FAILED"&&t==="stack-delete-complete"){let S=Error("Stack deletion failed - may have resources that need to be retained");throw S.code="DELETE_FAILED",S.stackStatus=l.StackStatus,S.statusReason=l.StackStatusReason,S}if(r.includes(l.StackStatus))throw Error(`Stack reached failure status: ${l.StackStatus}`);await new Promise((S)=>setTimeout(S,3000)),c++}catch(o){if(t==="stack-delete-complete"&&o.message?.includes("does not exist"))return;if(t==="stack-create-complete"&&o.message?.includes("does not exist")){await new Promise((l)=>setTimeout(l,2000)),c++;continue}throw o}throw Error(`Timeout waiting for stack to reach ${t}`)}async waitForStackComplete(e,t=120,s=5000){let a=["CREATE_COMPLETE","UPDATE_COMPLETE","DELETE_COMPLETE"],r=["CREATE_FAILED","UPDATE_FAILED","DELETE_FAILED","ROLLBACK_COMPLETE","ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED"];for(let m=0;m<t;m++)try{let i=await this.describeStacks({stackName:e});if(i.Stacks.length===0)return{success:!0,status:"DELETE_COMPLETE"};let c=i.Stacks[0],n=c.StackStatus;if(a.includes(n))return{success:!0,status:n};if(r.includes(n))return{success:!1,status:n,reason:c.StackStatusReason};await new Promise((o)=>setTimeout(o,s))}catch(i){if(i.message?.includes("does not exist"))return{success:!0,status:"DELETE_COMPLETE"};throw i}return{success:!1,status:"TIMEOUT",reason:"Timeout waiting for stack operation"}}}
2
2
  export{v};
@@ -0,0 +1 @@
1
+ import{Q}from"./chunk-dnmb3sr0.js";import"./chunk-dmwfnbg0.js";export{Q as EC2Client};