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,260 @@
1
+ /**
2
+ * Bootstrap file that installs hooks for NodejsFunction and DockerImageFunction
3
+ * BEFORE any CDK imports.
4
+ *
5
+ * This must be imported as the very first thing in the CDK app entry point,
6
+ * before any other imports.
7
+ *
8
+ * Runtime support:
9
+ * - Node.js: patches Module._load to intercept module loading
10
+ * - Bun: directly imports and patches modules (Module._load not supported)
11
+ *
12
+ * Hooks installed:
13
+ * - NodejsFunction: captures entry and handler props
14
+ * - DockerImageFunction: captures docker context path from code prop
15
+ * - DockerImageCode.fromImageAsset: captures the directory path
16
+ */
17
+ import { createRequire } from "node:module";
18
+ const requireFromPackage = createRequire(import.meta.url);
19
+ // Prefer resolving dependencies from the *CDK app project* (process.cwd()).
20
+ // This avoids patching a nested aws-cdk-lib copy when cdk-local-lambda is
21
+ // installed with its own node_modules (common with package managers).
22
+ let requireFromProject = requireFromPackage;
23
+ try {
24
+ requireFromProject = createRequire(`${process.cwd()}/package.json`);
25
+ }
26
+ catch {
27
+ // Fall back to resolving relative to this package.
28
+ }
29
+ /**
30
+ * Detect if we're running in Bun runtime
31
+ */
32
+ const isBun = typeof process.versions.bun !== "undefined";
33
+ // Symbols for NodejsFunction
34
+ const ENTRY_SYMBOL = Symbol.for("live-lambda:entry");
35
+ const HANDLER_SYMBOL = Symbol.for("live-lambda:handler");
36
+ // Symbols for DockerImageFunction
37
+ const DOCKER_CONTEXT_SYMBOL = Symbol.for("live-lambda:docker-context");
38
+ /**
39
+ * Map to store docker context paths captured from DockerImageCode.fromImageAsset
40
+ * Key is the DockerImageCode instance, value is the context path
41
+ */
42
+ const dockerImageCodeContextMap = new WeakMap();
43
+ /**
44
+ * Check if a module request is for aws-lambda-nodejs.
45
+ * We need to match:
46
+ * - "aws-cdk-lib/aws-lambda-nodejs" (direct import)
47
+ * - Paths ending with "/aws-lambda-nodejs" (resolved paths)
48
+ * - Paths containing "/aws-lambda-nodejs/" (submodule imports)
49
+ */
50
+ function isLambdaNodejsModule(request) {
51
+ return (request === "aws-cdk-lib/aws-lambda-nodejs" ||
52
+ request.endsWith("/aws-lambda-nodejs") ||
53
+ request.includes("/aws-lambda-nodejs/"));
54
+ }
55
+ /**
56
+ * Check if a module request is for aws-lambda (for DockerImageFunction).
57
+ * We need to match:
58
+ * - "aws-cdk-lib/aws-lambda" (direct import)
59
+ * - Paths ending with "/aws-lambda" (resolved paths)
60
+ * - Paths containing "/aws-lambda/" (submodule imports)
61
+ */
62
+ function isLambdaModule(request) {
63
+ // Be careful not to match aws-lambda-nodejs
64
+ if (request.includes("aws-lambda-nodejs")) {
65
+ return false;
66
+ }
67
+ return (request === "aws-cdk-lib/aws-lambda" ||
68
+ request.endsWith("/aws-lambda") ||
69
+ request.includes("/aws-lambda/"));
70
+ }
71
+ // Cache the lambda module for creating dummy code
72
+ let cachedLambdaModule = null;
73
+ /**
74
+ * Install hooks based on runtime environment.
75
+ *
76
+ * Bun notes:
77
+ * - Bun creates a *snapshot* of CommonJS named exports when importing from ESM.
78
+ * This means that mutating/replacing `module.exports.Foo` AFTER the ESM import
79
+ * was linked will not affect `import { Foo } from "..."` in the current process.
80
+ * - Therefore, Bun patching only works reliably when this bootstrap runs before
81
+ * the app entry point is loaded, e.g. via `bun --preload cdk-local-lambda/bootstrap`.
82
+ *
83
+ * Node.js:
84
+ * - We can patch Module._load to intercept module loading.
85
+ */
86
+ if (isBun) {
87
+ const isLiveMode = process.env.CDK_LIVE === "true";
88
+ // Best-effort patching for Bun. This is only guaranteed to work when this file
89
+ // is preloaded (see note above). Even then, we keep this logic lightweight.
90
+ if (isLiveMode) {
91
+ const hasPreloadFlag = process.execArgv.includes("--preload");
92
+ if (!hasPreloadFlag) {
93
+ console.warn("[LiveLambda] Warning: Running in Bun without --preload. Automatic handler/docker detection is likely disabled.");
94
+ console.warn("[LiveLambda] Fix: run Bun with `--preload cdk-local-lambda/bootstrap`.");
95
+ }
96
+ try {
97
+ // Patch aws-lambda first so NodejsFunction can create dummy Code.fromInline
98
+ // when CDK_LIVE=true (skips bundling).
99
+ const lambdaModule = requireFromProject("aws-cdk-lib/aws-lambda");
100
+ cachedLambdaModule = lambdaModule;
101
+ patchDockerImageFunction(lambdaModule);
102
+ const nodejsModule = requireFromProject("aws-cdk-lib/aws-lambda-nodejs");
103
+ patchNodejsFunction(nodejsModule);
104
+ }
105
+ catch (err) {
106
+ console.warn("[LiveLambda] Warning: Failed to install Bun patches:", err.message);
107
+ console.warn("[LiveLambda] Automatic handler/docker detection is required; ensure bootstrap is preloaded.");
108
+ console.warn("[LiveLambda] See: https://github.com/berenddeboer/cdk-local-lambda#bun-support");
109
+ }
110
+ }
111
+ }
112
+ else {
113
+ // Node.js: use Module._load hook to intercept module loading
114
+ const Module = requireFromPackage("node:module");
115
+ const originalLoad = Module._load;
116
+ Module._load = function (request, parent, isMain) {
117
+ // Call original load - let errors propagate naturally
118
+ const result = originalLoad.call(this, request, parent, isMain);
119
+ // Check if this is the lambda-nodejs module
120
+ if (isLambdaNodejsModule(request)) {
121
+ patchNodejsFunction(result);
122
+ }
123
+ // Check if this is the lambda module (for DockerImageFunction and Code.fromInline)
124
+ if (isLambdaModule(request)) {
125
+ // Cache the lambda module so we can use Code.fromInline in NodejsFunction patch
126
+ cachedLambdaModule = result;
127
+ patchDockerImageFunction(result);
128
+ }
129
+ return result;
130
+ };
131
+ }
132
+ /**
133
+ * Create a dummy inline code that does nothing.
134
+ * Used to skip bundling when CDK_LIVE=true.
135
+ */
136
+ function createDummyCode(lambdaModule) {
137
+ // Access lambda.Code.fromInline to create a no-op code
138
+ // This avoids bundling entirely since we provide pre-built code
139
+ const Code = lambdaModule.Code;
140
+ if (Code?.fromInline) {
141
+ return Code.fromInline("// Placeholder - replaced by LiveLambdaAspect");
142
+ }
143
+ return undefined;
144
+ }
145
+ /**
146
+ * Patch NodejsFunction to capture entry and handler props
147
+ */
148
+ function patchNodejsFunction(module) {
149
+ // If already patched, skip
150
+ if (module?.NodejsFunction?.__liveLambdaPatched) {
151
+ return;
152
+ }
153
+ // Check if we can patch
154
+ if (module?.NodejsFunction) {
155
+ const OriginalNodejsFunction = module.NodejsFunction;
156
+ const isLiveMode = process.env.CDK_LIVE === "true";
157
+ // Create wrapper class that captures entry/handler props
158
+ class NodejsFunctionWithCapture extends OriginalNodejsFunction {
159
+ constructor(scope, id, props = {}) {
160
+ // In live mode, provide dummy code to skip bundling entirely
161
+ // The aspect will replace this with the bridge code from S3
162
+ let modifiedProps = props;
163
+ if (isLiveMode && !props.code && cachedLambdaModule) {
164
+ const dummyCode = createDummyCode(cachedLambdaModule);
165
+ if (dummyCode) {
166
+ modifiedProps = { ...props, code: dummyCode };
167
+ }
168
+ }
169
+ super(scope, id, modifiedProps);
170
+ // Store the entry path on the instance (validate it's a non-empty string)
171
+ if (typeof props.entry === "string" && props.entry.trim().length > 0) {
172
+ ;
173
+ this[ENTRY_SYMBOL] =
174
+ props.entry;
175
+ }
176
+ // Store the handler name (validate and default to 'handler')
177
+ const handler = typeof props.handler === "string" && props.handler.trim().length > 0
178
+ ? props.handler
179
+ : "handler";
180
+ this[HANDLER_SYMBOL] = handler;
181
+ }
182
+ static __liveLambdaPatched = true;
183
+ }
184
+ // Try to replace - fail if we can't
185
+ try {
186
+ Object.defineProperty(module, "NodejsFunction", {
187
+ value: NodejsFunctionWithCapture,
188
+ writable: true,
189
+ configurable: true,
190
+ });
191
+ }
192
+ catch (err) {
193
+ console.error("[LiveLambda] FATAL: Cannot patch NodejsFunction - module is frozen or sealed.");
194
+ console.error("[LiveLambda] This can happen with certain bundlers or Node.js configurations.");
195
+ console.error("[LiveLambda] Error:", err.message);
196
+ process.exit(1);
197
+ }
198
+ }
199
+ }
200
+ /**
201
+ * Patch DockerImageFunction and DockerImageCode to capture docker context
202
+ */
203
+ function patchDockerImageFunction(module) {
204
+ if (!module)
205
+ return;
206
+ // First, patch DockerImageCode.fromImageAsset to capture the directory path
207
+ if (module.DockerImageCode && !module.DockerImageCode.__liveLambdaPatched) {
208
+ const OriginalDockerImageCode = module.DockerImageCode;
209
+ const originalFromImageAsset = OriginalDockerImageCode.fromImageAsset;
210
+ // Wrap fromImageAsset to capture the directory
211
+ const patchedFromImageAsset = (directory, props) => {
212
+ const result = originalFromImageAsset.call(OriginalDockerImageCode, directory, props);
213
+ // Store the directory path in the WeakMap, keyed by the result instance
214
+ dockerImageCodeContextMap.set(result, directory);
215
+ return result;
216
+ };
217
+ try {
218
+ Object.defineProperty(OriginalDockerImageCode, "fromImageAsset", {
219
+ value: patchedFromImageAsset,
220
+ writable: true,
221
+ configurable: true,
222
+ });
223
+ OriginalDockerImageCode.__liveLambdaPatched = true;
224
+ }
225
+ catch (err) {
226
+ console.warn("[LiveLambda] Could not patch DockerImageCode.fromImageAsset:", err.message);
227
+ }
228
+ }
229
+ // Then, patch DockerImageFunction to read from the WeakMap
230
+ if (module.DockerImageFunction &&
231
+ !module.DockerImageFunction.__liveLambdaPatched) {
232
+ const OriginalDockerImageFunction = module.DockerImageFunction;
233
+ // Create wrapper class that captures docker context
234
+ class DockerImageFunctionWithCapture extends OriginalDockerImageFunction {
235
+ constructor(scope, id, props) {
236
+ super(scope, id, props);
237
+ // Look up the docker context from the WeakMap
238
+ if (props.code) {
239
+ const contextPath = dockerImageCodeContextMap.get(props.code);
240
+ if (contextPath) {
241
+ ;
242
+ this[DOCKER_CONTEXT_SYMBOL] = contextPath;
243
+ }
244
+ }
245
+ }
246
+ static __liveLambdaPatched = true;
247
+ }
248
+ try {
249
+ Object.defineProperty(module, "DockerImageFunction", {
250
+ value: DockerImageFunctionWithCapture,
251
+ writable: true,
252
+ configurable: true,
253
+ });
254
+ }
255
+ catch (err) {
256
+ console.warn("[LiveLambda] Could not patch DockerImageFunction:", err.message);
257
+ }
258
+ }
259
+ }
260
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGl2ZS1sYW1iZGEtYm9vdHN0cmFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FzcGVjdC9saXZlLWxhbWJkYS1ib290c3RyYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUUzQyxNQUFNLGtCQUFrQixHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBRXpELDRFQUE0RTtBQUM1RSwwRUFBMEU7QUFDMUUsc0VBQXNFO0FBQ3RFLElBQUksa0JBQWtCLEdBQUcsa0JBQWtCLENBQUE7QUFDM0MsSUFBSSxDQUFDO0lBQ0gsa0JBQWtCLEdBQUcsYUFBYSxDQUFDLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxlQUFlLENBQUMsQ0FBQTtBQUNyRSxDQUFDO0FBQUMsTUFBTSxDQUFDO0lBQ1AsbURBQW1EO0FBQ3JELENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sS0FBSyxHQUFHLE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEtBQUssV0FBVyxDQUFBO0FBRXpELDZCQUE2QjtBQUM3QixNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUE7QUFDcEQsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFBO0FBRXhELGtDQUFrQztBQUNsQyxNQUFNLHFCQUFxQixHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLENBQUMsQ0FBQTtBQUV0RTs7O0dBR0c7QUFDSCxNQUFNLHlCQUF5QixHQUFHLElBQUksT0FBTyxFQUFrQixDQUFBO0FBRS9EOzs7Ozs7R0FNRztBQUNILFNBQVMsb0JBQW9CLENBQUMsT0FBZTtJQUMzQyxPQUFPLENBQ0wsT0FBTyxLQUFLLCtCQUErQjtRQUMzQyxPQUFP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LG9EQUFvRDtRQUNwRCxNQUFNLDhCQUErQixTQUFRLDJCQUEyQjtZQUN0RSxZQUFZLEtBQWMsRUFBRSxFQUFVLEVBQUUsS0FBK0I7Z0JBQ3JFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFBO2dCQUV2Qiw4Q0FBOEM7Z0JBQzlDLElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO29CQUNmLE1BQU0sV0FBVyxHQUFHLHlCQUF5QixDQUFDLEdBQUcsQ0FDL0MsS0FBSyxDQUFDLElBQWMsQ0FDckIsQ0FBQTtvQkFDRCxJQUFJLFdBQVcsRUFBRSxDQUFDO3dCQUNoQixDQUFDO3dCQUFDLElBQTBDLENBQzFDLHFCQUFxQixDQUN0QixHQUFHLFdBQVcsQ0FBQTtvQkFDakIsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELE1BQU0sQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUE7O1FBR25DLElBQUksQ0FBQztZQUNILE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLHFCQUFxQixFQUFFO2dCQUNuRCxLQUFLLEVBQUUsOEJBQThCO2dCQUNyQyxRQUFRLEVBQUUsSUFBSTtnQkFDZCxZQUFZLEVBQUUsSUFBSTthQUNuQixDQUFDLENBQUE7UUFDSixDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLE9BQU8sQ0FBQyxJQUFJLENBQ1YsbURBQW1ELEVBQ2xELEdBQWEsQ0FBQyxPQUFPLENBQ3ZCLENBQUE7UUFDSCxDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEJvb3RzdHJhcCBmaWxlIHRoYXQgaW5zdGFsbHMgaG9va3MgZm9yIE5vZGVqc0Z1bmN0aW9uIGFuZCBEb2NrZXJJbWFnZUZ1bmN0aW9uXG4gKiBCRUZPUkUgYW55IENESyBpbXBvcnRzLlxuICpcbiAqIFRoaXMgbXVzdCBiZSBpbXBvcnRlZCBhcyB0aGUgdmVyeSBmaXJzdCB0aGluZyBpbiB0aGUgQ0RLIGFwcCBlbnRyeSBwb2ludCxcbiAqIGJlZm9yZSBhbnkgb3RoZXIgaW1wb3J0cy5cbiAqXG4gKiBSdW50aW1lIHN1cHBvcnQ6XG4gKiAtIE5vZGUuanM6IHBhdGNoZXMgTW9kdWxlLl9sb2FkIHRvIGludGVyY2VwdCBtb2R1bGUgbG9hZGluZ1xuICogLSBCdW46IGRpcmVjdGx5IGltcG9ydHMgYW5kIHBhdGNoZXMgbW9kdWxlcyAoTW9kdWxlLl9sb2FkIG5vdCBzdXBwb3J0ZWQpXG4gKlxuICogSG9va3MgaW5zdGFsbGVkOlxuICogLSBOb2RlanNGdW5jdGlvbjogY2FwdHVyZXMgZW50cnkgYW5kIGhhbmRsZXIgcHJvcHNcbiAqIC0gRG9ja2VySW1hZ2VGdW5jdGlvbjogY2FwdHVyZXMgZG9ja2VyIGNvbnRleHQgcGF0aCBmcm9tIGNvZGUgcHJvcFxuICogLSBEb2NrZXJJbWFnZUNvZGUuZnJvbUltYWdlQXNzZXQ6IGNhcHR1cmVzIHRoZSBkaXJlY3RvcnkgcGF0aFxuICovXG5cbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIlxuXG5jb25zdCByZXF1aXJlRnJvbVBhY2thZ2UgPSBjcmVhdGVSZXF1aXJlKGltcG9ydC5tZXRhLnVybClcblxuLy8gUHJlZmVyIHJlc29sdmluZyBkZXBlbmRlbmNpZXMgZnJvbSB0aGUgKkNESyBhcHAgcHJvamVjdCogKHByb2Nlc3MuY3dkKCkpLlxuLy8gVGhpcyBhdm9pZHMgcGF0Y2hpbmcgYSBuZXN0ZWQgYXdzLWNkay1saWIgY29weSB3aGVuIGNkay1sb2NhbC1sYW1iZGEgaXNcbi8vIGluc3RhbGxlZCB3aXRoIGl0cyBvd24gbm9kZV9tb2R1bGVzIChjb21tb24gd2l0aCBwYWNrYWdlIG1hbmFnZXJzKS5cbmxldCByZXF1aXJlRnJvbVByb2plY3QgPSByZXF1aXJlRnJvbVBhY2thZ2VcbnRyeSB7XG4gIHJlcXVpcmVGcm9tUHJvamVjdCA9IGNyZWF0ZVJlcXVpcmUoYCR7cHJvY2Vzcy5jd2QoKX0vcGFja2FnZS5qc29uYClcbn0gY2F0Y2gge1xuICAvLyBGYWxsIGJhY2sgdG8gcmVzb2x2aW5nIHJlbGF0aXZlIHRvIHRoaXMgcGFja2FnZS5cbn1cblxuLyoqXG4gKiBEZXRlY3QgaWYgd2UncmUgcnVubmluZyBpbiBCdW4gcnVudGltZVxuICovXG5jb25zdCBpc0J1biA9IHR5cGVvZiBwcm9jZXNzLnZlcnNpb25zLmJ1biAhPT0gXCJ1bmRlZmluZWRcIlxuXG4vLyBTeW1ib2xzIGZvciBOb2RlanNGdW5jdGlvblxuY29uc3QgRU5UUllfU1lNQk9MID0gU3ltYm9sLmZvcihcImxpdmUtbGFtYmRhOmVudHJ5XCIpXG5jb25zdCBIQU5ETEVSX1NZTUJPTCA9IFN5bWJvbC5mb3IoXCJsaXZlLWxhbWJkYTpoYW5kbGVyXCIpXG5cbi8vIFN5bWJvbHMgZm9yIERvY2tlckltYWdlRnVuY3Rpb25cbmNvbnN0IERPQ0tFUl9DT05URVhUX1NZTUJPTCA9IFN5bWJvbC5mb3IoXCJsaXZlLWxhbWJkYTpkb2NrZXItY29udGV4dFwiKVxuXG4vKipcbiAqIE1hcCB0byBzdG9yZSBkb2NrZXIgY29udGV4dCBwYXRocyBjYXB0dXJlZCBmcm9tIERvY2tlckltYWdlQ29kZS5mcm9tSW1hZ2VBc3NldFxuICogS2V5IGlzIHRoZSBEb2NrZXJJbWFnZUNvZGUgaW5zdGFuY2UsIHZhbHVlIGlzIHRoZSBjb250ZXh0IHBhdGhcbiAqL1xuY29uc3QgZG9ja2VySW1hZ2VDb2RlQ29udGV4dE1hcCA9IG5ldyBXZWFrTWFwPG9iamVjdCwgc3RyaW5nPigpXG5cbi8qKlxuICogQ2hlY2sgaWYgYSBtb2R1bGUgcmVxdWVzdCBpcyBmb3IgYXdzLWxhbWJkYS1ub2RlanMuXG4gKiBXZSBuZWVkIHRvIG1hdGNoOlxuICogLSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGEtbm9kZWpzXCIgKGRpcmVjdCBpbXBvcnQpXG4gKiAtIFBhdGhzIGVuZGluZyB3aXRoIFwiL2F3cy1sYW1iZGEtbm9kZWpzXCIgKHJlc29sdmVkIHBhdGhzKVxuICogLSBQYXRocyBjb250YWluaW5nIFwiL2F3cy1sYW1iZGEtbm9kZWpzL1wiIChzdWJtb2R1bGUgaW1wb3J0cylcbiAqL1xuZnVuY3Rpb24gaXNMYW1iZGFOb2RlanNNb2R1bGUocmVxdWVzdDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgcmVxdWVzdCA9PT0gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhLW5vZGVqc1wiIHx8XG4gICAgcmVxdWVzdC5lbmRzV2l0aChcIi9hd3MtbGFtYmRhLW5vZGVqc1wiKSB8fFxuICAgIHJlcXVlc3QuaW5jbHVkZXMoXCIvYXdzLWxhbWJkYS1ub2RlanMvXCIpXG4gIClcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhIG1vZHVsZSByZXF1ZXN0IGlzIGZvciBhd3MtbGFtYmRhIChmb3IgRG9ja2VySW1hZ2VGdW5jdGlvbikuXG4gKiBXZSBuZWVkIHRvIG1hdGNoOlxuICogLSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIiAoZGlyZWN0IGltcG9ydClcbiAqIC0gUGF0aHMgZW5kaW5nIHdpdGggXCIvYXdzLWxhbWJkYVwiIChyZXNvbHZlZCBwYXRocylcbiAqIC0gUGF0aHMgY29udGFpbmluZyBcIi9hd3MtbGFtYmRhL1wiIChzdWJtb2R1bGUgaW1wb3J0cylcbiAqL1xuZnVuY3Rpb24gaXNMYW1iZGFNb2R1bGUocmVxdWVzdDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIC8vIEJlIGNhcmVmdWwgbm90IHRvIG1hdGNoIGF3cy1sYW1iZGEtbm9kZWpzXG4gIGlmIChyZXF1ZXN0LmluY2x1ZGVzKFwiYXdzLWxhbWJkYS1ub2RlanNcIikpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICByZXR1cm4gKFxuICAgIHJlcXVlc3QgPT09IFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiIHx8XG4gICAgcmVxdWVzdC5lbmRzV2l0aChcIi9hd3MtbGFtYmRhXCIpIHx8XG4gICAgcmVxdWVzdC5pbmNsdWRlcyhcIi9hd3MtbGFtYmRhL1wiKVxuICApXG59XG5cbi8vIE1vZHVsZSB0eXBlIGZvciB0aGUgbGFtYmRhLW5vZGVqcyBleHBvcnRzXG5pbnRlcmZhY2UgTGFtYmRhTm9kZWpzTW9kdWxlIHtcbiAgTm9kZWpzRnVuY3Rpb246IE5vZGVqc0Z1bmN0aW9uQ29uc3RydWN0b3IgJiB7XG4gICAgX19saXZlTGFtYmRhUGF0Y2hlZD86IGJvb2xlYW5cbiAgfVxufVxuXG4vLyBDb25zdHJ1Y3RvciB0eXBlIHRoYXQgY2FuIGJlIGV4dGVuZGVkXG5pbnRlcmZhY2UgTm9kZWpzRnVuY3Rpb25Db25zdHJ1Y3RvciB7XG4gIG5ldyAoXG4gICAgc2NvcGU6IHVua25vd24sXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wcz86IE5vZGVqc0Z1bmN0aW9uUHJvcHMsXG4gICk6IE5vZGVqc0Z1bmN0aW9uSW5zdGFuY2VcbiAgcHJvdG90eXBlOiBOb2RlanNGdW5jdGlvbkluc3RhbmNlXG59XG5cbmludGVyZmFjZSBOb2RlanNGdW5jdGlvbkluc3RhbmNlIHtcbiAgbm9kZTogeyBhZGRyOiBzdHJpbmcgfVxufVxuXG5pbnRlcmZhY2UgTm9kZWpzRnVuY3Rpb25Qcm9wcyB7XG4gIGVudHJ5Pzogc3RyaW5nXG4gIGhhbmRsZXI/OiBzdHJpbmdcbiAgY29kZT86IHVua25vd24gLy8gbGFtYmRhLkNvZGUgLSBpZiBwcm92aWRlZCwgYnVuZGxpbmcgaXMgc2tpcHBlZFxufVxuXG4vLyBNb2R1bGUgdHlwZSBmb3IgdGhlIGxhbWJkYSBleHBvcnRzXG5pbnRlcmZhY2UgTGFtYmRhTW9kdWxlIHtcbiAgRG9ja2VySW1hZ2VGdW5jdGlvbjogRG9ja2VySW1hZ2VGdW5jdGlvbkNvbnN0cnVjdG9yICYge1xuICAgIF9fbGl2ZUxhbWJkYVBhdGNoZWQ/OiBib29sZWFuXG4gIH1cbiAgRG9ja2VySW1hZ2VDb2RlOiBEb2NrZXJJbWFnZUNvZGVTdGF0aWMgJiB7XG4gICAgX19saXZlTGFtYmRhUGF0Y2hlZD86IGJvb2xlYW5cbiAgfVxufVxuXG4vLyBEb2NrZXJJbWFnZUZ1bmN0aW9uIGNvbnN0cnVjdG9yIHR5cGVcbmludGVyZmFjZSBEb2NrZXJJbWFnZUZ1bmN0aW9uQ29uc3RydWN0b3Ige1xuICBuZXcgKFxuICAgIHNjb3BlOiB1bmtub3duLFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IERvY2tlckltYWdlRnVuY3Rpb25Qcm9wcyxcbiAgKTogRG9ja2VySW1hZ2VGdW5jdGlvbkluc3RhbmNlXG4gIHByb3RvdHlwZTogRG9ja2VySW1hZ2VGdW5jdGlvbkluc3RhbmNlXG59XG5cbmludGVyZmFjZSBEb2NrZXJJbWFnZUZ1bmN0aW9uSW5zdGFuY2Uge1xuICBub2RlOiB7IGFkZHI6IHN0cmluZyB9XG59XG5cbmludGVyZmFjZSBEb2NrZXJJbWFnZUZ1bmN0aW9uUHJvcHMge1xuICBjb2RlOiBEb2NrZXJJbWFnZUNvZGVJbnN0YW5jZVxuICBba2V5OiBzdHJpbmddOiB1bmtub3duXG59XG5cbi8vIERvY2tlckltYWdlQ29kZSBzdGF0aWMgdHlwZVxuaW50ZXJmYWNlIERvY2tlckltYWdlQ29kZVN0YXRpYyB7XG4gIGZyb21JbWFnZUFzc2V0KFxuICAgIGRpcmVjdG9yeTogc3RyaW5nLFxuICAgIHByb3BzPzogRG9ja2VySW1hZ2VBc3NldFByb3BzLFxuICApOiBEb2NrZXJJbWFnZUNvZGVJbnN0YW5jZVxufVxuXG5pbnRlcmZhY2UgRG9ja2VySW1hZ2VDb2RlSW5zdGFuY2Uge1xuICAvLyBNYXJrZXIgdG8gaWRlbnRpZnkgZG9ja2VyIGltYWdlIGNvZGUgaW5zdGFuY2VzXG4gIF9faXNEb2NrZXJJbWFnZUNvZGU/OiBib29sZWFuXG59XG5cbmludGVyZmFjZSBEb2NrZXJJbWFnZUFzc2V0UHJvcHMge1xuICBmaWxlPzogc3RyaW5nXG4gIGNtZD86IHN0cmluZ1tdXG4gIFtrZXk6IHN0cmluZ106IHVua25vd25cbn1cblxuLy8gQ2FjaGUgdGhlIGxhbWJkYSBtb2R1bGUgZm9yIGNyZWF0aW5nIGR1bW15IGNvZGVcbmxldCBjYWNoZWRMYW1iZGFNb2R1bGU6IExhbWJkYU1vZHVsZSB8IG51bGwgPSBudWxsXG5cbi8qKlxuICogSW5zdGFsbCBob29rcyBiYXNlZCBvbiBydW50aW1lIGVudmlyb25tZW50LlxuICpcbiAqIEJ1biBub3RlczpcbiAqIC0gQnVuIGNyZWF0ZXMgYSAqc25hcHNob3QqIG9mIENvbW1vbkpTIG5hbWVkIGV4cG9ydHMgd2hlbiBpbXBvcnRpbmcgZnJvbSBFU00uXG4gKiAgIFRoaXMgbWVhbnMgdGhhdCBtdXRhdGluZy9yZXBsYWNpbmcgYG1vZHVsZS5leHBvcnRzLkZvb2AgQUZURVIgdGhlIEVTTSBpbXBvcnRcbiAqICAgd2FzIGxpbmtlZCB3aWxsIG5vdCBhZmZlY3QgYGltcG9ydCB7IEZvbyB9IGZyb20gXCIuLi5cImAgaW4gdGhlIGN1cnJlbnQgcHJvY2Vzcy5cbiAqIC0gVGhlcmVmb3JlLCBCdW4gcGF0Y2hpbmcgb25seSB3b3JrcyByZWxpYWJseSB3aGVuIHRoaXMgYm9vdHN0cmFwIHJ1bnMgYmVmb3JlXG4gKiAgIHRoZSBhcHAgZW50cnkgcG9pbnQgaXMgbG9hZGVkLCBlLmcuIHZpYSBgYnVuIC0tcHJlbG9hZCBjZGstbG9jYWwtbGFtYmRhL2Jvb3RzdHJhcGAuXG4gKlxuICogTm9kZS5qczpcbiAqIC0gV2UgY2FuIHBhdGNoIE1vZHVsZS5fbG9hZCB0byBpbnRlcmNlcHQgbW9kdWxlIGxvYWRpbmcuXG4gKi9cbmlmIChpc0J1bikge1xuICBjb25zdCBpc0xpdmVNb2RlID0gcHJvY2Vzcy5lbnYuQ0RLX0xJVkUgPT09IFwidHJ1ZVwiXG5cbiAgLy8gQmVzdC1lZmZvcnQgcGF0Y2hpbmcgZm9yIEJ1bi4gVGhpcyBpcyBvbmx5IGd1YXJhbnRlZWQgdG8gd29yayB3aGVuIHRoaXMgZmlsZVxuICAvLyBpcyBwcmVsb2FkZWQgKHNlZSBub3RlIGFib3ZlKS4gRXZlbiB0aGVuLCB3ZSBrZWVwIHRoaXMgbG9naWMgbGlnaHR3ZWlnaHQuXG4gIGlmIChpc0xpdmVNb2RlKSB7XG4gICAgY29uc3QgaGFzUHJlbG9hZEZsYWcgPSBwcm9jZXNzLmV4ZWNBcmd2LmluY2x1ZGVzKFwiLS1wcmVsb2FkXCIpXG5cbiAgICBpZiAoIWhhc1ByZWxvYWRGbGFnKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIFwiW0xpdmVMYW1iZGFdIFdhcm5pbmc6IFJ1bm5pbmcgaW4gQnVuIHdpdGhvdXQgLS1wcmVsb2FkLiBBdXRvbWF0aWMgaGFuZGxlci9kb2NrZXIgZGV0ZWN0aW9uIGlzIGxpa2VseSBkaXNhYmxlZC5cIixcbiAgICAgIClcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgXCJbTGl2ZUxhbWJkYV0gRml4OiBydW4gQnVuIHdpdGggYC0tcHJlbG9hZCBjZGstbG9jYWwtbGFtYmRhL2Jvb3RzdHJhcGAuXCIsXG4gICAgICApXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFBhdGNoIGF3cy1sYW1iZGEgZmlyc3Qgc28gTm9kZWpzRnVuY3Rpb24gY2FuIGNyZWF0ZSBkdW1teSBDb2RlLmZyb21JbmxpbmVcbiAgICAgIC8vIHdoZW4gQ0RLX0xJVkU9dHJ1ZSAoc2tpcHMgYnVuZGxpbmcpLlxuICAgICAgY29uc3QgbGFtYmRhTW9kdWxlID0gcmVxdWlyZUZyb21Qcm9qZWN0KFxuICAgICAgICBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIixcbiAgICAgICkgYXMgTGFtYmRhTW9kdWxlXG4gICAgICBjYWNoZWRMYW1iZGFNb2R1bGUgPSBsYW1iZGFNb2R1bGVcbiAgICAgIHBhdGNoRG9ja2VySW1hZ2VGdW5jdGlvbihsYW1iZGFNb2R1bGUpXG5cbiAgICAgIGNvbnN0IG5vZGVqc01vZHVsZSA9IHJlcXVpcmVGcm9tUHJvamVjdChcbiAgICAgICAgXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhLW5vZGVqc1wiLFxuICAgICAgKSBhcyBMYW1iZGFOb2RlanNNb2R1bGVcbiAgICAgIHBhdGNoTm9kZWpzRnVuY3Rpb24obm9kZWpzTW9kdWxlKVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBcIltMaXZlTGFtYmRhXSBXYXJuaW5nOiBGYWlsZWQgdG8gaW5zdGFsbCBCdW4gcGF0Y2hlczpcIixcbiAgICAgICAgKGVyciBhcyBFcnJvcikubWVzc2FnZSxcbiAgICAgIClcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgXCJbTGl2ZUxhbWJkYV0gQXV0b21hdGljIGhhbmRsZXIvZG9ja2VyIGRldGVjdGlvbiBpcyByZXF1aXJlZDsgZW5zdXJlIGJvb3RzdHJhcCBpcyBwcmVsb2FkZWQuXCIsXG4gICAgICApXG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIFwiW0xpdmVMYW1iZGFdIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JlcmVuZGRlYm9lci9jZGstbG9jYWwtbGFtYmRhI2J1bi1zdXBwb3J0XCIsXG4gICAgICApXG4gICAgfVxuICB9XG59IGVsc2Uge1xuICAvLyBOb2RlLmpzOiB1c2UgTW9kdWxlLl9sb2FkIGhvb2sgdG8gaW50ZXJjZXB0IG1vZHVsZSBsb2FkaW5nXG4gIGNvbnN0IE1vZHVsZSA9IHJlcXVpcmVGcm9tUGFja2FnZShcIm5vZGU6bW9kdWxlXCIpXG4gIGNvbnN0IG9yaWdpbmFsTG9hZDogKFxuICAgIHJlcXVlc3Q6IHN0cmluZyxcbiAgICBwYXJlbnQ6IE5vZGVNb2R1bGUgfCB1bmRlZmluZWQsXG4gICAgaXNNYWluOiBib29sZWFuLFxuICApID0+IHVua25vd24gPSBNb2R1bGUuX2xvYWRcblxuICBNb2R1bGUuX2xvYWQgPSBmdW5jdGlvbiAoXG4gICAgcmVxdWVzdDogc3RyaW5nLFxuICAgIHBhcmVudDogTm9kZU1vZHVsZSB8IHVuZGVmaW5lZCxcbiAgICBpc01haW46IGJvb2xlYW4sXG4gICk6IHVua25vd24ge1xuICAgIC8vIENhbGwgb3JpZ2luYWwgbG9hZCAtIGxldCBlcnJvcnMgcHJvcGFnYXRlIG5hdHVyYWxseVxuICAgIGNvbnN0IHJlc3VsdCA9IG9yaWdpbmFsTG9hZC5jYWxsKHRoaXMsIHJlcXVlc3QsIHBhcmVudCwgaXNNYWluKVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyB0aGUgbGFtYmRhLW5vZGVqcyBtb2R1bGVcbiAgICBpZiAoaXNMYW1iZGFOb2RlanNNb2R1bGUocmVxdWVzdCkpIHtcbiAgICAgIHBhdGNoTm9kZWpzRnVuY3Rpb24ocmVzdWx0IGFzIExhbWJkYU5vZGVqc01vZHVsZSB8IG51bGwpXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyB0aGUgbGFtYmRhIG1vZHVsZSAoZm9yIERvY2tlckltYWdlRnVuY3Rpb24gYW5kIENvZGUuZnJvbUlubGluZSlcbiAgICBpZiAoaXNMYW1iZGFNb2R1bGUocmVxdWVzdCkpIHtcbiAgICAgIC8vIENhY2hlIHRoZSBsYW1iZGEgbW9kdWxlIHNvIHdlIGNhbiB1c2UgQ29kZS5mcm9tSW5saW5lIGluIE5vZGVqc0Z1bmN0aW9uIHBhdGNoXG4gICAgICBjYWNoZWRMYW1iZGFNb2R1bGUgPSByZXN1bHQgYXMgTGFtYmRhTW9kdWxlIHwgbnVsbFxuICAgICAgcGF0Y2hEb2NrZXJJbWFnZUZ1bmN0aW9uKHJlc3VsdCBhcyBMYW1iZGFNb2R1bGUgfCBudWxsKVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZSBhIGR1bW15IGlubGluZSBjb2RlIHRoYXQgZG9lcyBub3RoaW5nLlxuICogVXNlZCB0byBza2lwIGJ1bmRsaW5nIHdoZW4gQ0RLX0xJVkU9dHJ1ZS5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRHVtbXlDb2RlKGxhbWJkYU1vZHVsZTogTGFtYmRhTW9kdWxlKTogdW5rbm93biB7XG4gIC8vIEFjY2VzcyBsYW1iZGEuQ29kZS5mcm9tSW5saW5lIHRvIGNyZWF0ZSBhIG5vLW9wIGNvZGVcbiAgLy8gVGhpcyBhdm9pZHMgYnVuZGxpbmcgZW50aXJlbHkgc2luY2Ugd2UgcHJvdmlkZSBwcmUtYnVpbHQgY29kZVxuICBjb25zdCBDb2RlID0gKFxuICAgIGxhbWJkYU1vZHVsZSBhcyB1bmtub3duIGFzIHtcbiAgICAgIENvZGU/OiB7IGZyb21JbmxpbmU/OiAoY29kZTogc3RyaW5nKSA9PiB1bmtub3duIH1cbiAgICB9XG4gICkuQ29kZVxuICBpZiAoQ29kZT8uZnJvbUlubGluZSkge1xuICAgIHJldHVybiBDb2RlLmZyb21JbmxpbmUoXCIvLyBQbGFjZWhvbGRlciAtIHJlcGxhY2VkIGJ5IExpdmVMYW1iZGFBc3BlY3RcIilcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogUGF0Y2ggTm9kZWpzRnVuY3Rpb24gdG8gY2FwdHVyZSBlbnRyeSBhbmQgaGFuZGxlciBwcm9wc1xuICovXG5mdW5jdGlvbiBwYXRjaE5vZGVqc0Z1bmN0aW9uKG1vZHVsZTogTGFtYmRhTm9kZWpzTW9kdWxlIHwgbnVsbCk6IHZvaWQge1xuICAvLyBJZiBhbHJlYWR5IHBhdGNoZWQsIHNraXBcbiAgaWYgKG1vZHVsZT8uTm9kZWpzRnVuY3Rpb24/Ll9fbGl2ZUxhbWJkYVBhdGNoZWQpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIC8vIENoZWNrIGlmIHdlIGNhbiBwYXRjaFxuICBpZiAobW9kdWxlPy5Ob2RlanNGdW5jdGlvbikge1xuICAgIGNvbnN0IE9yaWdpbmFsTm9kZWpzRnVuY3Rpb24gPSBtb2R1bGUuTm9kZWpzRnVuY3Rpb25cbiAgICBjb25zdCBpc0xpdmVNb2RlID0gcHJvY2Vzcy5lbnYuQ0RLX0xJVkUgPT09IFwidHJ1ZVwiXG5cbiAgICAvLyBDcmVhdGUgd3JhcHBlciBjbGFzcyB0aGF0IGNhcHR1cmVzIGVudHJ5L2hhbmRsZXIgcHJvcHNcbiAgICBjbGFzcyBOb2RlanNGdW5jdGlvbldpdGhDYXB0dXJlIGV4dGVuZHMgT3JpZ2luYWxOb2RlanNGdW5jdGlvbiB7XG4gICAgICBjb25zdHJ1Y3RvcihzY29wZTogdW5rbm93biwgaWQ6IHN0cmluZywgcHJvcHM6IE5vZGVqc0Z1bmN0aW9uUHJvcHMgPSB7fSkge1xuICAgICAgICAvLyBJbiBsaXZlIG1vZGUsIHByb3ZpZGUgZHVtbXkgY29kZSB0byBza2lwIGJ1bmRsaW5nIGVudGlyZWx5XG4gICAgICAgIC8vIFRoZSBhc3BlY3Qgd2lsbCByZXBsYWNlIHRoaXMgd2l0aCB0aGUgYnJpZGdlIGNvZGUgZnJvbSBTM1xuICAgICAgICBsZXQgbW9kaWZpZWRQcm9wcyA9IHByb3BzXG4gICAgICAgIGlmIChpc0xpdmVNb2RlICYmICFwcm9wcy5jb2RlICYmIGNhY2hlZExhbWJkYU1vZHVsZSkge1xuICAgICAgICAgIGNvbnN0IGR1bW15Q29kZSA9IGNyZWF0ZUR1bW15Q29kZShjYWNoZWRMYW1iZGFNb2R1bGUpXG4gICAgICAgICAgaWYgKGR1bW15Q29kZSkge1xuICAgICAgICAgICAgbW9kaWZpZWRQcm9wcyA9IHsgLi4ucHJvcHMsIGNvZGU6IGR1bW15Q29kZSB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCBtb2RpZmllZFByb3BzKVxuXG4gICAgICAgIC8vIFN0b3JlIHRoZSBlbnRyeSBwYXRoIG9uIHRoZSBpbnN0YW5jZSAodmFsaWRhdGUgaXQncyBhIG5vbi1lbXB0eSBzdHJpbmcpXG4gICAgICAgIGlmICh0eXBlb2YgcHJvcHMuZW50cnkgPT09IFwic3RyaW5nXCIgJiYgcHJvcHMuZW50cnkudHJpbSgpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICA7KHRoaXMgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3ltYm9sLCBzdHJpbmc+KVtFTlRSWV9TWU1CT0xdID1cbiAgICAgICAgICAgIHByb3BzLmVudHJ5XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTdG9yZSB0aGUgaGFuZGxlciBuYW1lICh2YWxpZGF0ZSBhbmQgZGVmYXVsdCB0byAnaGFuZGxlcicpXG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPVxuICAgICAgICAgIHR5cGVvZiBwcm9wcy5oYW5kbGVyID09PSBcInN0cmluZ1wiICYmIHByb3BzLmhhbmRsZXIudHJpbSgpLmxlbmd0aCA+IDBcbiAgICAgICAgICAgID8gcHJvcHMuaGFuZGxlclxuICAgICAgICAgICAgOiBcImhhbmRsZXJcIlxuICAgICAgICA7KHRoaXMgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3ltYm9sLCBzdHJpbmc+KVtIQU5ETEVSX1NZTUJPTF0gPSBoYW5kbGVyXG4gICAgICB9XG5cbiAgICAgIHN0YXRpYyBfX2xpdmVMYW1iZGFQYXRjaGVkID0gdHJ1ZVxuICAgIH1cblxuICAgIC8vIFRyeSB0byByZXBsYWNlIC0gZmFpbCBpZiB3ZSBjYW4ndFxuICAgIHRyeSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLCBcIk5vZGVqc0Z1bmN0aW9uXCIsIHtcbiAgICAgICAgdmFsdWU6IE5vZGVqc0Z1bmN0aW9uV2l0aENhcHR1cmUsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9KVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgXCJbTGl2ZUxhbWJkYV0gRkFUQUw6IENhbm5vdCBwYXRjaCBOb2RlanNGdW5jdGlvbiAtIG1vZHVsZSBpcyBmcm96ZW4gb3Igc2VhbGVkLlwiLFxuICAgICAgKVxuICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgXCJbTGl2ZUxhbWJkYV0gVGhpcyBjYW4gaGFwcGVuIHdpdGggY2VydGFpbiBidW5kbGVycyBvciBOb2RlLmpzIGNvbmZpZ3VyYXRpb25zLlwiLFxuICAgICAgKVxuICAgICAgY29uc29sZS5lcnJvcihcIltMaXZlTGFtYmRhXSBFcnJvcjpcIiwgKGVyciBhcyBFcnJvcikubWVzc2FnZSlcbiAgICAgIHByb2Nlc3MuZXhpdCgxKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFBhdGNoIERvY2tlckltYWdlRnVuY3Rpb24gYW5kIERvY2tlckltYWdlQ29kZSB0byBjYXB0dXJlIGRvY2tlciBjb250ZXh0XG4gKi9cbmZ1bmN0aW9uIHBhdGNoRG9ja2VySW1hZ2VGdW5jdGlvbihtb2R1bGU6IExhbWJkYU1vZHVsZSB8IG51bGwpOiB2b2lkIHtcbiAgaWYgKCFtb2R1bGUpIHJldHVyblxuXG4gIC8vIEZpcnN0LCBwYXRjaCBEb2NrZXJJbWFnZUNvZGUuZnJvbUltYWdlQXNzZXQgdG8gY2FwdHVyZSB0aGUgZGlyZWN0b3J5IHBhdGhcbiAgaWYgKG1vZHVsZS5Eb2NrZXJJbWFnZUNvZGUgJiYgIW1vZHVsZS5Eb2NrZXJJbWFnZUNvZGUuX19saXZlTGFtYmRhUGF0Y2hlZCkge1xuICAgIGNvbnN0IE9yaWdpbmFsRG9ja2VySW1hZ2VDb2RlID0gbW9kdWxlLkRvY2tlckltYWdlQ29kZVxuICAgIGNvbnN0IG9yaWdpbmFsRnJvbUltYWdlQXNzZXQgPSBPcmlnaW5hbERvY2tlckltYWdlQ29kZS5mcm9tSW1hZ2VBc3NldFxuXG4gICAgLy8gV3JhcCBmcm9tSW1hZ2VBc3NldCB0byBjYXB0dXJlIHRoZSBkaXJlY3RvcnlcbiAgICBjb25zdCBwYXRjaGVkRnJvbUltYWdlQXNzZXQgPSAoXG4gICAgICBkaXJlY3Rvcnk6IHN0cmluZyxcbiAgICAgIHByb3BzPzogRG9ja2VySW1hZ2VBc3NldFByb3BzLFxuICAgICk6IERvY2tlckltYWdlQ29kZUluc3RhbmNlID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IG9yaWdpbmFsRnJvbUltYWdlQXNzZXQuY2FsbChcbiAgICAgICAgT3JpZ2luYWxEb2NrZXJJbWFnZUNvZGUsXG4gICAgICAgIGRpcmVjdG9yeSxcbiAgICAgICAgcHJvcHMsXG4gICAgICApXG5cbiAgICAgIC8vIFN0b3JlIHRoZSBkaXJlY3RvcnkgcGF0aCBpbiB0aGUgV2Vha01hcCwga2V5ZWQgYnkgdGhlIHJlc3VsdCBpbnN0YW5jZVxuICAgICAgZG9ja2VySW1hZ2VDb2RlQ29udGV4dE1hcC5zZXQocmVzdWx0IGFzIG9iamVjdCwgZGlyZWN0b3J5KVxuXG4gICAgICByZXR1cm4gcmVzdWx0XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPcmlnaW5hbERvY2tlckltYWdlQ29kZSwgXCJmcm9tSW1hZ2VBc3NldFwiLCB7XG4gICAgICAgIHZhbHVlOiBwYXRjaGVkRnJvbUltYWdlQXNzZXQsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9KVxuICAgICAgOyhcbiAgICAgICAgT3JpZ2luYWxEb2NrZXJJbWFnZUNvZGUgYXMgRG9ja2VySW1hZ2VDb2RlU3RhdGljICYge1xuICAgICAgICAgIF9fbGl2ZUxhbWJkYVBhdGNoZWQ/OiBib29sZWFuXG4gICAgICAgIH1cbiAgICAgICkuX19saXZlTGFtYmRhUGF0Y2hlZCA9IHRydWVcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgXCJbTGl2ZUxhbWJkYV0gQ291bGQgbm90IHBhdGNoIERvY2tlckltYWdlQ29kZS5mcm9tSW1hZ2VBc3NldDpcIixcbiAgICAgICAgKGVyciBhcyBFcnJvcikubWVzc2FnZSxcbiAgICAgIClcbiAgICB9XG4gIH1cblxuICAvLyBUaGVuLCBwYXRjaCBEb2NrZXJJbWFnZUZ1bmN0aW9uIHRvIHJlYWQgZnJvbSB0aGUgV2Vha01hcFxuICBpZiAoXG4gICAgbW9kdWxlLkRvY2tlckltYWdlRnVuY3Rpb24gJiZcbiAgICAhbW9kdWxlLkRvY2tlckltYWdlRnVuY3Rpb24uX19saXZlTGFtYmRhUGF0Y2hlZFxuICApIHtcbiAgICBjb25zdCBPcmlnaW5hbERvY2tlckltYWdlRnVuY3Rpb24gPSBtb2R1bGUuRG9ja2VySW1hZ2VGdW5jdGlvblxuXG4gICAgLy8gQ3JlYXRlIHdyYXBwZXIgY2xhc3MgdGhhdCBjYXB0dXJlcyBkb2NrZXIgY29udGV4dFxuICAgIGNsYXNzIERvY2tlckltYWdlRnVuY3Rpb25XaXRoQ2FwdHVyZSBleHRlbmRzIE9yaWdpbmFsRG9ja2VySW1hZ2VGdW5jdGlvbiB7XG4gICAgICBjb25zdHJ1Y3RvcihzY29wZTogdW5rbm93biwgaWQ6IHN0cmluZywgcHJvcHM6IERvY2tlckltYWdlRnVuY3Rpb25Qcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKVxuXG4gICAgICAgIC8vIExvb2sgdXAgdGhlIGRvY2tlciBjb250ZXh0IGZyb20gdGhlIFdlYWtNYXBcbiAgICAgICAgaWYgKHByb3BzLmNvZGUpIHtcbiAgICAgICAgICBjb25zdCBjb250ZXh0UGF0aCA9IGRvY2tlckltYWdlQ29kZUNvbnRleHRNYXAuZ2V0KFxuICAgICAgICAgICAgcHJvcHMuY29kZSBhcyBvYmplY3QsXG4gICAgICAgICAgKVxuICAgICAgICAgIGlmIChjb250ZXh0UGF0aCkge1xuICAgICAgICAgICAgOyh0aGlzIGFzIHVua25vd24gYXMgUmVjb3JkPHN5bWJvbCwgc3RyaW5nPilbXG4gICAgICAgICAgICAgIERPQ0tFUl9DT05URVhUX1NZTUJPTFxuICAgICAgICAgICAgXSA9IGNvbnRleHRQYXRoXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHN0YXRpYyBfX2xpdmVMYW1iZGFQYXRjaGVkID0gdHJ1ZVxuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLCBcIkRvY2tlckltYWdlRnVuY3Rpb25cIiwge1xuICAgICAgICB2YWx1ZTogRG9ja2VySW1hZ2VGdW5jdGlvbldpdGhDYXB0dXJlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgfSlcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgXCJbTGl2ZUxhbWJkYV0gQ291bGQgbm90IHBhdGNoIERvY2tlckltYWdlRnVuY3Rpb246XCIsXG4gICAgICAgIChlcnIgYXMgRXJyb3IpLm1lc3NhZ2UsXG4gICAgICApXG4gICAgfVxuICB9XG59XG4iXX0=
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Functions to retrieve captured entry path and handler name from Lambda functions
3
+ * that were created with NodejsFunction.
4
+ *
5
+ * The live-lambda-bootstrap.ts file installs a hook that captures these values
6
+ * when NodejsFunction instances are created.
7
+ */
8
+ import type * as lambda from "aws-cdk-lib/aws-lambda";
9
+ /**
10
+ * Get the entry path that was passed to NodejsFunction constructor.
11
+ * Returns undefined if the function was not created with NodejsFunction
12
+ * or if the hook was not installed.
13
+ */
14
+ export declare function getEntryPath(fn: lambda.Function): string | undefined;
15
+ /**
16
+ * Get the handler name that was passed to NodejsFunction constructor.
17
+ * Returns undefined if the function was not created with NodejsFunction
18
+ * or if the hook was not installed.
19
+ */
20
+ export declare function getHandlerName(fn: lambda.Function): string | undefined;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Functions to retrieve captured entry path and handler name from Lambda functions
3
+ * that were created with NodejsFunction.
4
+ *
5
+ * The live-lambda-bootstrap.ts file installs a hook that captures these values
6
+ * when NodejsFunction instances are created.
7
+ */
8
+ // Symbols used by the bootstrap hook to store captured values
9
+ const ENTRY_SYMBOL = Symbol.for("live-lambda:entry");
10
+ const HANDLER_SYMBOL = Symbol.for("live-lambda:handler");
11
+ /**
12
+ * Get the entry path that was passed to NodejsFunction constructor.
13
+ * Returns undefined if the function was not created with NodejsFunction
14
+ * or if the hook was not installed.
15
+ */
16
+ export function getEntryPath(fn) {
17
+ return fn[ENTRY_SYMBOL];
18
+ }
19
+ /**
20
+ * Get the handler name that was passed to NodejsFunction constructor.
21
+ * Returns undefined if the function was not created with NodejsFunction
22
+ * or if the hook was not installed.
23
+ */
24
+ export function getHandlerName(fn) {
25
+ return fn[HANDLER_SYMBOL];
26
+ }
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZWpzLWZ1bmN0aW9uLWhvb2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXNwZWN0L25vZGVqcy1mdW5jdGlvbi1ob29rLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUlILDhEQUE4RDtBQUM5RCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUE7QUFDcEQsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFBO0FBRXhEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsWUFBWSxDQUFDLEVBQW1CO0lBQzlDLE9BQVEsRUFBb0QsQ0FBQyxZQUFZLENBQUMsQ0FBQTtBQUM1RSxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsRUFBbUI7SUFDaEQsT0FBUSxFQUFvRCxDQUFDLGNBQWMsQ0FBQyxDQUFBO0FBQzlFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEZ1bmN0aW9ucyB0byByZXRyaWV2ZSBjYXB0dXJlZCBlbnRyeSBwYXRoIGFuZCBoYW5kbGVyIG5hbWUgZnJvbSBMYW1iZGEgZnVuY3Rpb25zXG4gKiB0aGF0IHdlcmUgY3JlYXRlZCB3aXRoIE5vZGVqc0Z1bmN0aW9uLlxuICpcbiAqIFRoZSBsaXZlLWxhbWJkYS1ib290c3RyYXAudHMgZmlsZSBpbnN0YWxscyBhIGhvb2sgdGhhdCBjYXB0dXJlcyB0aGVzZSB2YWx1ZXNcbiAqIHdoZW4gTm9kZWpzRnVuY3Rpb24gaW5zdGFuY2VzIGFyZSBjcmVhdGVkLlxuICovXG5cbmltcG9ydCB0eXBlICogYXMgbGFtYmRhIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhXCJcblxuLy8gU3ltYm9scyB1c2VkIGJ5IHRoZSBib290c3RyYXAgaG9vayB0byBzdG9yZSBjYXB0dXJlZCB2YWx1ZXNcbmNvbnN0IEVOVFJZX1NZTUJPTCA9IFN5bWJvbC5mb3IoXCJsaXZlLWxhbWJkYTplbnRyeVwiKVxuY29uc3QgSEFORExFUl9TWU1CT0wgPSBTeW1ib2wuZm9yKFwibGl2ZS1sYW1iZGE6aGFuZGxlclwiKVxuXG4vKipcbiAqIEdldCB0aGUgZW50cnkgcGF0aCB0aGF0IHdhcyBwYXNzZWQgdG8gTm9kZWpzRnVuY3Rpb24gY29uc3RydWN0b3IuXG4gKiBSZXR1cm5zIHVuZGVmaW5lZCBpZiB0aGUgZnVuY3Rpb24gd2FzIG5vdCBjcmVhdGVkIHdpdGggTm9kZWpzRnVuY3Rpb25cbiAqIG9yIGlmIHRoZSBob29rIHdhcyBub3QgaW5zdGFsbGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RW50cnlQYXRoKGZuOiBsYW1iZGEuRnVuY3Rpb24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gKGZuIGFzIHVua25vd24gYXMgUmVjb3JkPHN5bWJvbCwgc3RyaW5nIHwgdW5kZWZpbmVkPilbRU5UUllfU1lNQk9MXVxufVxuXG4vKipcbiAqIEdldCB0aGUgaGFuZGxlciBuYW1lIHRoYXQgd2FzIHBhc3NlZCB0byBOb2RlanNGdW5jdGlvbiBjb25zdHJ1Y3Rvci5cbiAqIFJldHVybnMgdW5kZWZpbmVkIGlmIHRoZSBmdW5jdGlvbiB3YXMgbm90IGNyZWF0ZWQgd2l0aCBOb2RlanNGdW5jdGlvblxuICogb3IgaWYgdGhlIGhvb2sgd2FzIG5vdCBpbnN0YWxsZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRIYW5kbGVyTmFtZShmbjogbGFtYmRhLkZ1bmN0aW9uKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIChmbiBhcyB1bmtub3duIGFzIFJlY29yZDxzeW1ib2wsIHN0cmluZyB8IHVuZGVmaW5lZD4pW0hBTkRMRVJfU1lNQk9MXVxufVxuIl19
@@ -0,0 +1,60 @@
1
+ import * as cdk from "aws-cdk-lib";
2
+ import * as appsync from "aws-cdk-lib/aws-appsync";
3
+ import * as iam from "aws-cdk-lib/aws-iam";
4
+ import * as s3 from "aws-cdk-lib/aws-s3";
5
+ import type { Construct } from "constructs";
6
+ /**
7
+ * Properties for the LiveLambdaBootstrapStack
8
+ */
9
+ export interface CdkLocalLambdaBootstrapStackProps extends cdk.StackProps {
10
+ /**
11
+ * Optional name for the AppSync Events API
12
+ * @default 'LiveLambdaEventsApi'
13
+ */
14
+ apiName?: string;
15
+ }
16
+ /**
17
+ * Bootstrap stack that creates the shared AppSync Events API infrastructure
18
+ * for live lambda debugging. This stack should be deployed once per account/region.
19
+ */
20
+ export declare class CdkLocalLambdaBootstrapStack extends cdk.Stack {
21
+ /**
22
+ * The AppSync Events API for WebSocket communication
23
+ */
24
+ readonly api: appsync.CfnApi;
25
+ /**
26
+ * The channel namespace for live debugging channels
27
+ */
28
+ readonly channelNamespace: appsync.CfnChannelNamespace;
29
+ /**
30
+ * The HTTP endpoint for publishing events
31
+ */
32
+ readonly httpEndpoint: string;
33
+ /**
34
+ * The WebSocket endpoint for real-time subscriptions
35
+ */
36
+ readonly realtimeEndpoint: string;
37
+ /**
38
+ * IAM role for publishing to the Events API
39
+ */
40
+ readonly publishRole: iam.Role;
41
+ /**
42
+ * S3 bucket for storing the bridge Lambda code
43
+ */
44
+ readonly bridgeBucket: s3.Bucket;
45
+ constructor(scope: Construct, id: string, props?: CdkLocalLambdaBootstrapStackProps);
46
+ /**
47
+ * Grant a Lambda function permission to publish and subscribe to the Events API
48
+ */
49
+ grantPublishSubscribe(grantee: iam.IGrantable): iam.Grant;
50
+ /**
51
+ * Build the bridge handler and upload to S3 using a custom resource.
52
+ * The bridge code has AppSync endpoints baked in at deploy time.
53
+ */
54
+ private buildAndUploadBridge;
55
+ /**
56
+ * Build Docker bridge images for ARM64 and x86_64 architectures.
57
+ * Uses CDK Docker image assets to build and push to ECR.
58
+ */
59
+ private buildDockerBridgeImages;
60
+ }