cdk-local-lambda 0.0.2

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 (53) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +94 -0
  3. package/lib/aspect/docker-function-hook.d.ts +18 -0
  4. package/lib/aspect/docker-function-hook.js +31 -0
  5. package/lib/aspect/live-lambda-aspect.d.ts +85 -0
  6. package/lib/aspect/live-lambda-aspect.js +277 -0
  7. package/lib/aspect/live-lambda-bootstrap.d.ts +17 -0
  8. package/lib/aspect/live-lambda-bootstrap.js +260 -0
  9. package/lib/aspect/nodejs-function-hook.d.ts +20 -0
  10. package/lib/aspect/nodejs-function-hook.js +27 -0
  11. package/lib/bootstrap-stack/bootstrap-stack.d.ts +60 -0
  12. package/lib/bootstrap-stack/bootstrap-stack.js +338 -0
  13. package/lib/cli/appsync/client.d.ts +30 -0
  14. package/lib/cli/appsync/client.js +227 -0
  15. package/lib/cli/cdk-app.d.ts +7 -0
  16. package/lib/cli/cdk-app.js +25 -0
  17. package/lib/cli/commands/bootstrap.d.ts +9 -0
  18. package/lib/cli/commands/bootstrap.js +50 -0
  19. package/lib/cli/commands/local.d.ts +40 -0
  20. package/lib/cli/commands/local.js +1172 -0
  21. package/lib/cli/daemon.d.ts +22 -0
  22. package/lib/cli/daemon.js +18 -0
  23. package/lib/cli/docker/container.d.ts +116 -0
  24. package/lib/cli/docker/container.js +414 -0
  25. package/lib/cli/docker/types.d.ts +71 -0
  26. package/lib/cli/docker/types.js +5 -0
  27. package/lib/cli/docker/watcher.d.ts +44 -0
  28. package/lib/cli/docker/watcher.js +115 -0
  29. package/lib/cli/index.d.ts +9 -0
  30. package/lib/cli/index.js +26 -0
  31. package/lib/cli/runtime-api/server.d.ts +102 -0
  32. package/lib/cli/runtime-api/server.js +396 -0
  33. package/lib/cli/runtime-api/types.d.ts +149 -0
  34. package/lib/cli/runtime-api/types.js +10 -0
  35. package/lib/cli/runtime-wrapper/nodejs-runtime.d.ts +16 -0
  36. package/lib/cli/runtime-wrapper/nodejs-runtime.js +248 -0
  37. package/lib/cli/watcher/file-watcher.d.ts +32 -0
  38. package/lib/cli/watcher/file-watcher.js +57 -0
  39. package/lib/functions/bridge/appsync-client.d.ts +73 -0
  40. package/lib/functions/bridge/appsync-client.js +345 -0
  41. package/lib/functions/bridge/handler.d.ts +17 -0
  42. package/lib/functions/bridge/handler.js +79 -0
  43. package/lib/functions/bridge/ssm-config.d.ts +19 -0
  44. package/lib/functions/bridge/ssm-config.js +45 -0
  45. package/lib/functions/bridge-builder/handler.d.ts +12 -0
  46. package/lib/functions/bridge-builder/handler.js +181 -0
  47. package/lib/functions/bridge-docker/runtime.d.ts +9 -0
  48. package/lib/functions/bridge-docker/runtime.js +127 -0
  49. package/lib/index.d.ts +24 -0
  50. package/lib/index.js +28 -0
  51. package/lib/shared/types.d.ts +102 -0
  52. package/lib/shared/types.js +125 -0
  53. package/package.json +111 -0
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Effect-based AppSync Events client for the daemon.
3
+ *
4
+ * Wraps the existing AppSync client with Effect primitives for better
5
+ * error handling and resource management.
6
+ */
7
+ import { Sha256 } from "@aws-crypto/sha256-js";
8
+ import { defaultProvider } from "@aws-sdk/credential-provider-node";
9
+ import { HttpRequest } from "@aws-sdk/protocol-http";
10
+ import { SignatureV4 } from "@aws-sdk/signature-v4";
11
+ import { Effect, Stream } from "effect";
12
+ import WebSocket from "ws";
13
+ /**
14
+ * Create an Effect-based AppSync Events client.
15
+ */
16
+ export const makeAppSyncClient = (config) => {
17
+ // Extract region from endpoint URL
18
+ const match = config.httpEndpoint.match(/\.([a-z0-9-]+)\.amazonaws\.com/);
19
+ const region = config.region ?? match?.[1] ?? process.env.AWS_REGION ?? "us-east-1";
20
+ /**
21
+ * Sign a request with AWS SigV4.
22
+ */
23
+ const signRequest = (request) => Effect.tryPromise({
24
+ try: async () => {
25
+ const signer = new SignatureV4({
26
+ credentials: defaultProvider(),
27
+ region,
28
+ service: "appsync",
29
+ sha256: Sha256,
30
+ });
31
+ return await signer.sign(request);
32
+ },
33
+ catch: (error) => new Error(`Failed to sign request: ${String(error)}`),
34
+ });
35
+ /**
36
+ * Create authorization headers for subscribe operation.
37
+ */
38
+ const createSubscribeAuthorization = (channel) => Effect.gen(function* () {
39
+ const httpUrl = new URL(config.httpEndpoint);
40
+ const payload = JSON.stringify({ channel });
41
+ const request = new HttpRequest({
42
+ method: "POST",
43
+ protocol: "https:",
44
+ hostname: httpUrl.hostname,
45
+ path: "/event",
46
+ headers: {
47
+ accept: "application/json, text/javascript",
48
+ "content-encoding": "amz-1.0",
49
+ "content-type": "application/json; charset=UTF-8",
50
+ host: httpUrl.hostname,
51
+ },
52
+ body: payload,
53
+ });
54
+ const signedRequest = yield* signRequest(request);
55
+ const auth = {
56
+ accept: "application/json, text/javascript",
57
+ "content-encoding": "amz-1.0",
58
+ "content-type": "application/json; charset=UTF-8",
59
+ host: httpUrl.hostname,
60
+ "x-amz-date": signedRequest.headers["x-amz-date"],
61
+ "x-amz-content-sha256": signedRequest.headers["x-amz-content-sha256"],
62
+ Authorization: signedRequest.headers["authorization"],
63
+ };
64
+ if (signedRequest.headers["x-amz-security-token"]) {
65
+ auth["x-amz-security-token"] =
66
+ signedRequest.headers["x-amz-security-token"];
67
+ }
68
+ return auth;
69
+ });
70
+ /**
71
+ * Build signed WebSocket connection info.
72
+ */
73
+ const buildSignedWebSocketConnection = Effect.gen(function* () {
74
+ const realtimeUrl = new URL(config.realtimeEndpoint);
75
+ realtimeUrl.pathname = "/event/realtime";
76
+ const httpUrl = new URL(config.httpEndpoint);
77
+ const request = new HttpRequest({
78
+ method: "POST",
79
+ protocol: "https:",
80
+ hostname: httpUrl.hostname,
81
+ path: "/event",
82
+ headers: {
83
+ accept: "application/json, text/javascript",
84
+ "content-encoding": "amz-1.0",
85
+ "content-type": "application/json; charset=UTF-8",
86
+ host: httpUrl.hostname,
87
+ },
88
+ body: "{}",
89
+ });
90
+ const signedRequest = yield* signRequest(request);
91
+ const headerPayload = {
92
+ accept: "application/json, text/javascript",
93
+ "content-encoding": "amz-1.0",
94
+ "content-type": "application/json; charset=UTF-8",
95
+ host: httpUrl.hostname,
96
+ "x-amz-date": signedRequest.headers["x-amz-date"],
97
+ "x-amz-content-sha256": signedRequest.headers["x-amz-content-sha256"],
98
+ Authorization: signedRequest.headers["authorization"],
99
+ };
100
+ if (signedRequest.headers["x-amz-security-token"]) {
101
+ headerPayload["x-amz-security-token"] =
102
+ signedRequest.headers["x-amz-security-token"];
103
+ }
104
+ const encodedHeader = Buffer.from(JSON.stringify(headerPayload))
105
+ .toString("base64")
106
+ .replace(/\+/g, "-")
107
+ .replace(/\//g, "_")
108
+ .replace(/=+$/, "");
109
+ const authSubprotocol = `header-${encodedHeader}`;
110
+ return {
111
+ url: realtimeUrl.toString(),
112
+ subprotocols: ["aws-appsync-event-ws", authSubprotocol],
113
+ };
114
+ });
115
+ /**
116
+ * Publish a message to a channel.
117
+ */
118
+ const publish = (channel, message) => Effect.gen(function* () {
119
+ const url = new URL(config.httpEndpoint);
120
+ const body = JSON.stringify({
121
+ channel,
122
+ events: [JSON.stringify(message)],
123
+ });
124
+ const path = url.pathname.endsWith("/event") ? url.pathname : "/event";
125
+ const request = new HttpRequest({
126
+ method: "POST",
127
+ protocol: url.protocol,
128
+ hostname: url.hostname,
129
+ path,
130
+ headers: {
131
+ "Content-Type": "application/json",
132
+ host: url.hostname,
133
+ },
134
+ body,
135
+ });
136
+ const signedRequest = yield* signRequest(request);
137
+ const publishUrl = `${url.protocol}//${url.hostname}${path}`;
138
+ const response = yield* Effect.tryPromise({
139
+ try: async () => fetch(publishUrl, {
140
+ method: "POST",
141
+ headers: signedRequest.headers,
142
+ body,
143
+ }),
144
+ catch: (error) => new Error(`Failed to publish event: ${String(error)}`),
145
+ });
146
+ if (!response.ok) {
147
+ const text = yield* Effect.tryPromise({
148
+ try: () => response.text(),
149
+ catch: () => new Error("Failed to read response"),
150
+ });
151
+ yield* Effect.fail(new Error(`Failed to publish event: ${response.status} ${text}`));
152
+ }
153
+ yield* Effect.logDebug(`Published to ${channel}`);
154
+ });
155
+ /**
156
+ * Subscribe to a channel and receive messages as a Stream.
157
+ */
158
+ const subscribe = (channel) => Stream.asyncScoped((emit) => Effect.gen(function* () {
159
+ const { url, subprotocols } = yield* buildSignedWebSocketConnection;
160
+ yield* Effect.logDebug(`Connecting to ${url}`);
161
+ const ws = new WebSocket(url, [...subprotocols]);
162
+ ws.on("open", () => {
163
+ Effect.runSync(Effect.logDebug("WebSocket connected"));
164
+ ws.send(JSON.stringify({ type: "connection_init" }));
165
+ });
166
+ ws.on("message", async (data) => {
167
+ const message = JSON.parse(data.toString());
168
+ if (message.type === "connection_ack") {
169
+ Effect.runSync(Effect.logDebug("Connection acknowledged"));
170
+ const auth = await Effect.runPromise(createSubscribeAuthorization(channel));
171
+ ws.send(JSON.stringify({
172
+ type: "subscribe",
173
+ id: "sub-1",
174
+ channel,
175
+ authorization: auth,
176
+ }));
177
+ }
178
+ else if (message.type === "subscribe_success") {
179
+ Effect.runSync(Effect.logDebug(`Subscribed to ${channel}`));
180
+ }
181
+ else if (message.type === "data" && message.id === "sub-1") {
182
+ try {
183
+ const eventData = JSON.parse(message.event);
184
+ emit.single(eventData);
185
+ }
186
+ catch (err) {
187
+ Effect.runSync(Effect.logError(`Failed to parse event data: ${err}`));
188
+ }
189
+ }
190
+ else if (message.type === "error") {
191
+ Effect.runSync(Effect.logError(`WebSocket error: ${JSON.stringify(message)}`));
192
+ emit.fail(new Error(message.errors
193
+ ?.map((e) => e.message)
194
+ .join(", ") ?? "Unknown error"));
195
+ }
196
+ });
197
+ ws.on("error", (err) => {
198
+ Effect.runSync(Effect.logError(`WebSocket error: ${err.message}`));
199
+ emit.fail(new Error(err.message));
200
+ });
201
+ ws.on("close", () => {
202
+ Effect.runSync(Effect.logDebug("WebSocket closed"));
203
+ emit.end();
204
+ });
205
+ // Cleanup when scope closes
206
+ yield* Effect.addFinalizer(() => Effect.gen(function* () {
207
+ yield* Effect.logDebug("Closing WebSocket");
208
+ ws.close();
209
+ }));
210
+ }));
211
+ /**
212
+ * Subscribe to invocations for a function.
213
+ */
214
+ const subscribeToInvocations = (channel) => subscribe(channel);
215
+ /**
216
+ * Publish a response to a channel.
217
+ */
218
+ const publishResponse = (channel, response) => publish(channel, response);
219
+ return {
220
+ publish,
221
+ subscribe,
222
+ subscribeToInvocations,
223
+ publishResponse,
224
+ createSubscribeAuthorization,
225
+ };
226
+ };
227
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9hcHBzeW5jL2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQTtBQUM5QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUNBQW1DLENBQUE7QUFDbkUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFBO0FBQ3BELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQTtBQUNuRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUN2QyxPQUFPLFNBQVMsTUFBTSxJQUFJLENBQUE7QUFZMUI7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLE1BQTJCLEVBQUUsRUFBRTtJQUMvRCxtQ0FBbUM7SUFDbkMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQTtJQUN6RSxNQUFNLE1BQU0sR0FDVixNQUFNLENBQUMsTUFBTSxJQUFJLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLFdBQVcsQ0FBQTtJQUV0RTs7T0FFRztJQUNILE1BQU0sV0FBVyxHQUFHLENBQUMsT0FBb0IsRUFBRSxFQUFFLENBQzNDLE1BQU0sQ0FBQyxVQUFVLENBQUM7UUFDaEIsR0FBRyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ2QsTUFBTSxNQUFNLEdBQUcsSUFBSSxXQUFXLENBQUM7Z0JBQzdCLFdBQVcsRUFBRSxlQUFlLEVBQUU7Z0JBQzlCLE1BQU07Z0JBQ04sT0FBTyxFQUFFLFNBQVM7Z0JBQ2xCLE1BQU0sRUFBRSxNQUFNO2FBQ2YsQ0FBQyxDQUFBO1lBQ0YsT0FBTyxNQUFN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QUFBO1FBRUYsNEJBQTRCO1FBQzVCLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLENBQzlCLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO1lBQ2xCLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtZQUMzQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDWixDQUFDLENBQUMsQ0FDSCxDQUFBO0lBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQTtJQUVIOztPQUVHO0lBQ0gsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLE9BQWUsRUFBRSxFQUFFLENBQ2pELFNBQVMsQ0FBb0IsT0FBTyxDQUFDLENBQUE7SUFFdkM7O09BRUc7SUFDSCxNQUFNLGVBQWUsR0FBRyxDQUFDLE9BQWUsRUFBRSxRQUF5QixFQUFFLEVBQUUsQ0FDckUsT0FBTyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQTtJQUU1QixPQUFPO1FBQ0wsT0FBTztRQUNQLFNBQVM7UUFDVCxzQkFBc0I7UUFDdEIsZUFBZTtRQUNmLDRCQUE0QjtLQUM3QixDQUFBO0FBQ0gsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBFZmZlY3QtYmFzZWQgQXBwU3luYyBFdmVudHMgY2xpZW50IGZvciB0aGUgZGFlbW9uLlxuICpcbiAqIFdyYXBzIHRoZSBleGlzdGluZyBBcHBTeW5jIGNsaWVudCB3aXRoIEVmZmVjdCBwcmltaXRpdmVzIGZvciBiZXR0ZXJcbiAqIGVycm9yIGhhbmRsaW5nIGFuZCByZXNvdXJjZSBtYW5hZ2VtZW50LlxuICovXG5cbmltcG9ydCB7IFNoYTI1NiB9IGZyb20gXCJAYXdzLWNyeXB0by9zaGEyNTYtanNcIlxuaW1wb3J0IHsgZGVmYXVsdFByb3ZpZGVyIH0gZnJvbSBcIkBhd3Mtc2RrL2NyZWRlbnRpYWwtcHJvdmlkZXItbm9kZVwiXG5pbXBvcnQgeyBIdHRwUmVxdWVzdCB9IGZyb20gXCJAYXdzLXNkay9wcm90b2NvbC1odHRwXCJcbmltcG9ydCB7IFNpZ25hdHVyZVY0IH0gZnJvbSBcIkBhd3Mtc2RrL3NpZ25hdHVyZS12NFwiXG5pbXBvcnQgeyBFZmZlY3QsIFN0cmVhbSB9IGZyb20gXCJlZmZlY3RcIlxuaW1wb3J0IFdlYlNvY2tldCBmcm9tIFwid3NcIlxuaW1wb3J0IHR5cGUgeyBJbnZvY2F0aW9uTWVzc2FnZSwgUmVzcG9uc2VNZXNzYWdlIH0gZnJvbSBcIi4uLy4uL3NoYXJlZC90eXBlcy5qc1wiXG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIEVmZmVjdCBBcHBTeW5jIGNsaWVudC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBTeW5jQ2xpZW50Q29uZmlnIHtcbiAgaHR0cEVuZHBvaW50OiBzdHJpbmdcbiAgcmVhbHRpbWVFbmRwb2ludDogc3RyaW5nXG4gIHJlZ2lvbj86IHN0cmluZ1xufVxuXG4vKipcbiAqIENyZWF0ZSBhbiBFZmZlY3QtYmFzZWQgQXBwU3luYyBFdmVudHMgY2xpZW50LlxuICovXG5leHBvcnQgY29uc3QgbWFrZUFwcFN5bmNDbGllbnQgPSAoY29uZmlnOiBBcHBTeW5jQ2xpZW50Q29uZmlnKSA9PiB7XG4gIC8vIEV4dHJhY3QgcmVnaW9uIGZyb20gZW5kcG9pbnQgVVJMXG4gIGNvbnN0IG1hdGNoID0gY29uZmlnLmh0dHBFbmRwb2ludC5tYXRjaCgvXFwuKFthLXowLTktXSspXFwuYW1hem9uYXdzXFwuY29tLylcbiAgY29uc3QgcmVnaW9uID1cbiAgICBjb25maWcucmVnaW9uID8/IG1hdGNoPy5bMV0gPz8gcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTiA/PyBcInVzLWVhc3QtMVwiXG5cbiAgLyoqXG4gICAqIFNpZ24gYSByZXF1ZXN0IHdpdGggQVdTIFNpZ1Y0LlxuICAgKi9cbiAgY29uc3Qgc2lnblJlcXVlc3QgPSAocmVxdWVzdDogSHR0cFJlcXVlc3QpID0+XG4gICAgRWZmZWN0LnRyeVByb21pc2Uoe1xuICAgICAgdHJ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNpZ25lciA9IG5ldyBTaWduYXR1cmVWNCh7XG4gICAgICAgICAgY3JlZGVudGlhbHM6IGRlZmF1bHRQcm92aWRlcigpLFxuICAgICAgICAgIHJlZ2lvbixcbiAgICAgICAgICBzZXJ2aWNlOiBcImFwcHN5bmNcIixcbiAgICAgICAgICBzaGEyNTY6IFNoYTI1NixcbiAgICAgICAgfSlcbiAgICAgICAgcmV0dXJuIGF3YWl0IHNpZ25lci5zaWduKHJlcXVlc3QpXG4gICAgICB9LFxuICAgICAgY2F0Y2g6IChlcnJvcikgPT4gbmV3IEVycm9yKGBGYWlsZWQgdG8gc2lnbiByZXF1ZXN0OiAke1N0cmluZyhlcnJvcil9YCksXG4gICAgfSlcblxuICAvKipcbiAgICogQ3JlYXRlIGF1dGhvcml6YXRpb24gaGVhZGVycyBmb3Igc3Vic2NyaWJlIG9wZXJhdGlvbi5cbiAgICovXG4gIGNvbnN0IGNyZWF0ZVN1YnNjcmliZUF1dGhvcml6YXRpb24gPSAoY2hhbm5lbDogc3RyaW5nKSA9PlxuICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGNvbnN0IGh0dHBVcmwgPSBuZXcgVVJMKGNvbmZpZy5odHRwRW5kcG9pbnQpXG4gICAgICBjb25zdCBwYXlsb2FkID0gSlNPTi5zdHJpbmdpZnkoeyBjaGFubmVsIH0pXG5cbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgSHR0cFJlcXVlc3Qoe1xuICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICBwcm90b2NvbDogXCJodHRwczpcIixcbiAgICAgICAgaG9zdG5hbWU6IGh0dHBVcmwuaG9zdG5hbWUsXG4gICAgICAgIHBhdGg6IFwiL2V2ZW50XCIsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICBhY2NlcHQ6IFwiYXBwbGljYXRpb24vanNvbiwgdGV4dC9qYXZhc2NyaXB0XCIsXG4gICAgICAgICAgXCJjb250ZW50LWVuY29kaW5nXCI6IFwiYW16LTEuMFwiLFxuICAgICAgICAgIFwiY29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOFwiLFxuICAgICAgICAgIGhvc3Q6IGh0dHBVcmwuaG9zdG5hbWUsXG4gICAgICAgIH0sXG4gICAgICAgIGJvZHk6IHBheWxvYWQsXG4gICAgICB9KVxuXG4gICAgICBjb25zdCBzaWduZWRSZXF1ZXN0ID0geWllbGQqIHNpZ25SZXF1ZXN0KHJlcXVlc3QpXG5cbiAgICAgIGNvbnN0IGF1dGg6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAgIGFjY2VwdDogXCJhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHRcIixcbiAgICAgICAgXCJjb250ZW50LWVuY29kaW5nXCI6IFwiYW16LTEuMFwiLFxuICAgICAgICBcImNvbnRlbnQtdHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLThcIixcbiAgICAgICAgaG9zdDogaHR0cFVybC5ob3N0bmFtZSxcbiAgICAgICAgXCJ4LWFtei1kYXRlXCI6IHNpZ25lZFJlcXVlc3QuaGVhZGVyc1tcIngtYW16LWRhdGVcIl0sXG4gICAgICAgIFwieC1hbXotY29udGVudC1zaGEyNTZcIjogc2lnbmVkUmVxdWVzdC5oZWFkZXJzW1wieC1hbXotY29udGVudC1zaGEyNTZcIl0sXG4gICAgICAgIEF1dGhvcml6YXRpb246IHNpZ25lZFJlcXVlc3QuaGVhZGVyc1tcImF1dGhvcml6YXRpb25cIl0sXG4gICAgICB9XG5cbiAgICAgIGlmIChzaWduZWRSZXF1ZXN0LmhlYWRlcnNbXCJ4LWFtei1zZWN1cml0eS10b2tlblwiXSkge1xuICAgICAgICBhdXRoW1wieC1hbXotc2VjdXJpdHktdG9rZW5cIl0gPVxuICAgICAgICAgIHNpZ25lZFJlcXVlc3QuaGVhZGVyc1tcIngtYW16LXNlY3VyaXR5LXRva2VuXCJdXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhdXRoXG4gICAgfSlcblxuICAvKipcbiAgICogQnVpbGQgc2lnbmVkIFdlYlNvY2tldCBjb25uZWN0aW9uIGluZm8uXG4gICAqL1xuICBjb25zdCBidWlsZFNpZ25lZFdlYlNvY2tldENvbm5lY3Rpb24gPSBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgY29uc3QgcmVhbHRpbWVVcmwgPSBuZXcgVVJMKGNvbmZpZy5yZWFsdGltZUVuZHBvaW50KVxuICAgIHJlYWx0aW1lVXJsLnBhdGhuYW1lID0gXCIvZXZlbnQvcmVhbHRpbWVcIlxuICAgIGNvbnN0IGh0dHBVcmwgPSBuZXcgVVJMKGNvbmZpZy5odHRwRW5kcG9pbnQpXG5cbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IEh0dHBSZXF1ZXN0KHtcbiAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICBwcm90b2NvbDogXCJodHRwczpcIixcbiAgICAgIGhvc3RuYW1lOiBodHRwVXJsLmhvc3RuYW1lLFxuICAgICAgcGF0aDogXCIvZXZlbnRcIixcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgYWNjZXB0OiBcImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdFwiLFxuICAgICAgICBcImNvbnRlbnQtZW5jb2RpbmdcIjogXCJhbXotMS4wXCIsXG4gICAgICAgIFwiY29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOFwiLFxuICAgICAgICBob3N0OiBodHRwVXJsLmhvc3RuYW1lLFxuICAgICAgfSxcbiAgICAgIGJvZHk6IFwie31cIixcbiAgICB9KVxuXG4gICAgY29uc3Qgc2lnbmVkUmVxdWVzdCA9IHlpZWxkKiBzaWduUmVxdWVzdChyZXF1ZXN0KVxuXG4gICAgY29uc3QgaGVhZGVyUGF5bG9hZDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIGFjY2VwdDogXCJhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHRcIixcbiAgICAgIFwiY29udGVudC1lbmNvZGluZ1wiOiBcImFtei0xLjBcIixcbiAgICAgIFwiY29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOFwiLFxuICAgICAgaG9zdDogaHR0cFVybC5ob3N0bmFtZSxcbiAgICAgIFwieC1hbXotZGF0ZVwiOiBzaWduZWRSZXF1ZXN0LmhlYWRlcnNbXCJ4LWFtei1kYXRlXCJdLFxuICAgICAgXCJ4LWFtei1jb250ZW50LXNoYTI1NlwiOiBzaWduZWRSZXF1ZXN0LmhlYWRlcnNbXCJ4LWFtei1jb250ZW50LXNoYTI1NlwiXSxcbiAgICAgIEF1dGhvcml6YXRpb246IHNpZ25lZFJlcXVlc3QuaGVhZGVyc1tcImF1dGhvcml6YXRpb25cIl0sXG4gICAgfVxuXG4gICAgaWYgKHNpZ25lZFJlcXVlc3QuaGVhZGVyc1tcIngtYW16LXNlY3VyaXR5LXRva2VuXCJdKSB7XG4gICAgICBoZWFkZXJQYXlsb2FkW1wieC1hbXotc2VjdXJpdHktdG9rZW5cIl0gPVxuICAgICAgICBzaWduZWRSZXF1ZXN0LmhlYWRlcnNbXCJ4LWFtei1zZWN1cml0eS10b2tlblwiXVxuICAgIH1cblxuICAgIGNvbnN0IGVuY29kZWRIZWFkZXIgPSBCdWZmZXIuZnJvbShKU09OLnN0cmluZ2lmeShoZWFkZXJQYXlsb2FkKSlcbiAgICAgIC50b1N0cmluZyhcImJhc2U2NFwiKVxuICAgICAgLnJlcGxhY2UoL1xcKy9nLCBcIi1cIilcbiAgICAgIC5yZXBsYWNlKC9cXC8vZywgXCJfXCIpXG4gICAgICAucmVwbGFjZSgvPSskLywgXCJcIilcblxuICAgIGNvbnN0IGF1dGhTdWJwcm90b2NvbCA9IGBoZWFkZXItJHtlbmNvZGVkSGVhZGVyfWBcblxuICAgIHJldHVybiB7XG4gICAgICB1cmw6IHJlYWx0aW1lVXJsLnRvU3RyaW5nKCksXG4gICAgICBzdWJwcm90b2NvbHM6IFtcImF3cy1hcHBzeW5jLWV2ZW50LXdzXCIsIGF1dGhTdWJwcm90b2NvbF0gYXMgY29uc3QsXG4gICAgfVxuICB9KVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoIGEgbWVzc2FnZSB0byBhIGNoYW5uZWwuXG4gICAqL1xuICBjb25zdCBwdWJsaXNoID0gKGNoYW5uZWw6IHN0cmluZywgbWVzc2FnZTogdW5rbm93bikgPT5cbiAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKGNvbmZpZy5odHRwRW5kcG9pbnQpXG4gICAgICBjb25zdCBib2R5ID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBjaGFubmVsLFxuICAgICAgICBldmVudHM6IFtKU09OLnN0cmluZ2lmeShtZXNzYWdlKV0sXG4gICAgICB9KVxuXG4gICAgICBjb25zdCBwYXRoID0gdXJsLnBhdGhuYW1lLmVuZHNXaXRoKFwiL2V2ZW50XCIpID8gdXJsLnBhdGhuYW1lIDogXCIvZXZlbnRcIlxuXG4gICAgICBjb25zdCByZXF1ZXN0ID0gbmV3IEh0dHBSZXF1ZXN0KHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgcHJvdG9jb2w6IHVybC5wcm90b2NvbCxcbiAgICAgICAgaG9zdG5hbWU6IHVybC5ob3N0bmFtZSxcbiAgICAgICAgcGF0aCxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICAgIGhvc3Q6IHVybC5ob3N0bmFtZSxcbiAgICAgICAgfSxcbiAgICAgICAgYm9keSxcbiAgICAgIH0pXG5cbiAgICAgIGNvbnN0IHNpZ25lZFJlcXVlc3QgPSB5aWVsZCogc2lnblJlcXVlc3QocmVxdWVzdClcblxuICAgICAgY29uc3QgcHVibGlzaFVybCA9IGAke3VybC5wcm90b2NvbH0vLyR7dXJsLmhvc3RuYW1lfSR7cGF0aH1gXG4gICAgICBjb25zdCByZXNwb25zZSA9IHlpZWxkKiBFZmZlY3QudHJ5UHJvbWlzZSh7XG4gICAgICAgIHRyeTogYXN5bmMgKCkgPT5cbiAgICAgICAgICBmZXRjaChwdWJsaXNoVXJsLCB7XG4gICAgICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICAgICAgaGVhZGVyczogc2lnbmVkUmVxdWVzdC5oZWFkZXJzIGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4sXG4gICAgICAgICAgICBib2R5LFxuICAgICAgICAgIH0pLFxuICAgICAgICBjYXRjaDogKGVycm9yKSA9PlxuICAgICAgICAgIG5ldyBFcnJvcihgRmFpbGVkIHRvIHB1Ymxpc2ggZXZlbnQ6ICR7U3RyaW5nKGVycm9yKX1gKSxcbiAgICAgIH0pXG5cbiAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgY29uc3QgdGV4dCA9IHlpZWxkKiBFZmZlY3QudHJ5UHJvbWlzZSh7XG4gICAgICAgICAgdHJ5OiAoKSA9PiByZXNwb25zZS50ZXh0KCksXG4gICAgICAgICAgY2F0Y2g6ICgpID0+IG5ldyBFcnJvcihcIkZhaWxlZCB0byByZWFkIHJlc3BvbnNlXCIpLFxuICAgICAgICB9KVxuICAgICAgICB5aWVsZCogRWZmZWN0LmZhaWwoXG4gICAgICAgICAgbmV3IEVycm9yKGBGYWlsZWQgdG8gcHVibGlzaCBldmVudDogJHtyZXNwb25zZS5zdGF0dXN9ICR7dGV4dH1gKSxcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICB5aWVsZCogRWZmZWN0LmxvZ0RlYnVnKGBQdWJsaXNoZWQgdG8gJHtjaGFubmVsfWApXG4gICAgfSlcblxuICAvKipcbiAgICogU3Vic2NyaWJlIHRvIGEgY2hhbm5lbCBhbmQgcmVjZWl2ZSBtZXNzYWdlcyBhcyBhIFN0cmVhbS5cbiAgICovXG4gIGNvbnN0IHN1YnNjcmliZSA9IDxUPihjaGFubmVsOiBzdHJpbmcpID0+XG4gICAgU3RyZWFtLmFzeW5jU2NvcGVkPFQsIEVycm9yPigoZW1pdCkgPT5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgeyB1cmwsIHN1YnByb3RvY29scyB9ID0geWllbGQqIGJ1aWxkU2lnbmVkV2ViU29ja2V0Q29ubmVjdGlvblxuXG4gICAgICAgIHlpZWxkKiBFZmZlY3QubG9nRGVidWcoYENvbm5lY3RpbmcgdG8gJHt1cmx9YClcblxuICAgICAgICBjb25zdCB3cyA9IG5ldyBXZWJTb2NrZXQodXJsLCBbLi4uc3VicHJvdG9jb2xzXSlcbiAgICAgICAgd3Mub24oXCJvcGVuXCIsICgpID0+IHtcbiAgICAgICAgICBFZmZlY3QucnVuU3luYyhFZmZlY3QubG9nRGVidWcoXCJXZWJTb2NrZXQgY29ubmVjdGVkXCIpKVxuICAgICAgICAgIHdzLnNlbmQoSlNPTi5zdHJpbmdpZnkoeyB0eXBlOiBcImNvbm5lY3Rpb25faW5pdFwiIH0pKVxuICAgICAgICB9KVxuXG4gICAgICAgIHdzLm9uKFwibWVzc2FnZVwiLCBhc3luYyAoZGF0YSkgPT4ge1xuICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBKU09OLnBhcnNlKGRhdGEudG9TdHJpbmcoKSlcblxuICAgICAgICAgIGlmIChtZXNzYWdlLnR5cGUgPT09IFwiY29ubmVjdGlvbl9hY2tcIikge1xuICAgICAgICAgICAgRWZmZWN0LnJ1blN5bmMoRWZmZWN0LmxvZ0RlYnVnKFwiQ29ubmVjdGlvbiBhY2tub3dsZWRnZWRcIikpXG4gICAgICAgICAgICBjb25zdCBhdXRoID0gYXdhaXQgRWZmZWN0LnJ1blByb21pc2UoXG4gICAgICAgICAgICAgIGNyZWF0ZVN1YnNjcmliZUF1dGhvcml6YXRpb24oY2hhbm5lbCksXG4gICAgICAgICAgICApXG4gICAgICAgICAgICB3cy5zZW5kKFxuICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJzdWJzY3JpYmVcIixcbiAgICAgICAgICAgICAgICBpZDogXCJzdWItMVwiLFxuICAgICAgICAgICAgICAgIGNoYW5uZWwsXG4gICAgICAgICAgICAgICAgYXV0aG9yaXphdGlvbjogYXV0aCxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApXG4gICAgICAgICAgfSBlbHNlIGlmIChtZXNzYWdlLnR5cGUgPT09IFwic3Vic2NyaWJlX3N1Y2Nlc3NcIikge1xuICAgICAgICAgICAgRWZmZWN0LnJ1blN5bmMoRWZmZWN0LmxvZ0RlYnVnKGBTdWJzY3JpYmVkIHRvICR7Y2hhbm5lbH1gKSlcbiAgICAgICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UudHlwZSA9PT0gXCJkYXRhXCIgJiYgbWVzc2FnZS5pZCA9PT0gXCJzdWItMVwiKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCBldmVudERhdGEgPSBKU09OLnBhcnNlKG1lc3NhZ2UuZXZlbnQpIGFzIFRcbiAgICAgICAgICAgICAgZW1pdC5zaW5nbGUoZXZlbnREYXRhKVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgIEVmZmVjdC5ydW5TeW5jKFxuICAgICAgICAgICAgICAgIEVmZmVjdC5sb2dFcnJvcihgRmFpbGVkIHRvIHBhcnNlIGV2ZW50IGRhdGE6ICR7ZXJyfWApLFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChtZXNzYWdlLnR5cGUgPT09IFwiZXJyb3JcIikge1xuICAgICAgICAgICAgRWZmZWN0LnJ1blN5bmMoXG4gICAgICAgICAgICAgIEVmZmVjdC5sb2dFcnJvcihgV2ViU29ja2V0IGVycm9yOiAke0pTT04uc3RyaW5naWZ5KG1lc3NhZ2UpfWApLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgZW1pdC5mYWlsKFxuICAgICAgICAgICAgICBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5lcnJvcnNcbiAgICAgICAgICAgICAgICAgID8ubWFwKChlOiB7IG1lc3NhZ2U6IHN0cmluZyB9KSA9PiBlLm1lc3NhZ2UpXG4gICAgICAgICAgICAgICAgICAuam9pbihcIiwgXCIpID8/IFwiVW5rbm93biBlcnJvclwiLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICB3cy5vbihcImVycm9yXCIsIChlcnIpID0+IHtcbiAgICAgICAgICBFZmZlY3QucnVuU3luYyhFZmZlY3QubG9nRXJyb3IoYFdlYlNvY2tldCBlcnJvcjogJHtlcnIubWVzc2FnZX1gKSlcbiAgICAgICAgICBlbWl0LmZhaWwobmV3IEVycm9yKGVyci5tZXNzYWdlKSlcbiAgICAgICAgfSlcblxuICAgICAgICB3cy5vbihcImNsb3NlXCIsICgpID0+IHtcbiAgICAgICAgICBFZmZlY3QucnVuU3luYyhFZmZlY3QubG9nRGVidWcoXCJXZWJTb2NrZXQgY2xvc2VkXCIpKVxuICAgICAgICAgIGVtaXQuZW5kKClcbiAgICAgICAgfSlcblxuICAgICAgICAvLyBDbGVhbnVwIHdoZW4gc2NvcGUgY2xvc2VzXG4gICAgICAgIHlpZWxkKiBFZmZlY3QuYWRkRmluYWxpemVyKCgpID0+XG4gICAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgeWllbGQqIEVmZmVjdC5sb2dEZWJ1ZyhcIkNsb3NpbmcgV2ViU29ja2V0XCIpXG4gICAgICAgICAgICB3cy5jbG9zZSgpXG4gICAgICAgICAgfSksXG4gICAgICAgIClcbiAgICAgIH0pLFxuICAgIClcblxuICAvKipcbiAgICogU3Vic2NyaWJlIHRvIGludm9jYXRpb25zIGZvciBhIGZ1bmN0aW9uLlxuICAgKi9cbiAgY29uc3Qgc3Vic2NyaWJlVG9JbnZvY2F0aW9ucyA9IChjaGFubmVsOiBzdHJpbmcpID0+XG4gICAgc3Vic2NyaWJlPEludm9jYXRpb25NZXNzYWdlPihjaGFubmVsKVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoIGEgcmVzcG9uc2UgdG8gYSBjaGFubmVsLlxuICAgKi9cbiAgY29uc3QgcHVibGlzaFJlc3BvbnNlID0gKGNoYW5uZWw6IHN0cmluZywgcmVzcG9uc2U6IFJlc3BvbnNlTWVzc2FnZSkgPT5cbiAgICBwdWJsaXNoKGNoYW5uZWwsIHJlc3BvbnNlKVxuXG4gIHJldHVybiB7XG4gICAgcHVibGlzaCxcbiAgICBzdWJzY3JpYmUsXG4gICAgc3Vic2NyaWJlVG9JbnZvY2F0aW9ucyxcbiAgICBwdWJsaXNoUmVzcG9uc2UsXG4gICAgY3JlYXRlU3Vic2NyaWJlQXV0aG9yaXphdGlvbixcbiAgfVxufVxuXG4vKipcbiAqIFR5cGUgZm9yIHRoZSBBcHBTeW5jIGNsaWVudC5cbiAqL1xuZXhwb3J0IHR5cGUgQXBwU3luY0NsaWVudCA9IFJldHVyblR5cGU8dHlwZW9mIG1ha2VBcHBTeW5jQ2xpZW50PlxuIl19
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * CDK app entry point for bootstrap deployment.
4
+ *
5
+ * This file is used by CDK CLI to deploy the CdkLocalLambdaBootstrapStack.
6
+ */
7
+ export {};
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * CDK app entry point for bootstrap deployment.
4
+ *
5
+ * This file is used by CDK CLI to deploy the CdkLocalLambdaBootstrapStack.
6
+ */
7
+ import * as cdk from "aws-cdk-lib";
8
+ import { CdkLocalLambdaBootstrapStack } from "../bootstrap-stack/bootstrap-stack.js";
9
+ const app = new cdk.App();
10
+ // Get account and region from environment
11
+ const account = process.env.CDK_DEFAULT_ACCOUNT || process.env.AWS_ACCOUNT_ID;
12
+ const region = process.env.CDK_DEFAULT_REGION ||
13
+ process.env.AWS_REGION ||
14
+ process.env.AWS_DEFAULT_REGION;
15
+ if (!account || !region) {
16
+ console.error("Error: AWS account and region must be configured.");
17
+ console.error("Set CDK_DEFAULT_ACCOUNT and CDK_DEFAULT_REGION, or use AWS CLI profile.");
18
+ console.error(`Current: account=${account}, region=${region}`);
19
+ process.exit(1);
20
+ }
21
+ new CdkLocalLambdaBootstrapStack(app, "CdkLocalLambdaBootstrapStack", {
22
+ env: { account, region },
23
+ });
24
+ app.synth();
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RrLWFwcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvY2RrLWFwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0E7Ozs7R0FJRztBQUVILE9BQU8sS0FBSyxHQUFHLE1BQU0sYUFBYSxDQUFBO0FBQ2xDLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLHVDQUF1QyxDQUFBO0FBRXBGLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFBO0FBRXpCLDBDQUEwQztBQUMxQyxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFBO0FBQzdFLE1BQU0sTUFBTSxHQUNWLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCO0lBQzlCLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVTtJQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFBO0FBRWhDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUN4QixPQUFPLENBQUMsS0FBSyxDQUFDLG1EQUFtRCxDQUFDLENBQUE7SUFDbEUsT0FBTyxDQUFDLEtBQUssQ0FDWCx5RUFBeUUsQ0FDMUUsQ0FBQTtJQUNELE9BQU8sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLE9BQU8sWUFBWSxNQUFNLEVBQUUsQ0FBQyxDQUFBO0lBQzlELE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFDakIsQ0FBQztBQUVELElBQUksNEJBQTRCLENBQUMsR0FBRyxFQUFFLDhCQUE4QixFQUFFO0lBQ3BFLEdBQUcsRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUU7Q0FDekIsQ0FBQyxDQUFBO0FBRUYsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiIyEvdXNyL2Jpbi9lbnYgYnVuXG4vKipcbiAqIENESyBhcHAgZW50cnkgcG9pbnQgZm9yIGJvb3RzdHJhcCBkZXBsb3ltZW50LlxuICpcbiAqIFRoaXMgZmlsZSBpcyB1c2VkIGJ5IENESyBDTEkgdG8gZGVwbG95IHRoZSBDZGtMb2NhbExhbWJkYUJvb3RzdHJhcFN0YWNrLlxuICovXG5cbmltcG9ydCAqIGFzIGNkayBmcm9tIFwiYXdzLWNkay1saWJcIlxuaW1wb3J0IHsgQ2RrTG9jYWxMYW1iZGFCb290c3RyYXBTdGFjayB9IGZyb20gXCIuLi9ib290c3RyYXAtc3RhY2svYm9vdHN0cmFwLXN0YWNrLmpzXCJcblxuY29uc3QgYXBwID0gbmV3IGNkay5BcHAoKVxuXG4vLyBHZXQgYWNjb3VudCBhbmQgcmVnaW9uIGZyb20gZW52aXJvbm1lbnRcbmNvbnN0IGFjY291bnQgPSBwcm9jZXNzLmVudi5DREtfREVGQVVMVF9BQ0NPVU5UIHx8IHByb2Nlc3MuZW52LkFXU19BQ0NPVU5UX0lEXG5jb25zdCByZWdpb24gPVxuICBwcm9jZXNzLmVudi5DREtfREVGQVVMVF9SRUdJT04gfHxcbiAgcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTiB8fFxuICBwcm9jZXNzLmVudi5BV1NfREVGQVVMVF9SRUdJT05cblxuaWYgKCFhY2NvdW50IHx8ICFyZWdpb24pIHtcbiAgY29uc29sZS5lcnJvcihcIkVycm9yOiBBV1MgYWNjb3VudCBhbmQgcmVnaW9uIG11c3QgYmUgY29uZmlndXJlZC5cIilcbiAgY29uc29sZS5lcnJvcihcbiAgICBcIlNldCBDREtfREVGQVVMVF9BQ0NPVU5UIGFuZCBDREtfREVGQVVMVF9SRUdJT04sIG9yIHVzZSBBV1MgQ0xJIHByb2ZpbGUuXCIsXG4gIClcbiAgY29uc29sZS5lcnJvcihgQ3VycmVudDogYWNjb3VudD0ke2FjY291bnR9LCByZWdpb249JHtyZWdpb259YClcbiAgcHJvY2Vzcy5leGl0KDEpXG59XG5cbm5ldyBDZGtMb2NhbExhbWJkYUJvb3RzdHJhcFN0YWNrKGFwcCwgXCJDZGtMb2NhbExhbWJkYUJvb3RzdHJhcFN0YWNrXCIsIHtcbiAgZW52OiB7IGFjY291bnQsIHJlZ2lvbiB9LFxufSlcblxuYXBwLnN5bnRoKClcbiJdfQ==
@@ -0,0 +1,9 @@
1
+ import { Command } from "@effect/cli";
2
+ import { Option } from "effect";
3
+ /**
4
+ * Bootstrap command - deploys the CdkLocalLambdaBootstrapStack
5
+ */
6
+ export declare const bootstrapCommand: Command.Command<"bootstrap", never, Error, {
7
+ readonly profile: Option.Option<string>;
8
+ readonly region: Option.Option<string>;
9
+ }>;
@@ -0,0 +1,50 @@
1
+ import { execSync } from "node:child_process";
2
+ import { Command, Options } from "@effect/cli";
3
+ import { Console, Effect, Option } from "effect";
4
+ import { BOOTSTRAP_STACK_NAME } from "../../shared/types.js";
5
+ // Common options
6
+ const profileOption = Options.text("profile").pipe(Options.optional, Options.withDescription("AWS profile to use"));
7
+ const regionOption = Options.text("region").pipe(Options.optional, Options.withDescription("AWS region to deploy to"));
8
+ /**
9
+ * Bootstrap command - deploys the CdkLocalLambdaBootstrapStack
10
+ */
11
+ export const bootstrapCommand = Command.make("bootstrap", { profile: profileOption, region: regionOption }, ({ profile, region }) => Effect.gen(function* () {
12
+ yield* Console.log("Deploying bootstrap stack...");
13
+ // Build CDK deploy command with options
14
+ const args = [
15
+ "npx",
16
+ "cdk",
17
+ "deploy",
18
+ BOOTSTRAP_STACK_NAME,
19
+ "--require-approval",
20
+ "never",
21
+ ];
22
+ if (Option.isSome(profile)) {
23
+ args.push("--profile", profile.value);
24
+ }
25
+ // Build environment with optional region
26
+ const env = { ...process.env };
27
+ if (Option.isSome(region)) {
28
+ env.AWS_REGION = region.value;
29
+ env.CDK_DEFAULT_REGION = region.value;
30
+ }
31
+ const command = args.join(" ");
32
+ yield* Console.log(`Running: ${command}`);
33
+ // Execute CDK deploy synchronously so output is streamed
34
+ yield* Effect.try({
35
+ try: () => {
36
+ execSync(command, {
37
+ stdio: "inherit",
38
+ env,
39
+ });
40
+ },
41
+ catch: (error) => {
42
+ if (error instanceof Error) {
43
+ return new Error(`CDK deploy failed: ${error.message}`);
44
+ }
45
+ return new Error("CDK deploy failed with unknown error");
46
+ },
47
+ });
48
+ yield* Console.log("Bootstrap stack deployed successfully!");
49
+ })).pipe(Command.withDescription("Deploy the Live Lambda bootstrap stack to AWS"));
50
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vdHN0cmFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jb21tYW5kcy9ib290c3RyYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBQzdDLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQzlDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUNoRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQTtBQUU1RCxpQkFBaUI7QUFDakIsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQ2hELE9BQU8sQ0FBQyxRQUFRLEVBQ2hCLE9BQU8sQ0FBQyxlQUFlLENBQUMsb0JBQW9CLENBQUMsQ0FDOUMsQ0FBQTtBQUVELE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUM5QyxPQUFPLENBQUMsUUFBUSxFQUNoQixPQUFPLENBQUMsZUFBZSxDQUFDLHlCQUF5QixDQUFDLENBQ25ELENBQUE7QUFFRDs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQzFDLFdBQVcsRUFDWCxFQUFFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxFQUNoRCxDQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FDdEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUM7SUFDbEIsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFBO0lBRWxELHdDQUF3QztJQUN4QyxNQUFNLElBQUksR0FBRztRQUNYLEtBQUs7UUFDTCxLQUFLO1FBQ0wsUUFBUTtRQUNSLG9CQUFvQjtRQUNwQixvQkFBb0I7UUFDcEIsT0FBTztLQUNSLENBQUE7SUFFRCxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDdkMsQ0FBQztJQUVELHlDQUF5QztJQUN6QyxNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFBO0lBQzlCLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzFCLEdBQUcsQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQTtRQUM3QixHQUFHLENBQUMsa0JBQWtCLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQTtJQUN2QyxDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUM5QixLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksT0FBTyxFQUFFLENBQUMsQ0FBQTtJQUV6Qyx5REFBeUQ7SUFDekQsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQztRQUNoQixHQUFHLEVBQUUsR0FBRyxFQUFFO1lBQ1IsUUFBUSxDQUFDLE9BQU8sRUFBRTtnQkFDaEIsS0FBSyxFQUFFLFNBQVM7Z0JBQ2hCLEdBQUc7YUFDSixDQUFDLENBQUE7UUFDSixDQUFDO1FBQ0QsS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDZixJQUFJLEtBQUssWUFBWSxLQUFLLEVBQUUsQ0FBQztnQkFDM0IsT0FBTyxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7WUFDekQsQ0FBQztZQUNELE9BQU8sSUFBSSxLQUFLLENBQUMsc0NBQXNDLENBQUMsQ0FBQTtRQUMxRCxDQUFDO0tBQ0YsQ0FBQyxDQUFBO0lBRUYsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFBO0FBQzlELENBQUMsQ0FBQyxDQUNMLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsK0NBQStDLENBQUMsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCJcbmltcG9ydCB7IENvbW1hbmQsIE9wdGlvbnMgfSBmcm9tIFwiQGVmZmVjdC9jbGlcIlxuaW1wb3J0IHsgQ29uc29sZSwgRWZmZWN0LCBPcHRpb24gfSBmcm9tIFwiZWZmZWN0XCJcbmltcG9ydCB7IEJPT1RTVFJBUF9TVEFDS19OQU1FIH0gZnJvbSBcIi4uLy4uL3NoYXJlZC90eXBlcy5qc1wiXG5cbi8vIENvbW1vbiBvcHRpb25zXG5jb25zdCBwcm9maWxlT3B0aW9uID0gT3B0aW9ucy50ZXh0KFwicHJvZmlsZVwiKS5waXBlKFxuICBPcHRpb25zLm9wdGlvbmFsLFxuICBPcHRpb25zLndpdGhEZXNjcmlwdGlvbihcIkFXUyBwcm9maWxlIHRvIHVzZVwiKSxcbilcblxuY29uc3QgcmVnaW9uT3B0aW9uID0gT3B0aW9ucy50ZXh0KFwicmVnaW9uXCIpLnBpcGUoXG4gIE9wdGlvbnMub3B0aW9uYWwsXG4gIE9wdGlvbnMud2l0aERlc2NyaXB0aW9uKFwiQVdTIHJlZ2lvbiB0byBkZXBsb3kgdG9cIiksXG4pXG5cbi8qKlxuICogQm9vdHN0cmFwIGNvbW1hbmQgLSBkZXBsb3lzIHRoZSBDZGtMb2NhbExhbWJkYUJvb3RzdHJhcFN0YWNrXG4gKi9cbmV4cG9ydCBjb25zdCBib290c3RyYXBDb21tYW5kID0gQ29tbWFuZC5tYWtlKFxuICBcImJvb3RzdHJhcFwiLFxuICB7IHByb2ZpbGU6IHByb2ZpbGVPcHRpb24sIHJlZ2lvbjogcmVnaW9uT3B0aW9uIH0sXG4gICh7IHByb2ZpbGUsIHJlZ2lvbiB9KSA9PlxuICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIHlpZWxkKiBDb25zb2xlLmxvZyhcIkRlcGxveWluZyBib290c3RyYXAgc3RhY2suLi5cIilcblxuICAgICAgLy8gQnVpbGQgQ0RLIGRlcGxveSBjb21tYW5kIHdpdGggb3B0aW9uc1xuICAgICAgY29uc3QgYXJncyA9IFtcbiAgICAgICAgXCJucHhcIixcbiAgICAgICAgXCJjZGtcIixcbiAgICAgICAgXCJkZXBsb3lcIixcbiAgICAgICAgQk9PVFNUUkFQX1NUQUNLX05BTUUsXG4gICAgICAgIFwiLS1yZXF1aXJlLWFwcHJvdmFsXCIsXG4gICAgICAgIFwibmV2ZXJcIixcbiAgICAgIF1cblxuICAgICAgaWYgKE9wdGlvbi5pc1NvbWUocHJvZmlsZSkpIHtcbiAgICAgICAgYXJncy5wdXNoKFwiLS1wcm9maWxlXCIsIHByb2ZpbGUudmFsdWUpXG4gICAgICB9XG5cbiAgICAgIC8vIEJ1aWxkIGVudmlyb25tZW50IHdpdGggb3B0aW9uYWwgcmVnaW9uXG4gICAgICBjb25zdCBlbnYgPSB7IC4uLnByb2Nlc3MuZW52IH1cbiAgICAgIGlmIChPcHRpb24uaXNTb21lKHJlZ2lvbikpIHtcbiAgICAgICAgZW52LkFXU19SRUdJT04gPSByZWdpb24udmFsdWVcbiAgICAgICAgZW52LkNES19ERUZBVUxUX1JFR0lPTiA9IHJlZ2lvbi52YWx1ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBjb21tYW5kID0gYXJncy5qb2luKFwiIFwiKVxuICAgICAgeWllbGQqIENvbnNvbGUubG9nKGBSdW5uaW5nOiAke2NvbW1hbmR9YClcblxuICAgICAgLy8gRXhlY3V0ZSBDREsgZGVwbG95IHN5bmNocm9ub3VzbHkgc28gb3V0cHV0IGlzIHN0cmVhbWVkXG4gICAgICB5aWVsZCogRWZmZWN0LnRyeSh7XG4gICAgICAgIHRyeTogKCkgPT4ge1xuICAgICAgICAgIGV4ZWNTeW5jKGNvbW1hbmQsIHtcbiAgICAgICAgICAgIHN0ZGlvOiBcImluaGVyaXRcIixcbiAgICAgICAgICAgIGVudixcbiAgICAgICAgICB9KVxuICAgICAgICB9LFxuICAgICAgICBjYXRjaDogKGVycm9yKSA9PiB7XG4gICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRXJyb3IoYENESyBkZXBsb3kgZmFpbGVkOiAke2Vycm9yLm1lc3NhZ2V9YClcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBFcnJvcihcIkNESyBkZXBsb3kgZmFpbGVkIHdpdGggdW5rbm93biBlcnJvclwiKVxuICAgICAgICB9LFxuICAgICAgfSlcblxuICAgICAgeWllbGQqIENvbnNvbGUubG9nKFwiQm9vdHN0cmFwIHN0YWNrIGRlcGxveWVkIHN1Y2Nlc3NmdWxseSFcIilcbiAgICB9KSxcbikucGlwZShDb21tYW5kLndpdGhEZXNjcmlwdGlvbihcIkRlcGxveSB0aGUgTGl2ZSBMYW1iZGEgYm9vdHN0cmFwIHN0YWNrIHRvIEFXU1wiKSlcbiJdfQ==
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Local command for running Lambda functions locally using Docker.
3
+ *
4
+ * This command:
5
+ * 1. Starts CDK watch with CDK_LIVE=true and hotswap
6
+ * 2. Discovers Lambda functions with live-lambda:handler tag
7
+ * 3. Connects to AppSync Events
8
+ * 4. Subscribes to invocation channels
9
+ * 5. For each function, maintains ONE Docker container that handles all invocations
10
+ * 6. Sends responses back via AppSync
11
+ * 7. Re-discovers functions after each CDK deploy
12
+ */
13
+ import { Command } from "@effect/cli";
14
+ import { type CommandExecutor } from "@effect/platform";
15
+ /**
16
+ * Invocation context for tracking and logging.
17
+ */
18
+ export interface InvocationContext {
19
+ /** Sequential invocation number */
20
+ num: number;
21
+ /** Start timestamp in milliseconds */
22
+ start: number;
23
+ /** Function name */
24
+ fn: string;
25
+ /** Whether this is a Docker container invocation */
26
+ isDocker: boolean;
27
+ }
28
+ /**
29
+ * Local command definition.
30
+ */
31
+ export declare const localCommand: Command.Command<"local", CommandExecutor.CommandExecutor, Error | import("@effect/platform/Error").PlatformError, {
32
+ readonly profile: import("effect/Option").Option<string>;
33
+ readonly region: import("effect/Option").Option<string>;
34
+ readonly qualifier: string;
35
+ readonly stacks: import("effect/Option").Option<string>;
36
+ readonly all: boolean;
37
+ readonly debug: boolean;
38
+ readonly idleTimeout: number;
39
+ readonly pollTimeout: import("effect/Option").Option<number>;
40
+ }>;