alchemy 0.53.0 → 0.55.0

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 (214) hide show
  1. package/bin/alchemy.js +196353 -0
  2. package/bin/alchemy.ts +2 -2
  3. package/bin/commands/init.ts +1190 -0
  4. package/bin/constants.ts +18 -0
  5. package/bin/services/execute-alchemy.ts +7 -2
  6. package/bin/services/package-manager.ts +1 -1
  7. package/bin/types.ts +14 -5
  8. package/lib/aws/ec2/index.d.ts +10 -0
  9. package/lib/aws/ec2/index.d.ts.map +1 -0
  10. package/lib/aws/ec2/index.js +10 -0
  11. package/lib/aws/ec2/index.js.map +1 -0
  12. package/lib/aws/ec2/internet-gateway-attachment.d.ts +150 -0
  13. package/lib/aws/ec2/internet-gateway-attachment.d.ts.map +1 -0
  14. package/lib/aws/ec2/internet-gateway-attachment.js +248 -0
  15. package/lib/aws/ec2/internet-gateway-attachment.js.map +1 -0
  16. package/lib/aws/ec2/internet-gateway.d.ts +132 -0
  17. package/lib/aws/ec2/internet-gateway.d.ts.map +1 -0
  18. package/lib/aws/ec2/internet-gateway.js +311 -0
  19. package/lib/aws/ec2/internet-gateway.js.map +1 -0
  20. package/lib/aws/ec2/nat-gateway.d.ts +145 -0
  21. package/lib/aws/ec2/nat-gateway.d.ts.map +1 -0
  22. package/lib/aws/ec2/nat-gateway.js +618 -0
  23. package/lib/aws/ec2/nat-gateway.js.map +1 -0
  24. package/lib/aws/ec2/route-table-association.d.ts +134 -0
  25. package/lib/aws/ec2/route-table-association.d.ts.map +1 -0
  26. package/lib/aws/ec2/route-table-association.js +364 -0
  27. package/lib/aws/ec2/route-table-association.js.map +1 -0
  28. package/lib/aws/ec2/route-table.d.ts +94 -0
  29. package/lib/aws/ec2/route-table.d.ts.map +1 -0
  30. package/lib/aws/ec2/route-table.js +253 -0
  31. package/lib/aws/ec2/route-table.js.map +1 -0
  32. package/lib/aws/ec2/route.d.ts +130 -0
  33. package/lib/aws/ec2/route.d.ts.map +1 -0
  34. package/lib/aws/ec2/route.js +253 -0
  35. package/lib/aws/ec2/route.js.map +1 -0
  36. package/lib/aws/ec2/security-group-rule.d.ts +84 -0
  37. package/lib/aws/ec2/security-group-rule.d.ts.map +1 -0
  38. package/lib/aws/ec2/security-group-rule.js +123 -0
  39. package/lib/aws/ec2/security-group-rule.js.map +1 -0
  40. package/lib/aws/ec2/security-group.d.ts +84 -0
  41. package/lib/aws/ec2/security-group.d.ts.map +1 -0
  42. package/lib/aws/ec2/security-group.js +207 -0
  43. package/lib/aws/ec2/security-group.js.map +1 -0
  44. package/lib/aws/ec2/subnet.d.ts +110 -0
  45. package/lib/aws/ec2/subnet.d.ts.map +1 -0
  46. package/lib/aws/ec2/subnet.js +336 -0
  47. package/lib/aws/ec2/subnet.js.map +1 -0
  48. package/lib/aws/ec2/utils.d.ts +15 -0
  49. package/lib/aws/ec2/utils.d.ts.map +1 -0
  50. package/lib/aws/ec2/utils.js +79 -0
  51. package/lib/aws/ec2/utils.js.map +1 -0
  52. package/lib/aws/ec2/vpc.d.ts +160 -0
  53. package/lib/aws/ec2/vpc.d.ts.map +1 -0
  54. package/lib/aws/ec2/vpc.js +453 -0
  55. package/lib/aws/ec2/vpc.js.map +1 -0
  56. package/lib/aws/index.d.ts +7 -0
  57. package/lib/aws/index.d.ts.map +1 -1
  58. package/lib/aws/index.js +8 -0
  59. package/lib/aws/index.js.map +1 -1
  60. package/lib/aws/utils.d.ts +25 -0
  61. package/lib/aws/utils.d.ts.map +1 -0
  62. package/lib/aws/utils.js +89 -0
  63. package/lib/aws/utils.js.map +1 -0
  64. package/lib/build-date.d.ts +6 -0
  65. package/lib/build-date.d.ts.map +1 -0
  66. package/lib/build-date.js +8 -0
  67. package/lib/build-date.js.map +1 -0
  68. package/lib/cloudflare/astro.d.ts.map +1 -1
  69. package/lib/cloudflare/astro.js +4 -3
  70. package/lib/cloudflare/astro.js.map +1 -1
  71. package/lib/cloudflare/bundle/externals.d.ts +3 -0
  72. package/lib/cloudflare/bundle/externals.d.ts.map +1 -0
  73. package/lib/cloudflare/bundle/externals.js +35 -0
  74. package/lib/cloudflare/bundle/externals.js.map +1 -0
  75. package/lib/cloudflare/bundle/internal-worker-bundle.d.ts +8 -1
  76. package/lib/cloudflare/bundle/internal-worker-bundle.d.ts.map +1 -1
  77. package/lib/cloudflare/bundle/internal-worker-bundle.js +11 -4
  78. package/lib/cloudflare/bundle/internal-worker-bundle.js.map +1 -1
  79. package/lib/cloudflare/bundle/plugin-hot-reload.d.ts +4 -1
  80. package/lib/cloudflare/bundle/plugin-hot-reload.d.ts.map +1 -1
  81. package/lib/cloudflare/bundle/plugin-hot-reload.js +27 -11
  82. package/lib/cloudflare/bundle/plugin-hot-reload.js.map +1 -1
  83. package/lib/cloudflare/bundle/plugin-hybrid-node-compat.js +5 -1
  84. package/lib/cloudflare/bundle/plugin-hybrid-node-compat.js.map +1 -1
  85. package/lib/cloudflare/bundle/plugin-wasm.d.ts +6 -2
  86. package/lib/cloudflare/bundle/plugin-wasm.d.ts.map +1 -1
  87. package/lib/cloudflare/bundle/plugin-wasm.js +21 -47
  88. package/lib/cloudflare/bundle/plugin-wasm.js.map +1 -1
  89. package/lib/cloudflare/bundle/validate-node-compat.d.ts +2 -1
  90. package/lib/cloudflare/bundle/validate-node-compat.d.ts.map +1 -1
  91. package/lib/cloudflare/bundle/validate-node-compat.js +5 -4
  92. package/lib/cloudflare/bundle/validate-node-compat.js.map +1 -1
  93. package/lib/cloudflare/compatibility-date.gen.d.ts +1 -1
  94. package/lib/cloudflare/compatibility-date.gen.js +1 -1
  95. package/lib/cloudflare/d1-database.js +1 -1
  96. package/lib/cloudflare/d1-database.js.map +1 -1
  97. package/lib/cloudflare/d1-migrations.d.ts.map +1 -1
  98. package/lib/cloudflare/d1-migrations.js +8 -10
  99. package/lib/cloudflare/d1-migrations.js.map +1 -1
  100. package/lib/cloudflare/miniflare/miniflare-worker-options.d.ts +3 -3
  101. package/lib/cloudflare/miniflare/miniflare-worker-options.d.ts.map +1 -1
  102. package/lib/cloudflare/miniflare/miniflare-worker-options.js +23 -6
  103. package/lib/cloudflare/miniflare/miniflare-worker-options.js.map +1 -1
  104. package/lib/cloudflare/miniflare/miniflare.d.ts.map +1 -1
  105. package/lib/cloudflare/miniflare/miniflare.js +2 -4
  106. package/lib/cloudflare/miniflare/miniflare.js.map +1 -1
  107. package/lib/cloudflare/miniflare/remote-binding-proxy.d.ts.map +1 -1
  108. package/lib/cloudflare/miniflare/remote-binding-proxy.js +4 -6
  109. package/lib/cloudflare/miniflare/remote-binding-proxy.js.map +1 -1
  110. package/lib/cloudflare/react-router.d.ts +4 -0
  111. package/lib/cloudflare/react-router.d.ts.map +1 -1
  112. package/lib/cloudflare/react-router.js +8 -5
  113. package/lib/cloudflare/react-router.js.map +1 -1
  114. package/lib/cloudflare/worker-bundle.d.ts +80 -0
  115. package/lib/cloudflare/worker-bundle.d.ts.map +1 -0
  116. package/lib/cloudflare/worker-bundle.js +266 -0
  117. package/lib/cloudflare/worker-bundle.js.map +1 -0
  118. package/lib/cloudflare/worker.d.ts +1 -1
  119. package/lib/cloudflare/worker.d.ts.map +1 -1
  120. package/lib/cloudflare/worker.js +81 -195
  121. package/lib/cloudflare/worker.js.map +1 -1
  122. package/lib/esbuild/bundle.d.ts +1 -0
  123. package/lib/esbuild/bundle.d.ts.map +1 -1
  124. package/lib/state/cloudflare-state-store.js +1 -5
  125. package/lib/state/cloudflare-state-store.js.map +1 -1
  126. package/lib/state/dofs-state-store/store.d.ts.map +1 -1
  127. package/lib/state/dofs-state-store/store.js +4 -4
  128. package/lib/state/dofs-state-store/store.js.map +1 -1
  129. package/lib/util/params.d.ts +5 -0
  130. package/lib/util/params.d.ts.map +1 -0
  131. package/lib/util/params.js +30 -0
  132. package/lib/util/params.js.map +1 -0
  133. package/lib/util/timeout.d.ts +31 -0
  134. package/lib/util/timeout.d.ts.map +1 -0
  135. package/lib/util/timeout.js +109 -0
  136. package/lib/util/timeout.js.map +1 -0
  137. package/lib/util/xml.d.ts +5 -0
  138. package/lib/util/xml.d.ts.map +1 -0
  139. package/lib/util/xml.js +8 -0
  140. package/lib/util/xml.js.map +1 -0
  141. package/package.json +12 -5
  142. package/src/aws/ec2/index.ts +9 -0
  143. package/src/aws/ec2/internet-gateway-attachment.ts +468 -0
  144. package/src/aws/ec2/internet-gateway.ts +557 -0
  145. package/src/aws/ec2/nat-gateway.ts +1123 -0
  146. package/src/aws/ec2/route-table-association.ts +747 -0
  147. package/src/aws/ec2/route-table.ts +452 -0
  148. package/src/aws/ec2/route.ts +447 -0
  149. package/src/aws/ec2/security-group-rule.ts +229 -0
  150. package/src/aws/ec2/security-group.ts +418 -0
  151. package/src/aws/ec2/subnet.ts +625 -0
  152. package/src/aws/ec2/utils.ts +102 -0
  153. package/src/aws/ec2/vpc.ts +969 -0
  154. package/src/aws/index.ts +9 -0
  155. package/src/aws/utils.ts +137 -0
  156. package/src/build-date.ts +8 -0
  157. package/src/cloudflare/astro.ts +4 -3
  158. package/src/cloudflare/bundle/externals.ts +36 -0
  159. package/src/cloudflare/bundle/internal-worker-bundle.ts +12 -3
  160. package/src/cloudflare/bundle/plugin-hot-reload.ts +32 -12
  161. package/src/cloudflare/bundle/plugin-hybrid-node-compat.ts +6 -1
  162. package/src/cloudflare/bundle/plugin-wasm.ts +26 -54
  163. package/src/cloudflare/bundle/validate-node-compat.ts +6 -5
  164. package/src/cloudflare/compatibility-date.gen.ts +1 -1
  165. package/src/cloudflare/d1-database.ts +1 -1
  166. package/src/cloudflare/d1-migrations.ts +19 -18
  167. package/src/cloudflare/miniflare/miniflare-worker-options.ts +27 -13
  168. package/src/cloudflare/miniflare/miniflare.ts +2 -4
  169. package/src/cloudflare/miniflare/remote-binding-proxy.ts +5 -7
  170. package/src/cloudflare/react-router.ts +14 -6
  171. package/src/cloudflare/worker-bundle.ts +364 -0
  172. package/src/cloudflare/worker.ts +104 -241
  173. package/src/state/cloudflare-state-store.ts +1 -5
  174. package/src/state/dofs-state-store/store.ts +4 -4
  175. package/src/util/params.ts +33 -0
  176. package/src/util/timeout.ts +178 -0
  177. package/src/util/xml.ts +7 -0
  178. package/templates/nuxt/package.json +1 -1
  179. package/templates/nuxt/types/env.d.ts +11 -0
  180. package/templates/react-router/workers/app.ts +2 -2
  181. package/templates/rwsdk/.cursor/rules/alchemy_cloudflare.mdc +385 -0
  182. package/templates/rwsdk/wrangler.jsonc +10 -7
  183. package/templates/typescript/tsconfig.json +1 -2
  184. package/bin/alchemy.mjs +0 -51766
  185. package/lib/cloudflare/bundle/esbuild.d.ts +0 -16
  186. package/lib/cloudflare/bundle/esbuild.d.ts.map +0 -1
  187. package/lib/cloudflare/bundle/esbuild.js +0 -159
  188. package/lib/cloudflare/bundle/esbuild.js.map +0 -1
  189. package/lib/cloudflare/bundle/fs.d.ts +0 -18
  190. package/lib/cloudflare/bundle/fs.d.ts.map +0 -1
  191. package/lib/cloudflare/bundle/fs.js +0 -78
  192. package/lib/cloudflare/bundle/fs.js.map +0 -1
  193. package/lib/cloudflare/bundle/index.d.ts +0 -3
  194. package/lib/cloudflare/bundle/index.d.ts.map +0 -1
  195. package/lib/cloudflare/bundle/index.js +0 -2
  196. package/lib/cloudflare/bundle/index.js.map +0 -1
  197. package/lib/cloudflare/bundle/inline.d.ts +0 -12
  198. package/lib/cloudflare/bundle/inline.d.ts.map +0 -1
  199. package/lib/cloudflare/bundle/inline.js +0 -32
  200. package/lib/cloudflare/bundle/inline.js.map +0 -1
  201. package/lib/cloudflare/bundle/normalize.d.ts +0 -21
  202. package/lib/cloudflare/bundle/normalize.d.ts.map +0 -1
  203. package/lib/cloudflare/bundle/normalize.js +0 -49
  204. package/lib/cloudflare/bundle/normalize.js.map +0 -1
  205. package/lib/cloudflare/bundle/shared.d.ts +0 -30
  206. package/lib/cloudflare/bundle/shared.d.ts.map +0 -1
  207. package/lib/cloudflare/bundle/shared.js +0 -34
  208. package/lib/cloudflare/bundle/shared.js.map +0 -1
  209. package/src/cloudflare/bundle/esbuild.ts +0 -194
  210. package/src/cloudflare/bundle/fs.ts +0 -103
  211. package/src/cloudflare/bundle/index.ts +0 -6
  212. package/src/cloudflare/bundle/inline.ts +0 -42
  213. package/src/cloudflare/bundle/normalize.ts +0 -76
  214. package/src/cloudflare/bundle/shared.ts +0 -73
@@ -0,0 +1,452 @@
1
+ import type { AwsClient } from "aws4fetch";
2
+ import { XMLParser } from "fast-xml-parser";
3
+ import type { Context } from "../../context.ts";
4
+ import { Resource } from "../../resource.ts";
5
+ import { ignore } from "../../util/ignore.ts";
6
+ import { logger } from "../../util/logger.ts";
7
+ import {
8
+ mergeTimeoutConfig,
9
+ type TimeoutConfig,
10
+ waitForResourceState,
11
+ } from "../../util/timeout.ts";
12
+ import { callEC2Api, createEC2Client } from "./utils.ts";
13
+ import type { Vpc } from "./vpc.ts";
14
+
15
+ /**
16
+ * Properties for creating or updating a Route Table
17
+ */
18
+ export interface RouteTableProps {
19
+ /**
20
+ * The VPC to create the route table in
21
+ */
22
+ vpc: Vpc | string;
23
+
24
+ /**
25
+ * Tags to apply to the route table
26
+ */
27
+ tags?: Record<string, string>;
28
+
29
+ /**
30
+ * Timeout configuration for Route Table operations
31
+ * @default Route Table-specific sensible defaults (30 attempts, 1000ms delay)
32
+ */
33
+ timeout?: Partial<TimeoutConfig>;
34
+ }
35
+
36
+ /**
37
+ * Output returned after Route Table creation/update
38
+ */
39
+ export interface RouteTable
40
+ extends Resource<"aws::RouteTable">,
41
+ RouteTableProps {
42
+ /**
43
+ * The ID of the route table
44
+ */
45
+ routeTableId: string;
46
+
47
+ /**
48
+ * The ID of the VPC the route table belongs to
49
+ */
50
+ vpcId: string;
51
+ }
52
+
53
+ /**
54
+ * AWS Route Table Resource
55
+ *
56
+ * Creates and manages route tables that control the routing of network traffic
57
+ * within a VPC. Route tables contain rules (routes) that determine where network
58
+ * traffic is directed. Subnet associations are managed separately using the
59
+ * RouteTableAssociation resource.
60
+ *
61
+ * @example
62
+ * // Create a basic route table
63
+ * const routeTable = await RouteTable("main-route-table", {
64
+ * vpc: myVpc,
65
+ * tags: {
66
+ * Name: "main-route-table",
67
+ * Environment: "production"
68
+ * }
69
+ * });
70
+ *
71
+ * @example
72
+ * // Create a public route table for internet access
73
+ * const publicRouteTable = await RouteTable("public-routes", {
74
+ * vpc: myVpc,
75
+ * tags: {
76
+ * Name: "public-route-table",
77
+ * Type: "public",
78
+ * Purpose: "internet-access"
79
+ * }
80
+ * });
81
+ *
82
+ * @example
83
+ * // Create a private route table for internal traffic
84
+ * const privateRouteTable = await RouteTable("private-routes", {
85
+ * vpc: myVpc,
86
+ * tags: {
87
+ * Name: "private-route-table",
88
+ * Type: "private",
89
+ * Purpose: "internal-only"
90
+ * }
91
+ * });
92
+ *
93
+ * @example
94
+ * // Create a route table with custom timeout configuration
95
+ * const customRouteTable = await RouteTable("custom-routes", {
96
+ * vpc: myVpc,
97
+ * timeout: {
98
+ * maxAttempts: 45,
99
+ * delayMs: 1500
100
+ * },
101
+ * tags: {
102
+ * Name: "custom-timeout-route-table"
103
+ * }
104
+ * });
105
+ */
106
+ export const RouteTable = Resource(
107
+ "aws::RouteTable",
108
+ async function (
109
+ this: Context<RouteTable>,
110
+ _id: string,
111
+ props: RouteTableProps,
112
+ ): Promise<RouteTable> {
113
+ const client = await createEC2Client();
114
+ const timeoutConfig = mergeTimeoutConfig(
115
+ ROUTE_TABLE_TIMEOUT,
116
+ props.timeout,
117
+ );
118
+ const vpcId = typeof props.vpc === "string" ? props.vpc : props.vpc.vpcId;
119
+
120
+ if (this.phase === "delete") {
121
+ if (this.output?.routeTableId) {
122
+ logger.log(`🗑️ Deleting Route Table: ${this.output.routeTableId}`);
123
+
124
+ // Delete the Route Table
125
+ await ignore("InvalidRouteTableID.NotFound", async () => {
126
+ await callEC2Api(
127
+ client,
128
+ "DeleteRouteTable",
129
+ parseRouteTableXmlResponse,
130
+ {
131
+ RouteTableId: this.output.routeTableId,
132
+ },
133
+ );
134
+ });
135
+
136
+ // Wait for Route Table to be fully deleted
137
+ await waitForRouteTableDeleted(
138
+ client,
139
+ this.output.routeTableId,
140
+ timeoutConfig,
141
+ );
142
+
143
+ logger.log(
144
+ ` ✅ Route Table ${this.output.routeTableId} deletion completed`,
145
+ );
146
+ }
147
+ return this.destroy();
148
+ }
149
+
150
+ let routeTable: AwsRouteTable;
151
+
152
+ if (this.phase === "update" && this.output?.routeTableId) {
153
+ logger.log(`🔄 Updating Route Table: ${this.output.routeTableId}`);
154
+
155
+ // Get existing route table
156
+ const response = await callEC2Api<DescribeRouteTablesResponse>(
157
+ client,
158
+ "DescribeRouteTables",
159
+ parseRouteTableXmlResponse,
160
+ {
161
+ "RouteTableId.1": this.output.routeTableId,
162
+ },
163
+ );
164
+
165
+ if (!response.RouteTables?.[0]) {
166
+ throw new Error(`Route Table ${this.output.routeTableId} not found`);
167
+ }
168
+
169
+ routeTable = response.RouteTables[0];
170
+ logger.log(` ✅ Route Table ${this.output.routeTableId} updated`);
171
+ } else {
172
+ logger.log(`🚀 Creating Route Table in VPC ${vpcId}`);
173
+
174
+ // Create new route table
175
+ const createRouteTableParams: CreateRouteTableParams = {
176
+ VpcId: vpcId,
177
+ };
178
+
179
+ // Add tags if specified
180
+ if (props.tags) {
181
+ createRouteTableParams.TagSpecifications = [
182
+ {
183
+ ResourceType: "route-table",
184
+ Tags: Object.entries(props.tags).map(([key, value]) => ({
185
+ Key: key,
186
+ Value: value,
187
+ })),
188
+ },
189
+ ];
190
+ }
191
+
192
+ const createParams = convertCreateRouteTableParamsToAwsFormat(
193
+ createRouteTableParams,
194
+ );
195
+
196
+ const response = await callEC2Api<CreateRouteTableResponse>(
197
+ client,
198
+ "CreateRouteTable",
199
+ parseRouteTableXmlResponse,
200
+ createParams,
201
+ );
202
+
203
+ if (!response.RouteTable) {
204
+ throw new Error("Failed to create route table");
205
+ }
206
+
207
+ routeTable = response.RouteTable;
208
+ logger.log(` ✅ Route Table ${routeTable.RouteTableId} created`);
209
+ }
210
+
211
+ return this({
212
+ routeTableId: routeTable.RouteTableId!,
213
+ vpcId: routeTable.VpcId!,
214
+ ...props,
215
+ vpc: vpcId,
216
+ });
217
+ },
218
+ );
219
+
220
+ /**
221
+ * Route Table timeout constants
222
+ */
223
+ export const ROUTE_TABLE_TIMEOUT: TimeoutConfig = {
224
+ maxAttempts: 30,
225
+ delayMs: 1000, // 1 second - Route Tables are fast resources
226
+ };
227
+
228
+ /**
229
+ * Comprehensive AWS Route Table API Parameter Types
230
+ */
231
+
232
+ // Common structures
233
+ interface TagSpecification {
234
+ ResourceType: string;
235
+ Tags: Array<{
236
+ Key: string;
237
+ Value: string;
238
+ }>;
239
+ }
240
+
241
+ // Route Table API Request Parameters
242
+ interface CreateRouteTableParams {
243
+ VpcId: string;
244
+ TagSpecifications?: TagSpecification[];
245
+ DryRun?: boolean;
246
+ }
247
+
248
+ /**
249
+ * Helper functions to convert typed parameters to AWS API format
250
+ */
251
+ function convertCreateRouteTableParamsToAwsFormat(
252
+ params: CreateRouteTableParams,
253
+ ): Record<string, string> {
254
+ const awsParams: Record<string, string> = {
255
+ VpcId: params.VpcId,
256
+ };
257
+
258
+ if (params.DryRun !== undefined) {
259
+ awsParams.DryRun = params.DryRun.toString();
260
+ }
261
+
262
+ // Handle TagSpecifications
263
+ if (params.TagSpecifications) {
264
+ params.TagSpecifications.forEach((tagSpec, specIndex) => {
265
+ const specNum = specIndex + 1;
266
+ awsParams[`TagSpecification.${specNum}.ResourceType`] =
267
+ tagSpec.ResourceType;
268
+
269
+ tagSpec.Tags.forEach((tag, tagIndex) => {
270
+ const tagNum = tagIndex + 1;
271
+ awsParams[`TagSpecification.${specNum}.Tag.${tagNum}.Key`] = tag.Key;
272
+ awsParams[`TagSpecification.${specNum}.Tag.${tagNum}.Value`] =
273
+ tag.Value;
274
+ });
275
+ });
276
+ }
277
+
278
+ return awsParams;
279
+ }
280
+
281
+ /**
282
+ * AWS Route Table API response types
283
+ */
284
+ interface AwsRouteTable {
285
+ RouteTableId: string;
286
+ VpcId: string;
287
+ Routes?: Array<{
288
+ DestinationCidrBlock?: string;
289
+ GatewayId?: string;
290
+ InstanceId?: string;
291
+ NatGatewayId?: string;
292
+ State: string;
293
+ Origin: string;
294
+ }>;
295
+ }
296
+
297
+ /**
298
+ * Raw XML parsing interfaces for type safety
299
+ */
300
+ interface RawRouteTableXmlItem {
301
+ routeTableId: string;
302
+ vpcId: string;
303
+ routeSet?: {
304
+ item?: Array<RawRouteXmlItem> | RawRouteXmlItem;
305
+ };
306
+ }
307
+
308
+ interface RawRouteXmlItem {
309
+ destinationCidrBlock?: string;
310
+ gatewayId?: string;
311
+ instanceId?: string;
312
+ natGatewayId?: string;
313
+ state: string;
314
+ origin: string;
315
+ }
316
+
317
+ interface CreateRouteTableResponse {
318
+ RouteTable: AwsRouteTable;
319
+ }
320
+
321
+ interface DescribeRouteTablesResponse {
322
+ RouteTables: AwsRouteTable[];
323
+ }
324
+
325
+ /**
326
+ * Parse XML responses specifically for Route Table operations
327
+ */
328
+ function parseRouteTableXmlResponse<
329
+ T extends
330
+ | CreateRouteTableResponse
331
+ | DescribeRouteTablesResponse
332
+ | { success: boolean },
333
+ >(xmlText: string): T {
334
+ const parser = new XMLParser({
335
+ ignoreAttributes: true,
336
+ parseAttributeValue: true,
337
+ parseTagValue: true,
338
+ trimValues: true,
339
+ });
340
+
341
+ const parsed = parser.parse(xmlText);
342
+ const result: Record<string, unknown> = {};
343
+
344
+ // Parse CreateRouteTableResponse
345
+ if (parsed.CreateRouteTableResponse) {
346
+ const routeTable = parsed.CreateRouteTableResponse
347
+ .routeTable as RawRouteTableXmlItem;
348
+ if (routeTable) {
349
+ result.RouteTable = {
350
+ RouteTableId: routeTable.routeTableId,
351
+ VpcId: routeTable.vpcId,
352
+ Routes: routeTable.routeSet?.item
353
+ ? (Array.isArray(routeTable.routeSet.item)
354
+ ? routeTable.routeSet.item
355
+ : [routeTable.routeSet.item]
356
+ ).map((route: RawRouteXmlItem) => ({
357
+ DestinationCidrBlock: route.destinationCidrBlock,
358
+ GatewayId: route.gatewayId,
359
+ InstanceId: route.instanceId,
360
+ NatGatewayId: route.natGatewayId,
361
+ State: route.state,
362
+ Origin: route.origin,
363
+ }))
364
+ : [],
365
+ };
366
+ }
367
+ }
368
+
369
+ // Parse DescribeRouteTablesResponse
370
+ if (parsed.DescribeRouteTablesResponse) {
371
+ const routeTableSet = parsed.DescribeRouteTablesResponse.routeTableSet;
372
+ if (routeTableSet?.item) {
373
+ const routeTables = Array.isArray(routeTableSet.item)
374
+ ? routeTableSet.item
375
+ : [routeTableSet.item];
376
+ result.RouteTables = routeTables.map(
377
+ (routeTable: RawRouteTableXmlItem) => ({
378
+ RouteTableId: routeTable.routeTableId,
379
+ VpcId: routeTable.vpcId,
380
+ Routes: routeTable.routeSet?.item
381
+ ? (Array.isArray(routeTable.routeSet.item)
382
+ ? routeTable.routeSet.item
383
+ : [routeTable.routeSet.item]
384
+ ).map((route: RawRouteXmlItem) => ({
385
+ DestinationCidrBlock: route.destinationCidrBlock,
386
+ GatewayId: route.gatewayId,
387
+ InstanceId: route.instanceId,
388
+ NatGatewayId: route.natGatewayId,
389
+ State: route.state,
390
+ Origin: route.origin,
391
+ }))
392
+ : [],
393
+ }),
394
+ );
395
+ } else {
396
+ result.RouteTables = [];
397
+ }
398
+ }
399
+
400
+ // Handle success responses
401
+ if (parsed.DeleteRouteTableResponse) {
402
+ result.success = true;
403
+ }
404
+
405
+ return result as T;
406
+ }
407
+
408
+ /**
409
+ * Wait for Route Table to be deleted
410
+ */
411
+ async function waitForRouteTableDeleted(
412
+ client: AwsClient,
413
+ routeTableId: string,
414
+ timeoutConfig: TimeoutConfig,
415
+ ): Promise<void> {
416
+ const checkFunction = async () => {
417
+ try {
418
+ const response = await callEC2Api<DescribeRouteTablesResponse>(
419
+ client,
420
+ "DescribeRouteTables",
421
+ parseRouteTableXmlResponse,
422
+ {
423
+ "RouteTableId.1": routeTableId,
424
+ },
425
+ );
426
+ return response.RouteTables?.[0];
427
+ } catch (error: any) {
428
+ // If Route Table is not found, it's been deleted - return undefined
429
+ if (
430
+ error.code === "InvalidRouteTableID.NotFound" ||
431
+ error.code === "InvalidRouteTable.NotFound"
432
+ ) {
433
+ return undefined;
434
+ }
435
+ throw error;
436
+ }
437
+ };
438
+
439
+ const isReady = (rt: AwsRouteTable | undefined) => {
440
+ // Route Table is deleted if it doesn't exist
441
+ return !rt;
442
+ };
443
+
444
+ await waitForResourceState(
445
+ checkFunction,
446
+ isReady,
447
+ timeoutConfig,
448
+ routeTableId,
449
+ "Route Table",
450
+ "be deleted",
451
+ );
452
+ }