cdk-serverless 3.3.3 → 3.5.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 (46) hide show
  1. package/docs/constructs/assets/hierarchy.js +1 -1
  2. package/docs/constructs/assets/navigation.js +1 -1
  3. package/docs/constructs/assets/search.js +1 -1
  4. package/docs/constructs/classes/GraphQlApi.html +4 -3
  5. package/docs/constructs/classes/McpAuth.html +1 -1
  6. package/docs/constructs/classes/McpCognitoAuth.html +1 -1
  7. package/docs/constructs/classes/RestApi.html +1 -1
  8. package/docs/constructs/classes/SingleTableDatastore.html +1 -1
  9. package/docs/constructs/classes/Workflow.html +1 -1
  10. package/docs/constructs/hierarchy.html +5 -5
  11. package/docs/constructs/interfaces/GraphQlApiProps.html +24 -3
  12. package/docs/constructs/interfaces/LambdaResolverOptions.html +72 -0
  13. package/docs/constructs/interfaces/RestApiProps.html +1 -1
  14. package/docs/constructs/modules.html +2 -2
  15. package/docs/experiments/appsync-unit-resolver-error-probe.md +201 -0
  16. package/docs/lambda/assets/hierarchy.js +1 -1
  17. package/docs/lambda/assets/navigation.js +1 -1
  18. package/docs/lambda/assets/search.js +1 -1
  19. package/docs/lambda/classes/errors.BadRequestError.html +1 -1
  20. package/docs/lambda/classes/errors.ForbiddenError.html +3 -3
  21. package/docs/lambda/classes/errors.HttpError.html +3 -3
  22. package/docs/lambda/classes/errors.NotFoundError.html +3 -3
  23. package/docs/lambda/classes/errors.UnauthenticatedError.html +1 -1
  24. package/docs/lambda/classes/errors.appsync.AppSyncError.html +193 -0
  25. package/docs/lambda/classes/errors.appsync.ConflictError.html +184 -0
  26. package/docs/lambda/classes/errors.appsync.ForbiddenError.html +184 -0
  27. package/docs/lambda/classes/errors.appsync.NotFoundError.html +184 -0
  28. package/docs/lambda/classes/errors.appsync.ValidationError.html +184 -0
  29. package/docs/lambda/functions/api.createAppSyncBatchHandler.html +57 -0
  30. package/docs/lambda/hierarchy.html +16 -5
  31. package/docs/lambda/interfaces/api.AppSyncBatchHandlerContext.html +89 -0
  32. package/docs/lambda/interfaces/api.AppSyncHandlerContext.html +6 -0
  33. package/docs/lambda/modules/api.html +6 -6
  34. package/docs/lambda/modules/errors.appsync.html +38 -0
  35. package/docs/lambda/modules/errors.html +4 -0
  36. package/docs/lambda/types/api.AppSyncBatchHandler.html +53 -0
  37. package/lib/constructs/graphql.d.ts +40 -1
  38. package/lib/constructs/graphql.js +103 -3
  39. package/lib/lambda/appsync-errors.d.ts +67 -0
  40. package/lib/lambda/appsync-errors.js +91 -0
  41. package/lib/lambda/errors.d.ts +1 -0
  42. package/lib/lambda/errors.js +36 -2
  43. package/lib/lambda/handler.d.ts +28 -0
  44. package/lib/lambda/handler.js +142 -2
  45. package/llm.md +43 -0
  46. package/package.json +1 -1
@@ -36,9 +36,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.createAppSyncHandler = exports.createHttpHandler = exports.createOpenApiHandler = exports.createOpenApiHandlerWithRequestBodyNoResponse = exports.createOpenApiHandlerWithRequestBody = void 0;
39
+ exports.createAppSyncBatchHandler = exports.createAppSyncHandler = exports.createHttpHandler = exports.createOpenApiHandler = exports.createOpenApiHandlerWithRequestBodyNoResponse = exports.createOpenApiHandlerWithRequestBody = void 0;
40
40
  const process_1 = require("process");
41
41
  const lambda_log_1 = __importDefault(require("lambda-log"));
42
+ const appsyncErrors = __importStar(require("./appsync-errors"));
42
43
  const auth_1 = require("./auth");
43
44
  const errors = __importStar(require("./errors"));
44
45
  /**
@@ -198,6 +199,70 @@ function corsHeader(event) {
198
199
  'Access-Control-Allow-Headers': 'Authorization, *', // Allow the Authorization header and any other headers
199
200
  };
200
201
  }
202
+ /**
203
+ * Maps an HTTP status code to the GraphQL errorType reported to AppSync.
204
+ *
205
+ * Local (non-exported) helper used only by createAppSyncHandler when it
206
+ * translates an errors.HttpError into a typed AppSync error. The explicit
207
+ * default keeps any unmapped status (for example a 418 or a 5xx) reported as
208
+ * the generic 'Error' errorType rather than leaking the raw status code.
209
+ */
210
+ function httpStatusToErrorType(statusCode) {
211
+ switch (statusCode) {
212
+ case 400:
213
+ return 'BadRequest';
214
+ case 401:
215
+ return 'Unauthorized';
216
+ case 403:
217
+ return 'Forbidden';
218
+ case 404:
219
+ return 'NotFound';
220
+ default:
221
+ return 'Error';
222
+ }
223
+ }
224
+ /**
225
+ * Normalises the two recognised typed-error shapes to a common
226
+ * { errorType, message, errorInfo } so the gate, envelope and rethrow are a
227
+ * single code path across the single and batch handlers. Returns undefined for
228
+ * anything that is neither (plain Error, Boom), which the callers rethrow.
229
+ *
230
+ * - appsyncErrors.AppSyncError carries its own GraphQL errorType and an optional
231
+ * errorInfo, which flow through unchanged.
232
+ * - errors.HttpError (the HTTP base thrown by the shared JwtAuthorizer via
233
+ * assertAuthenticated/assertGroup/assertAdmin, and by resolver code directly)
234
+ * has no GraphQL errorType, so map its statusCode with httpStatusToErrorType.
235
+ * HttpError carries no errorInfo, so errorInfo is undefined.
236
+ *
237
+ * The two instanceof checks are disjoint: HttpError and AppSyncError share no
238
+ * ancestry, so an appsync.ForbiddenError takes the AppSyncError branch and an
239
+ * errors.ForbiddenError the HttpError branch.
240
+ */
241
+ function toTypedError(error) {
242
+ if (error instanceof appsyncErrors.AppSyncError) {
243
+ return { errorType: error.errorType, message: error.message, errorInfo: error.errorInfo };
244
+ }
245
+ else if (error instanceof errors.HttpError) {
246
+ return { errorType: httpStatusToErrorType(error.statusCode), message: error.message, errorInfo: undefined };
247
+ }
248
+ return undefined;
249
+ }
250
+ /**
251
+ * Builds the direct-Lambda error envelope AppSync surfaces as a typed GraphQL
252
+ * error. __appSyncError is a reserved sentinel key the resolver response handler
253
+ * keys on to recognise this envelope. Branching on the sentinel (rather than on
254
+ * a bare errorMessage) means a legitimate resolver result that merely contains
255
+ * an errorMessage field is not misclassified as a typed error.
256
+ */
257
+ function buildErrorEnvelope(typed) {
258
+ return {
259
+ __appSyncError: true,
260
+ data: null,
261
+ errorType: typed.errorType,
262
+ errorMessage: typed.message,
263
+ errorInfo: typed.errorInfo,
264
+ };
265
+ }
201
266
  /**
202
267
  * Creates an AppSync resolver handler from the given AppSyncHandler.
203
268
  * Returns a function that can be used as an AppSync resolver.
@@ -225,6 +290,26 @@ const createAppSyncHandler = (handler) => {
225
290
  return await handler(ctx);
226
291
  }
227
292
  catch (error) {
293
+ const typed = toTypedError(error);
294
+ if (typed && process.env.APPSYNC_TYPED_ERRORS === 'true') {
295
+ // The envelope-return is gated on APPSYNC_TYPED_ERRORS === 'true'.
296
+ // GraphQlApi.addLambdaResolver injects that env var only on its
297
+ // typedErrors: true path, whose APPSYNC_JS resolver has a response
298
+ // handler that reads this envelope and calls
299
+ // util.error(errorMessage, errorType, null, errorInfo), turning it into
300
+ // a GraphQL error on a successful invocation. Returning (not throwing)
301
+ // keeps the invocation off the Lambda Errors metric.
302
+ //
303
+ // When the env var is absent (the default UNIT resolver path, or a
304
+ // hand-wired handler used without GraphQlApi) the typed error falls
305
+ // through to the rethrow below, so the invocation fails loudly instead
306
+ // of surfacing the envelope as field data. Any value other than the
307
+ // exact string 'true' means rethrow. This is why a default UNIT
308
+ // resolver whose handler hits an auth assertion (an HttpError) still
309
+ // fails loudly unless typedErrors is active.
310
+ ctx.logger.warn(typed.message, { errorType: typed.errorType, errorInfo: typed.errorInfo });
311
+ return buildErrorEnvelope(typed);
312
+ }
228
313
  // log the error and throw it again
229
314
  ctx.logger.error(error);
230
315
  throw error;
@@ -232,4 +317,59 @@ const createAppSyncHandler = (handler) => {
232
317
  };
233
318
  };
234
319
  exports.createAppSyncHandler = createAppSyncHandler;
235
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sYW1iZGEvaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxxQ0FBOEI7QUFDOUIsNERBQStDO0FBQy9DLGlDQU1nQjtBQUNoQixpREFBbUM7QUE2RG5DOztHQUVHO0FBQ0ksTUFBTSxtQ0FBbUMsR0FBRyxDQUErRCxPQUEwSCxFQUF1QixFQUFFO0lBQ25RLE9BQU8sSUFBQSx5QkFBaUIsRUFBQyxPQUFPLENBQUMsQ0FBQztBQUNwQyxDQUFDLENBQUM7QUFGVyxRQUFBLG1DQUFtQyx1Q0FFOUM7QUFFRjs7R0FFRztBQUNJLE1BQU0sNkNBQTZDLEdBQUcsQ0FBc0MsT0FBNEUsRUFBdUIsRUFBRTtJQUN0TSxPQUFPLElBQUEseUJBQWlCLEVBQUMsT0FBTyxDQUFDLENBQUM7QUFDcEMsQ0FBQyxDQUFDO0FBRlcsUUFBQSw2Q0FBNkMsaURBRXhEO0FBRUY7O0dBRUc7QUFDSSxNQUFNLG9CQUFvQixHQUFHLENBQWdELE9BQTZFLEVBQXVCLEVBQUU7SUFDeEwsT0FBTyxJQUFBLHlCQUFpQixFQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3BDLENBQUMsQ0FBQztBQUZXLFFBQUEsb0JBQW9CLHdCQUUvQjtBQUVGOztHQUVHO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLEtBQXFGLEVBQUUsR0FBYyxFQUFFLEVBQUU7SUFDakksaUhBQWlIO0lBQ2pILElBQUksYUFBRyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3JCLE9BQU8sSUFBSSxvQ0FBNkIsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDdkQsQ0FBQztTQUFNLENBQUM7UUFDTixnR0FBZ0c7UUFDaEcsT0FBTyxJQUFJLGdDQUF5QixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDNUQsQ0FBQztBQUNI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QUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUM7UUFDekQsZ0NBQWdDO1FBQ2hDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssS0FBSyxNQUFNLENBQUM7UUFFeEQseUJBQXlCO1FBQ3pCLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUV4QyxJQUFJLENBQUM7WUFDSCxvQ0FBb0M7WUFDcEMsTUFBTSxHQUFHLENBQUMsV0FBVyxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3JDLCtDQUErQztZQUMvQyxPQUFPLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzVCLENBQUM7UUFBQyxPQUFPLEtBQVUsRUFBRSxDQUFDO1lBQ3BCLG1DQUFtQztZQUNuQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN4QixNQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDLENBQUM7QUFDSixDQUFDLENBQUM7QUE3QlMsUUFBQSxvQkFBb0Isd0JBNkI3QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGVudiB9IGZyb20gJ3Byb2Nlc3MnO1xuaW1wb3J0IGxvZ2dlciwgeyBMYW1iZGFMb2cgfSBmcm9tICdsYW1iZGEtbG9nJztcbmltcG9ydCB7XG4gIEFwaUdhdGV3YXl2MUNvZ25pdG9BdXRob3JpemVyLFxuICBBcGlHYXRld2F5djFKd3RBdXRob3JpemVyLFxuICBBcHBTeW5jQ29nbml0b0F1dGhvcml6ZXIsXG4gIENvZ25pdG9BdXRob3JpemVyLFxuICBKd3RBdXRob3JpemVyLFxufSBmcm9tICcuL2F1dGgnO1xuaW1wb3J0ICogYXMgZXJyb3JzIGZyb20gJy4vZXJyb3JzJztcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLyBIVFRQIEFwaVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHByb3BlcnRpZXMgZm9yIGFuIEhUVFAgcmVzcG9uc2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSHR0cFJlc3BvbnNlQ29udGV4dCB7XG4gIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gIGhlYWRlcnM6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9O1xuICBqc29uOiBib29sZWFuO1xufVxuXG4vKipcbiAqIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIGZvciBhbiBIVFRQIHJlcXVlc3QgaGFuZGxlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIdHRwSGFuZGxlckNvbnRleHQge1xuICBldmVudDogQVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eVdpdGhDb2duaXRvQXV0aG9yaXplckV2ZW50O1xuICBsYW1iZGFDb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dDtcbiAgbG9nZ2VyOiBsb2dnZXIuTGFtYmRhTG9nO1xuICByZXNwb25zZTogSHR0cFJlc3BvbnNlQ29udGV4dDtcbiAgYXV0aDogSnd0QXV0aG9yaXplcjtcbn1cblxuLyoqXG4gKiBBIHR5cGUgZGVmaW5pdGlvbiBmb3IgYW4gSFRUUCBoYW5kbGVyLlxuICovXG5leHBvcnQgdHlwZSBIdHRwSGFuZGxlcjxULCBSPiA9IChcbiAgY29udGV4dDogSHR0cEhhbmRsZXJDb250ZXh0LFxuICBib2R5OiBULFxuKSA9PiBQcm9taXNlPFI+O1xuXG4vKipcbiAqIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIGZvciBhbiBPcGVuQVBJIG9wZXJhdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcGVyYXRpb24ge1xuICByZXNwb25zZXM6IHtcbiAgICBbc3RhdHVzQ29kZTogbnVtYmVyXToge1xuICAgICAgY29udGVudDoge1xuICAgICAgICAnYXBwbGljYXRpb24vanNvbic6IGFueTtcbiAgICAgIH07XG4gICAgfSB8IGFueTtcbiAgfTtcbn1cblxuLyoqXG4gKiBBIHR5cGUgZGVmaW5pdGlvbiBmb3IgYW4gQVBJIEdhdGV3YXkgdjEgcmVxdWVzdCBoYW5kbGVyLlxuICovXG5leHBvcnQgdHlwZSBBUElHYXRld2F5djFIYW5kbGVyID1cbiAgQVdTTGFtYmRhLkhhbmRsZXI8QVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eVdpdGhDb2duaXRvQXV0aG9yaXplckV2ZW50LCBBV1NMYW1iZGEuQVBJR2F0ZXdheVByb3h5UmVzdWx0IHwgdW5kZWZpbmVkPjtcblxuLyoqXG4gKiBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgcHJvcGVydGllcyBmb3IgYW4gT3BlbkFQSSBvcGVyYXRpb24gd2l0aCBhIHJlcXVlc3QgYm9keS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcGVyYXRpb25XaXRoUmVxdWVzdEJvZHkgZXh0ZW5kcyBPcGVyYXRpb24ge1xuICByZXF1ZXN0Qm9keTogeyBjb250ZW50OiB7ICdhcHBsaWNhdGlvbi9qc29uJzogYW55IH0gfTtcbn1cblxuLyoqXG4gKiBBIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIGFuIEhUVFAgcmVxdWVzdCBoYW5kbGVyIGZvciBhbiBPcGVuQVBJIG9wZXJhdGlvbiB3aXRoIGEgcmVxdWVzdCBib2R5LlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlT3BlbkFwaUhhbmRsZXJXaXRoUmVxdWVzdEJvZHkgPSA8T1AgZXh0ZW5kcyBPcGVyYXRpb25XaXRoUmVxdWVzdEJvZHksIFNDIGV4dGVuZHMgbnVtYmVyID0gMjAwPihoYW5kbGVyOiBIdHRwSGFuZGxlcjxPUFsncmVxdWVzdEJvZHknXVsnY29udGVudCddWydhcHBsaWNhdGlvbi9qc29uJ10sIE9QWydyZXNwb25zZXMnXVtTQ11bJ2NvbnRlbnQnXVsnYXBwbGljYXRpb24vanNvbiddPik6IEFQSUdhdGV3YXl2MUhhbmRsZXIgPT4ge1xuICByZXR1cm4gY3JlYXRlSHR0cEhhbmRsZXIoaGFuZGxlcik7XG59O1xuXG4vKipcbiAqIEEgZmFjdG9yeSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYW4gSFRUUCByZXF1ZXN0IGhhbmRsZXIgZm9yIGFuIE9wZW5BUEkgb3BlcmF0aW9uIHdpdGggYSByZXF1ZXN0IGJvZHkgYW5kIG5vIHJlc3BvbnNlLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlT3BlbkFwaUhhbmRsZXJXaXRoUmVxdWVzdEJvZHlOb1Jlc3BvbnNlID0gPE9QIGV4dGVuZHMgT3BlcmF0aW9uV2l0aFJlcXVlc3RCb2R5PihoYW5kbGVyOiBIdHRwSGFuZGxlcjxPUFsncmVxdWVzdEJvZHknXVsnY29udGVudCddWydhcHBsaWNhdGlvbi9qc29uJ10sIHZvaWQ+KTogQVBJR2F0ZXdheXYxSGFuZGxlciA9PiB7XG4gIHJldHVybiBjcmVhdGVIdHRwSGFuZGxlcihoYW5kbGVyKTtcbn07XG5cbi8qKlxuICogQSBmYWN0b3J5IGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhbiBIVFRQIHJlcXVlc3QgaGFuZGxlciBmb3IgYW4gT3BlbkFQSSBvcGVyYXRpb24uXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVPcGVuQXBpSGFuZGxlciA9IDxPUCBleHRlbmRzIE9wZXJhdGlvbiwgU0MgZXh0ZW5kcyBudW1iZXIgPSAyMDA+KGhhbmRsZXI6IEh0dHBIYW5kbGVyPGFueSwgT1BbJ3Jlc3BvbnNlcyddW1NDXVsnY29udGVudCddWydhcHBsaWNhdGlvbi9qc29uJ10+KTogQVBJR2F0ZXdheXYxSGFuZGxlciA9PiB7XG4gIHJldHVybiBjcmVhdGVIdHRwSGFuZGxlcihoYW5kbGVyKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGFuIGF1dGhvcml6ZXIgZm9yIHRoZSBhdXRoZW50aWNhdGlvbiBtZXRob2QgY2hvc2VuIChKV1Qgb3IgQ29nbml0bykuXG4gKi9cbmNvbnN0IGNyZWF0ZUF1dGhvcml6ZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlFdmVudEJhc2U8QVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eUNvZ25pdG9BdXRob3JpemVyPiwgbG9nOiBMYW1iZGFMb2cpID0+IHtcbiAgLy8gSWYgQ29nbml0byBpcyB1c2VkLCBVU0VSX1BPT0xfSUQgaXMgaW5qZWN0ZWQgaW50byB0aGUgZnVuY3Rpb24ncyBlbnZpcm9ubWVudC4gQ3VycmVudGx5IGFzc3VtZXMgSldUIG90aGVyd2lzZS5cbiAgaWYgKGVudi5VU0VSX1BPT0xfSUQpIHtcbiAgICByZXR1cm4gbmV3IEFwaUdhdGV3YXl2MUNvZ25pdG9BdXRob3JpemVyKGV2ZW50LCBsb2cpO1xuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgbWlnaHQgbmVlZCB0byBnZXQgbW9yZSBzb3BoaXN0aWNhdGVkIGlmIG1vcmUgYXV0aG9yaXphdGlvbiBtZXRob2RzIG5lZWQgdG8gYmUgc3VwcG9ydGVkLlxuICAgIHJldHVybiBuZXcgQXBpR2F0ZXdheXYxSnd0QXV0aG9yaXplcihldmVudCwgJ2FkbWluJywgbG9nKTtcbiAgfVxufTtcblxuLyoqXG4gKiBBIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIGFuIEhUVFAgcmVxdWVzdCBoYW5kbGVyLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlSHR0cEhhbmRsZXIgPVxuICA8VCwgUj4oaGFuZGxlcjogSHR0cEhhbmRsZXI8VCwgUj4pOiBBUElHYXRld2F5djFIYW5kbGVyID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKGV2ZW50LCBjb250ZXh0KSA9PiB7XG4gICAgICAvLyBDcmVhdGUgYW4gb2JqZWN0IHRvIGhvbGQgdGhlIGNvbnRleHQgZm9yIHRoaXMgSFRUUCByZXF1ZXN0XG4gICAgICBjb25zdCBhdXRoID0gY3JlYXRlQXV0aG9yaXplcihldmVudCwgbG9nZ2VyIGFzIHVua25vd24gYXMgbG9nZ2VyLkxhbWJkYUxvZyk7XG4gICAgICBjb25zdCBjdHg6IEh0dHBIYW5kbGVyQ29udGV4dCA9IHtcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIGF1dGgsXG4gICAgICAgIGxhbWJkYUNvbnRleHQ6IGNvbnRleHQsXG4gICAgICAgIGxvZ2dlcjogbG9nZ2VyIGFzIHVua25vd24gYXMgbG9nZ2VyLkxhbWJkYUxvZyxcbiAgICAgICAgcmVzcG9uc2U6IHsgaGVhZGVyczoge30sIGpzb246IHRydWUgfSxcbiAgICAgIH07XG4gICAgICAvLyBBZGQgdGhlIHJlcXVlc3QgSUQgdG8gdGhlIGxvZ2dpbmcgbWV0YWRhdGEsIGFuZCBlbmFibGUgZGVidWcgbG9nZ2luZyBpZiB0aGUgREVCVUcgZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgc2V0IHRvIFwidHJ1ZVwiXG4gICAgICBjdHgubG9nZ2VyLm9wdGlvbnMubWV0YS5yZXF1ZXN0SWQgPSBjb250ZXh0LmF3c1JlcXVlc3RJZDtcbiAgICAgIGN0eC5sb2dnZXIub3B0aW9ucy5kZWJ1ZyA9IHByb2Nlc3MuZW52LkRFQlVHID09PSAndHJ1ZSc7XG5cbiAgICAgIC8vIExvZyB0aGUgZXZlbnQgb2JqZWN0IGZvciBkZWJ1Z2dpbmcgcHVycG9zZXNcbiAgICAgIGN0eC5sb2dnZXIuZGVidWcoSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gQXV0aGVudGljYXRlIHRoZSB1c2VyIHVzaW5nIHRoZSBDb2duaXRvIGF1dGhvcml6ZXJcbiAgICAgICAgYXdhaXQgY3R4LmF1dGguYXV0aGVudGljYXRlKCk7XG5cbiAgICAgICAgLy8gQ2FsbCB0aGUgdXNlci1kZWZpbmVkIGhhbmRsZXIgZnVuY3Rpb24sIHBhc3NpbmcgaW4gdGhlIHJlcXVlc3QgY29udGV4dCBvYmplY3QgYW5kIHRoZSBwYXJzZWQgcmVxdWVzdCBib2R5XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGhhbmRsZXIoY3R4LCBwYXJzZUJvZHkoZXZlbnQpKTtcblxuICAgICAgICAvLyBDb25zdHJ1Y3QgYW5kIHJldHVybiB0aGUgSFRUUCByZXNwb25zZVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN0YXR1c0NvZGU6IGN0eC5yZXNwb25zZS5zdGF0dXNDb2RlID8/IChyZXMgPyAyMDAgOiAyMDQpLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgIC4uLmN0eC5yZXNwb25zZS5oZWFkZXJzLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYm9keTogcmVzID8gKGN0eC5yZXNwb25zZS5qc29uID8gSlNPTi5zdHJpbmdpZnkocmVzKSA6IHJlcykgOiAnJyxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgLy8gSGFuZGxlIGFueSBlcnJvcnMgdGhhdCBvY2N1ciBkdXJpbmcgcmVxdWVzdCBwcm9jZXNzaW5nXG5cbiAgICAgICAgLy8gSWYgdGhlIGVycm9yIGlzIGFuIGluc3RhbmNlIG9mIEh0dHBFcnJvciwgcmV0dXJuIGFuIEhUVFAgcmVzcG9uc2Ugd2l0aCB0aGUgZXJyb3Igc3RhdHVzIGNvZGUgYW5kIG1lc3NhZ2VcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgZXJyb3JzLkh0dHBFcnJvcikge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXNDb2RlOiBlcnJvci5zdGF0dXNDb2RlLFxuICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgICAgLi4uY3R4LnJlc3BvbnNlLmhlYWRlcnMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYm9keTogZXJyb3IubWVzc2FnZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIC8vIElmIHRoZSBlcnJvciBpcyBhIEJvb20gZXJyb3IgKGZyb20gdGhlIGhhcGkuanMgZnJhbWV3b3JrKSwgcmV0dXJuIGFuIEhUVFAgcmVzcG9uc2Ugd2l0aCB0aGUgZXJyb3Igc3RhdHVzIGNvZGUgYW5kIHBheWxvYWRcbiAgICAgICAgaWYgKGVycm9yLmlzQm9vbSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXNDb2RlOiBlcnJvci5vdXRwdXQuc3RhdHVzQ29kZSxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgICAgLi4uZXJyb3Iub3V0cHV0LmhlYWRlcnMsXG4gICAgICAgICAgICAgIC4uLmNvcnNIZWFkZXIoZXZlbnQpLFxuICAgICAgICAgICAgICAuLi5jdHgucmVzcG9uc2UuaGVhZGVycyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShlcnJvci5vdXRwdXQucGF5bG9hZCksXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICAvLyBGb3IgYWxsIG90aGVyIHR5cGVzIG9mIGVycm9ycywgbG9nIHRoZSBlcnJvciBhbmQgcmV0dXJuIGEgNTAwIHN0YXR1cyBjb2RlIHdpdGggdGhlIGVycm9yIG1lc3NhZ2VcbiAgICAgICAgY3R4LmxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3RhdHVzQ29kZTogY3R4LnJlc3BvbnNlLnN0YXR1c0NvZGUgPz8gNTAwLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgIC4uLmN0eC5yZXNwb25zZS5oZWFkZXJzLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYm9keTogZXJyb3IudG9TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuXG4vKipcbiAqIExvb2tzIHVwIGEgaGVhZGVyIHZhbHVlIGNhc2UtaW5zZW5zaXRpdmVseS5cbiAqIEhUVFAgaGVhZGVyIG5hbWVzIGFyZSBjYXNlLWluc2Vuc2l0aXZlIHBlciBSRkMgOTExMCDCpzUuMS5cbiAqL1xuZnVuY3Rpb24gaGVhZGVyVmFsdWUoaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB8IG51bGwgfCB1bmRlZmluZWQsIG5hbWU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghaGVhZGVycykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3Qga2V5ID0gT2JqZWN0LmtleXMoaGVhZGVycykuZmluZChrID0+IGsudG9Mb3dlckNhc2UoKSA9PT0gbmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgcmV0dXJuIGtleSA/IGhlYWRlcnNba2V5XSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIHRha2VzIGFuIGV2ZW50IG9iamVjdCByZXByZXNlbnRpbmcgYW4gQVBJIEdhdGV3YXkgUHJveHkgZXZlbnRcbiAqIHdpdGggYSBDb2duaXRvIGF1dGhvcml6ZXIsIGFuZCBleHRyYWN0cyBhbmQgcGFyc2VzIHRoZSByZXF1ZXN0IGJvZHksIGlmIHByZXNlbnQuXG4gKlxuICogQHBhcmFtIGV2ZW50IFRoZSBBUEkgR2F0ZXdheSBQcm94eSBldmVudCB3aXRoIGEgQ29nbml0byBhdXRob3JpemVyXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIHJlcXVlc3QgYm9keVxuICovXG5mdW5jdGlvbiBwYXJzZUJvZHk8VD4oZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlXaXRoQ29nbml0b0F1dGhvcml6ZXJFdmVudCk6IFQge1xuICBsZXQgYm9keSA9IGV2ZW50LmJvZHk7XG5cbiAgLy8gSWYgdGhlIHJlcXVlc3QgYm9keSBpcyBiYXNlNjQtZW5jb2RlZCwgZGVjb2RlIGl0XG4gIGlmIChldmVudC5ib2R5ICYmIGV2ZW50LmlzQmFzZTY0RW5jb2RlZCkge1xuICAgIGNvbnN0IGJ1ZmYgPSBCdWZmZXIuZnJvbShldmVudC5ib2R5ISwgJ2Jhc2U2NCcpO1xuICAgIGJvZHkgPSBidWZmLnRvU3RyaW5nKCd1dGY4Jyk7XG4gIH1cblxuICAvLyBJZiB0aGUgcmVxdWVzdCBib2R5IGlzIGluIEpTT04gZm9ybWF0LCBwYXJzZSBpdCBpbnRvIGEgSmF2YVNjcmlwdCBvYmplY3RcbiAgaWYgKGhlYWRlclZhbHVlKGV2ZW50LmhlYWRlcnMsICdjb250ZW50LXR5cGUnKT8uaW5jbHVkZXMoJ2FwcGxpY2F0aW9uL2pzb24nKSkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKGJvZHkgPz8gJ3t9Jyk7XG4gIH1cblxuICAvLyBJZiB0aGUgcmVxdWVzdCBib2R5IGlzIG5vdCBwcmVzZW50IG9yIG5vdCBpbiBKU09OIGZvcm1hdCwgcmV0dXJuIGl0IGFzLWlzXG4gIHJldHVybiBib2R5IGFzIGFueTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgdGhlIENPUlMgaGVhZGVycyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgQVBJIEdhdGV3YXkgcmVzcG9uc2UuXG4gKlxuICogQHBhcmFtIGV2ZW50IC0gVGhlIEFQSSBHYXRld2F5IGV2ZW50IG9iamVjdC5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBDT1JTIGhlYWRlcnMuXG4gKi9cbmZ1bmN0aW9uIGNvcnNIZWFkZXIoZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlXaXRoQ29nbml0b0F1dGhvcml6ZXJFdmVudCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgY29uc3Qgb3JpZ2luID0gaGVhZGVyVmFsdWUoZXZlbnQ/LmhlYWRlcnMsICdvcmlnaW4nKTtcbiAgcmV0dXJuIHtcbiAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJzogb3JpZ2luID8/ICcqJywgLy8gQWxsb3cgcmVxdWVzdHMgZnJvbSB0aGUgb3JpZ2luIGhlYWRlciwgb3IgYWxsb3cgYW55IG9yaWdpbiBpZiBub3QgcHJlc2VudFxuICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFscyc6IG9yaWdpbiA/ICd0cnVlJyA6ICdmYWxzZScsIC8vIEluY2x1ZGUgY29va2llcyBpbiBjcm9zcy1vcmlnaW4gcmVxdWVzdHMgaWYgdGhlIG9yaWdpbiBoZWFkZXIgaXMgcHJlc2VudFxuICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJzogJyonLCAvLyBBbGxvdyBhbnkgSFRUUCBtZXRob2RcbiAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyc6ICdBdXRob3JpemF0aW9uLCAqJywgLy8gQWxsb3cgdGhlIEF1dGhvcml6YXRpb24gaGVhZGVyIGFuZCBhbnkgb3RoZXIgaGVhZGVyc1xuICB9O1xufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLyBBcHBTeW5jXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBUaGUgY29udGV4dCBmb3IgdGhlIEFwcFN5bmMgcmVzb2x2ZXIgZnVuY3Rpb24uXG4gKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZXZlbnQsIGxhbWJkYSBjb250ZXh0LCBsb2dnZXIsIGFuZCBDb2duaXRvIGF1dGhvcml6ZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBwU3luY0hhbmRsZXJDb250ZXh0PFQ+IHtcbiAgZXZlbnQ6IEFXU0xhbWJkYS5BcHBTeW5jUmVzb2x2ZXJFdmVudDxUPjtcbiAgbGFtYmRhQ29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQ7XG4gIGxvZ2dlcjogbG9nZ2VyLkxhbWJkYUxvZztcbiAgY29nbml0b0F1dGg6IENvZ25pdG9BdXRob3JpemVyO1xufVxuXG4vKipcbiAqIEEgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIGFuIEFwcFN5bmMgcmVzb2x2ZXIgZXZlbnQuXG4gKiBSZWNlaXZlcyB0aGUgY29udGV4dCBvYmplY3QgYW5kIHJldHVybnMgdGhlIHJlc3BvbnNlLlxuICovXG5leHBvcnQgdHlwZSBBcHBTeW5jSGFuZGxlcjxULCBSPiA9IChcbiAgY29udGV4dDogQXBwU3luY0hhbmRsZXJDb250ZXh0PFQ+LFxuKSA9PiBQcm9taXNlPFI+O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gQXBwU3luYyByZXNvbHZlciBoYW5kbGVyIGZyb20gdGhlIGdpdmVuIEFwcFN5bmNIYW5kbGVyLlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgYXMgYW4gQXBwU3luYyByZXNvbHZlci5cbiAqXG4gKiBAcGFyYW0gaGFuZGxlciBUaGUgQXBwU3luY0hhbmRsZXIgdG8gdXNlIGFzIHRoZSByZXNvbHZlci5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUFwcFN5bmNIYW5kbGVyID1cbiAgPFQsIFI+KGhhbmRsZXI6IEFwcFN5bmNIYW5kbGVyPFQsIFI+KTogQVdTTGFtYmRhLkFwcFN5bmNSZXNvbHZlckhhbmRsZXI8VCwgUj4gPT4ge1xuICAgIHJldHVybiBhc3luYyAoZXZlbnQsIGNvbnRleHQpID0+IHtcbiAgICAgIGNvbnN0IGN0eDogQXBwU3luY0hhbmRsZXJDb250ZXh0PFQ+ID0ge1xuICAgICAgICBldmVudCxcbiAgICAgICAgbGFtYmRhQ29udGV4dDogY29udGV4dCxcbiAgICAgICAgbG9nZ2VyOiBsb2dnZXIgYXMgdW5rbm93biBhcyBsb2dnZXIuTGFtYmRhTG9nLFxuICAgICAgICBjb2duaXRvQXV0aDogbmV3IEFwcFN5bmNDb2duaXRvQXV0aG9yaXplcihldmVudCksXG4gICAgICB9O1xuXG4gICAgICAvLyBzZXQgdGhlIG1ldGEgaW5mb3JtYXRpb24gaW4gbG9nZ2VyXG4gICAgICBjdHgubG9nZ2VyLm9wdGlvbnMubWV0YS5yZXF1ZXN0SWQgPSBjb250ZXh0LmF3c1JlcXVlc3RJZDtcbiAgICAgIC8vIHNldCB0aGUgZGVidWcgZmxhZyBmb3IgbG9nZ2VyXG4gICAgICBjdHgubG9nZ2VyLm9wdGlvbnMuZGVidWcgPSBwcm9jZXNzLmVudi5ERUJVRyA9PT0gJ3RydWUnO1xuXG4gICAgICAvLyBsb2cgdGhlIHJlY2VpdmVkIGV2ZW50XG4gICAgICBjdHgubG9nZ2VyLmRlYnVnKEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIGF1dGhlbnRpY2F0ZSB0aGUgaW5jb21pbmcgcmVxdWVzdFxuICAgICAgICBhd2FpdCBjdHguY29nbml0b0F1dGguYXV0aGVudGljYXRlKCk7XG4gICAgICAgIC8vIGludm9rZSB0aGUgaGFuZGxlciBmdW5jdGlvbiB3aXRoIHRoZSBjb250ZXh0XG4gICAgICAgIHJldHVybiBhd2FpdCBoYW5kbGVyKGN0eCk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgIC8vIGxvZyB0aGUgZXJyb3IgYW5kIHRocm93IGl0IGFnYWluXG4gICAgICAgIGN0eC5sb2dnZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuXG4iXX0=
320
+ /**
321
+ * Creates a batched AppSync resolver handler from the given AppSyncBatchHandler.
322
+ * Returns a function that can be used as an AppSync BatchInvoke resolver: array
323
+ * in, array out, order preserved.
324
+ *
325
+ * It mirrors createAppSyncHandler's context and auth plumbing but operates on an
326
+ * array of events. Authentication runs once per batch off the first event, and
327
+ * the context carries both the first event (ctx.event = events[0]) and the full
328
+ * ctx.events array. The handler returns R[] in the same order as the input events.
329
+ *
330
+ * @param handler The AppSyncBatchHandler to use as the resolver.
331
+ */
332
+ const createAppSyncBatchHandler = (handler) => {
333
+ return async (events, context) => {
334
+ // BatchInvoke always delivers a non-empty array; authenticate and build
335
+ // the context off the first event, exactly like createAppSyncHandler.
336
+ const first = events[0];
337
+ const ctx = {
338
+ event: first,
339
+ events,
340
+ lambdaContext: context,
341
+ logger: lambda_log_1.default,
342
+ cognitoAuth: new auth_1.AppSyncCognitoAuthorizer(first),
343
+ };
344
+ // set the meta information in logger
345
+ ctx.logger.options.meta.requestId = context.awsRequestId;
346
+ // set the debug flag for logger
347
+ ctx.logger.options.debug = process.env.DEBUG === 'true';
348
+ // log the received batch of events
349
+ ctx.logger.debug(JSON.stringify(events));
350
+ try {
351
+ // authenticate once per batch off the first event
352
+ await ctx.cognitoAuth.authenticate();
353
+ // invoke the handler function with the batch context; it returns R[] in source order
354
+ return await handler(ctx);
355
+ }
356
+ catch (error) {
357
+ const typed = toTypedError(error);
358
+ if (typed && process.env.APPSYNC_TYPED_ERRORS === 'true') {
359
+ // Same gate and envelope as createAppSyncHandler. AppSync expects one
360
+ // result per event in a BatchInvoke response, so a batch-level typed
361
+ // error returns an array of envelopes aligned to the batch length;
362
+ // each item surfaces the same typed error. Returning (not throwing)
363
+ // keeps the invocation off the Lambda Errors metric. Without the flag
364
+ // the typed error falls through to the rethrow below.
365
+ ctx.logger.warn(typed.message, { errorType: typed.errorType, errorInfo: typed.errorInfo });
366
+ return events.map(() => buildErrorEnvelope(typed));
367
+ }
368
+ // log the error and throw it again
369
+ ctx.logger.error(error);
370
+ throw error;
371
+ }
372
+ };
373
+ };
374
+ exports.createAppSyncBatchHandler = createAppSyncBatchHandler;
375
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sYW1iZGEvaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxxQ0FBOEI7QUFDOUIsNERBQStDO0FBQy9DLGdFQUFrRDtBQUNsRCxpQ0FNZ0I7QUFDaEIsaURBQW1DO0FBNkRuQzs7R0FFRztBQUNJLE1BQU0sbUNBQW1DLEdBQUcsQ0FBK0QsT0FBMEgsRUFBdUIsRUFBRTtJQUNuUSxPQUFPLElBQUEseUJBQWlCLEVBQUMsT0FBTyxDQUFDLENBQUM7QUFDcEMsQ0FBQyxDQUFDO0FBRlcsUUFBQSxtQ0FBbUMsdUNBRTlDO0FBRUY7O0dBRUc7QUFDSSxNQUFNLDZDQUE2QyxHQUFHLENBQXNDLE9BQTRFLEVBQXVCLEVBQUU7SUFDdE0sT0FBTyxJQUFBLHlCQUFpQixFQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3BDLENBQUMsQ0FBQztBQUZXLFFBQUEsNkNBQTZDLGlEQUV4RDtBQUVGOztHQUVHO0FBQ0ksTUFBTSxvQkFBb0IsR0FBRyxDQUFnRCxPQUE2RSxFQUF1QixFQUFFO0lBQ3hMLE9BQU8sSUFBQSx5QkFBaUIsRUFBQyxPQUFPLENBQUMsQ0FBQztBQUNwQyxDQUFDLENBQUM7QUFGVyxRQUFBLG9CQUFvQix3QkFFL0I7QUFFRjs7R0FFRztBQUNILE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxLQUFxRixFQUFFLEdBQWMsRUFBRSxFQUFFO0lBQ2pJLGlIQUFpSDtJQUNqSCxJQUFJLGFBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNyQixPQUFPLElBQUksb0NBQTZCLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7U0FBTSxDQUFDO1FBQ04sZ0dBQWdHO1FBQ2hHLE9BQU8sSUFBSSxnQ0FBeUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lB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LENBQUMsQ0FBQztRQUM1QixDQUFDO1FBQUMsT0FBTyxLQUFVLEVBQUUsQ0FBQztZQUNwQixNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFbEMsSUFBSSxLQUFLLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsS0FBSyxNQUFNLEVBQUUsQ0FBQztnQkFDekQsc0VBQXNFO2dCQUN0RSxxRUFBcUU7Z0JBQ3JFLG1FQUFtRTtnQkFDbkUsb0VBQW9FO2dCQUNwRSxzRUFBc0U7Z0JBQ3RFLHNEQUFzRDtnQkFDdEQsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztnQkFDM0YsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLGtCQUFrQixDQUFJLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDeEQsQ0FBQztZQUNELG1DQUFtQztZQUNuQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN4QixNQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDLENBQUM7QUFDSixDQUFDLENBQUM7QUEvQ1MsUUFBQSx5QkFBeUIsNkJBK0NsQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGVudiB9IGZyb20gJ3Byb2Nlc3MnO1xuaW1wb3J0IGxvZ2dlciwgeyBMYW1iZGFMb2cgfSBmcm9tICdsYW1iZGEtbG9nJztcbmltcG9ydCAqIGFzIGFwcHN5bmNFcnJvcnMgZnJvbSAnLi9hcHBzeW5jLWVycm9ycyc7XG5pbXBvcnQge1xuICBBcGlHYXRld2F5djFDb2duaXRvQXV0aG9yaXplcixcbiAgQXBpR2F0ZXdheXYxSnd0QXV0aG9yaXplcixcbiAgQXBwU3luY0NvZ25pdG9BdXRob3JpemVyLFxuICBDb2duaXRvQXV0aG9yaXplcixcbiAgSnd0QXV0aG9yaXplcixcbn0gZnJvbSAnLi9hdXRoJztcbmltcG9ydCAqIGFzIGVycm9ycyBmcm9tICcuL2Vycm9ycyc7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLy8gSFRUUCBBcGlcbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vKipcbiAqIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIGZvciBhbiBIVFRQIHJlc3BvbnNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEh0dHBSZXNwb25zZUNvbnRleHQge1xuICBzdGF0dXNDb2RlPzogbnVtYmVyO1xuICBoZWFkZXJzOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfTtcbiAganNvbjogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgcHJvcGVydGllcyBmb3IgYW4gSFRUUCByZXF1ZXN0IGhhbmRsZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSHR0cEhhbmRsZXJDb250ZXh0IHtcbiAgZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlXaXRoQ29nbml0b0F1dGhvcml6ZXJFdmVudDtcbiAgbGFtYmRhQ29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQ7XG4gIGxvZ2dlcjogbG9nZ2VyLkxhbWJkYUxvZztcbiAgcmVzcG9uc2U6IEh0dHBSZXNwb25zZUNvbnRleHQ7XG4gIGF1dGg6IEp3dEF1dGhvcml6ZXI7XG59XG5cbi8qKlxuICogQSB0eXBlIGRlZmluaXRpb24gZm9yIGFuIEhUVFAgaGFuZGxlci5cbiAqL1xuZXhwb3J0IHR5cGUgSHR0cEhhbmRsZXI8VCwgUj4gPSAoXG4gIGNvbnRleHQ6IEh0dHBIYW5kbGVyQ29udGV4dCxcbiAgYm9keTogVCxcbikgPT4gUHJvbWlzZTxSPjtcblxuLyoqXG4gKiBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgcHJvcGVydGllcyBmb3IgYW4gT3BlbkFQSSBvcGVyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3BlcmF0aW9uIHtcbiAgcmVzcG9uc2VzOiB7XG4gICAgW3N0YXR1c0NvZGU6IG51bWJlcl06IHtcbiAgICAgIGNvbnRlbnQ6IHtcbiAgICAgICAgJ2FwcGxpY2F0aW9uL2pzb24nOiBhbnk7XG4gICAgICB9O1xuICAgIH0gfCBhbnk7XG4gIH07XG59XG5cbi8qKlxuICogQSB0eXBlIGRlZmluaXRpb24gZm9yIGFuIEFQSSBHYXRld2F5IHYxIHJlcXVlc3QgaGFuZGxlci5cbiAqL1xuZXhwb3J0IHR5cGUgQVBJR2F0ZXdheXYxSGFuZGxlciA9XG4gIEFXU0xhbWJkYS5IYW5kbGVyPEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlXaXRoQ29nbml0b0F1dGhvcml6ZXJFdmVudCwgQVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eVJlc3VsdCB8IHVuZGVmaW5lZD47XG5cbi8qKlxuICogQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHByb3BlcnRpZXMgZm9yIGFuIE9wZW5BUEkgb3BlcmF0aW9uIHdpdGggYSByZXF1ZXN0IGJvZHkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3BlcmF0aW9uV2l0aFJlcXVlc3RCb2R5IGV4dGVuZHMgT3BlcmF0aW9uIHtcbiAgcmVxdWVzdEJvZHk6IHsgY29udGVudDogeyAnYXBwbGljYXRpb24vanNvbic6IGFueSB9IH07XG59XG5cbi8qKlxuICogQSBmYWN0b3J5IGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhbiBIVFRQIHJlcXVlc3QgaGFuZGxlciBmb3IgYW4gT3BlbkFQSSBvcGVyYXRpb24gd2l0aCBhIHJlcXVlc3QgYm9keS5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU9wZW5BcGlIYW5kbGVyV2l0aFJlcXVlc3RCb2R5ID0gPE9QIGV4dGVuZHMgT3BlcmF0aW9uV2l0aFJlcXVlc3RCb2R5LCBTQyBleHRlbmRzIG51bWJlciA9IDIwMD4oaGFuZGxlcjogSHR0cEhhbmRsZXI8T1BbJ3JlcXVlc3RCb2R5J11bJ2NvbnRlbnQnXVsnYXBwbGljYXRpb24vanNvbiddLCBPUFsncmVzcG9uc2VzJ11bU0NdWydjb250ZW50J11bJ2FwcGxpY2F0aW9uL2pzb24nXT4pOiBBUElHYXRld2F5djFIYW5kbGVyID0+IHtcbiAgcmV0dXJuIGNyZWF0ZUh0dHBIYW5kbGVyKGhhbmRsZXIpO1xufTtcblxuLyoqXG4gKiBBIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIGFuIEhUVFAgcmVxdWVzdCBoYW5kbGVyIGZvciBhbiBPcGVuQVBJIG9wZXJhdGlvbiB3aXRoIGEgcmVxdWVzdCBib2R5IGFuZCBubyByZXNwb25zZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU9wZW5BcGlIYW5kbGVyV2l0aFJlcXVlc3RCb2R5Tm9SZXNwb25zZSA9IDxPUCBleHRlbmRzIE9wZXJhdGlvbldpdGhSZXF1ZXN0Qm9keT4oaGFuZGxlcjogSHR0cEhhbmRsZXI8T1BbJ3JlcXVlc3RCb2R5J11bJ2NvbnRlbnQnXVsnYXBwbGljYXRpb24vanNvbiddLCB2b2lkPik6IEFQSUdhdGV3YXl2MUhhbmRsZXIgPT4ge1xuICByZXR1cm4gY3JlYXRlSHR0cEhhbmRsZXIoaGFuZGxlcik7XG59O1xuXG4vKipcbiAqIEEgZmFjdG9yeSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYW4gSFRUUCByZXF1ZXN0IGhhbmRsZXIgZm9yIGFuIE9wZW5BUEkgb3BlcmF0aW9uLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlT3BlbkFwaUhhbmRsZXIgPSA8T1AgZXh0ZW5kcyBPcGVyYXRpb24sIFNDIGV4dGVuZHMgbnVtYmVyID0gMjAwPihoYW5kbGVyOiBIdHRwSGFuZGxlcjxhbnksIE9QWydyZXNwb25zZXMnXVtTQ11bJ2NvbnRlbnQnXVsnYXBwbGljYXRpb24vanNvbiddPik6IEFQSUdhdGV3YXl2MUhhbmRsZXIgPT4ge1xuICByZXR1cm4gY3JlYXRlSHR0cEhhbmRsZXIoaGFuZGxlcik7XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhbiBhdXRob3JpemVyIGZvciB0aGUgYXV0aGVudGljYXRpb24gbWV0aG9kIGNob3NlbiAoSldUIG9yIENvZ25pdG8pLlxuICovXG5jb25zdCBjcmVhdGVBdXRob3JpemVyID0gKGV2ZW50OiBBV1NMYW1iZGEuQVBJR2F0ZXdheVByb3h5RXZlbnRCYXNlPEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlDb2duaXRvQXV0aG9yaXplcj4sIGxvZzogTGFtYmRhTG9nKSA9PiB7XG4gIC8vIElmIENvZ25pdG8gaXMgdXNlZCwgVVNFUl9QT09MX0lEIGlzIGluamVjdGVkIGludG8gdGhlIGZ1bmN0aW9uJ3MgZW52aXJvbm1lbnQuIEN1cnJlbnRseSBhc3N1bWVzIEpXVCBvdGhlcndpc2UuXG4gIGlmIChlbnYuVVNFUl9QT09MX0lEKSB7XG4gICAgcmV0dXJuIG5ldyBBcGlHYXRld2F5djFDb2duaXRvQXV0aG9yaXplcihldmVudCwgbG9nKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBUaGlzIG1pZ2h0IG5lZWQgdG8gZ2V0IG1vcmUgc29waGlzdGljYXRlZCBpZiBtb3JlIGF1dGhvcml6YXRpb24gbWV0aG9kcyBuZWVkIHRvIGJlIHN1cHBvcnRlZC5cbiAgICByZXR1cm4gbmV3IEFwaUdhdGV3YXl2MUp3dEF1dGhvcml6ZXIoZXZlbnQsICdhZG1pbicsIGxvZyk7XG4gIH1cbn07XG5cbi8qKlxuICogQSBmYWN0b3J5IGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhbiBIVFRQIHJlcXVlc3QgaGFuZGxlci5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUh0dHBIYW5kbGVyID1cbiAgPFQsIFI+KGhhbmRsZXI6IEh0dHBIYW5kbGVyPFQsIFI+KTogQVBJR2F0ZXdheXYxSGFuZGxlciA9PiB7XG4gICAgcmV0dXJuIGFzeW5jIChldmVudCwgY29udGV4dCkgPT4ge1xuICAgICAgLy8gQ3JlYXRlIGFuIG9iamVjdCB0byBob2xkIHRoZSBjb250ZXh0IGZvciB0aGlzIEhUVFAgcmVxdWVzdFxuICAgICAgY29uc3QgYXV0aCA9IGNyZWF0ZUF1dGhvcml6ZXIoZXZlbnQsIGxvZ2dlciBhcyB1bmtub3duIGFzIGxvZ2dlci5MYW1iZGFMb2cpO1xuICAgICAgY29uc3QgY3R4OiBIdHRwSGFuZGxlckNvbnRleHQgPSB7XG4gICAgICAgIGV2ZW50LFxuICAgICAgICBhdXRoLFxuICAgICAgICBsYW1iZGFDb250ZXh0OiBjb250ZXh0LFxuICAgICAgICBsb2dnZXI6IGxvZ2dlciBhcyB1bmtub3duIGFzIGxvZ2dlci5MYW1iZGFMb2csXG4gICAgICAgIHJlc3BvbnNlOiB7IGhlYWRlcnM6IHt9LCBqc29uOiB0cnVlIH0sXG4gICAgICB9O1xuICAgICAgLy8gQWRkIHRoZSByZXF1ZXN0IElEIHRvIHRoZSBsb2dnaW5nIG1ldGFkYXRhLCBhbmQgZW5hYmxlIGRlYnVnIGxvZ2dpbmcgaWYgdGhlIERFQlVHIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIHNldCB0byBcInRydWVcIlxuICAgICAgY3R4LmxvZ2dlci5vcHRpb25zLm1ldGEucmVxdWVzdElkID0gY29udGV4dC5hd3NSZXF1ZXN0SWQ7XG4gICAgICBjdHgubG9nZ2VyLm9wdGlvbnMuZGVidWcgPSBwcm9jZXNzLmVudi5ERUJVRyA9PT0gJ3RydWUnO1xuXG4gICAgICAvLyBMb2cgdGhlIGV2ZW50IG9iamVjdCBmb3IgZGVidWdnaW5nIHB1cnBvc2VzXG4gICAgICBjdHgubG9nZ2VyLmRlYnVnKEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIEF1dGhlbnRpY2F0ZSB0aGUgdXNlciB1c2luZyB0aGUgQ29nbml0byBhdXRob3JpemVyXG4gICAgICAgIGF3YWl0IGN0eC5hdXRoLmF1dGhlbnRpY2F0ZSgpO1xuXG4gICAgICAgIC8vIENhbGwgdGhlIHVzZXItZGVmaW5lZCBoYW5kbGVyIGZ1bmN0aW9uLCBwYXNzaW5nIGluIHRoZSByZXF1ZXN0IGNvbnRleHQgb2JqZWN0IGFuZCB0aGUgcGFyc2VkIHJlcXVlc3QgYm9keVxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBoYW5kbGVyKGN0eCwgcGFyc2VCb2R5KGV2ZW50KSk7XG5cbiAgICAgICAgLy8gQ29uc3RydWN0IGFuZCByZXR1cm4gdGhlIEhUVFAgcmVzcG9uc2VcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdGF0dXNDb2RlOiBjdHgucmVzcG9uc2Uuc3RhdHVzQ29kZSA/PyAocmVzID8gMjAwIDogMjA0KSxcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgLi4uY29yc0hlYWRlcihldmVudCksXG4gICAgICAgICAgICAuLi5jdHgucmVzcG9uc2UuaGVhZGVycyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJvZHk6IHJlcyA/IChjdHgucmVzcG9uc2UuanNvbiA/IEpTT04uc3RyaW5naWZ5KHJlcykgOiByZXMpIDogJycsXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgIC8vIEhhbmRsZSBhbnkgZXJyb3JzIHRoYXQgb2NjdXIgZHVyaW5nIHJlcXVlc3QgcHJvY2Vzc2luZ1xuXG4gICAgICAgIC8vIElmIHRoZSBlcnJvciBpcyBhbiBpbnN0YW5jZSBvZiBIdHRwRXJyb3IsIHJldHVybiBhbiBIVFRQIHJlc3BvbnNlIHdpdGggdGhlIGVycm9yIHN0YXR1cyBjb2RlIGFuZCBtZXNzYWdlXG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIGVycm9ycy5IdHRwRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhdHVzQ29kZTogZXJyb3Iuc3RhdHVzQ29kZSxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgICAgLi4uY29yc0hlYWRlcihldmVudCksXG4gICAgICAgICAgICAgIC4uLmN0eC5yZXNwb25zZS5oZWFkZXJzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJvZHk6IGVycm9yLm1lc3NhZ2UsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiB0aGUgZXJyb3IgaXMgYSBCb29tIGVycm9yIChmcm9tIHRoZSBoYXBpLmpzIGZyYW1ld29yayksIHJldHVybiBhbiBIVFRQIHJlc3BvbnNlIHdpdGggdGhlIGVycm9yIHN0YXR1cyBjb2RlIGFuZCBwYXlsb2FkXG4gICAgICAgIGlmIChlcnJvci5pc0Jvb20pIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhdHVzQ29kZTogZXJyb3Iub3V0cHV0LnN0YXR1c0NvZGUsXG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAgIC4uLmVycm9yLm91dHB1dC5oZWFkZXJzLFxuICAgICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgICAgLi4uY3R4LnJlc3BvbnNlLmhlYWRlcnMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoZXJyb3Iub3V0cHV0LnBheWxvYWQpLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgLy8gRm9yIGFsbCBvdGhlciB0eXBlcyBvZiBlcnJvcnMsIGxvZyB0aGUgZXJyb3IgYW5kIHJldHVybiBhIDUwMCBzdGF0dXMgY29kZSB3aXRoIHRoZSBlcnJvciBtZXNzYWdlXG4gICAgICAgIGN0eC5sb2dnZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN0YXR1c0NvZGU6IGN0eC5yZXNwb25zZS5zdGF0dXNDb2RlID8/IDUwMCxcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgLi4uY29yc0hlYWRlcihldmVudCksXG4gICAgICAgICAgICAuLi5jdHgucmVzcG9uc2UuaGVhZGVycyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJvZHk6IGVycm9yLnRvU3RyaW5nKCksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfTtcbiAgfTtcblxuLyoqXG4gKiBMb29rcyB1cCBhIGhlYWRlciB2YWx1ZSBjYXNlLWluc2Vuc2l0aXZlbHkuXG4gKiBIVFRQIGhlYWRlciBuYW1lcyBhcmUgY2FzZS1pbnNlbnNpdGl2ZSBwZXIgUkZDIDkxMTAgwqc1LjEuXG4gKi9cbmZ1bmN0aW9uIGhlYWRlclZhbHVlKGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4gfCBudWxsIHwgdW5kZWZpbmVkLCBuYW1lOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoIWhlYWRlcnMpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IGtleSA9IE9iamVjdC5rZXlzKGhlYWRlcnMpLmZpbmQoayA9PiBrLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUudG9Mb3dlckNhc2UoKSk7XG4gIHJldHVybiBrZXkgPyBoZWFkZXJzW2tleV0gOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiB0YWtlcyBhbiBldmVudCBvYmplY3QgcmVwcmVzZW50aW5nIGFuIEFQSSBHYXRld2F5IFByb3h5IGV2ZW50XG4gKiB3aXRoIGEgQ29nbml0byBhdXRob3JpemVyLCBhbmQgZXh0cmFjdHMgYW5kIHBhcnNlcyB0aGUgcmVxdWVzdCBib2R5LCBpZiBwcmVzZW50LlxuICpcbiAqIEBwYXJhbSBldmVudCBUaGUgQVBJIEdhdGV3YXkgUHJveHkgZXZlbnQgd2l0aCBhIENvZ25pdG8gYXV0aG9yaXplclxuICogQHJldHVybnMgVGhlIHBhcnNlZCByZXF1ZXN0IGJvZHlcbiAqL1xuZnVuY3Rpb24gcGFyc2VCb2R5PFQ+KGV2ZW50OiBBV1NMYW1iZGEuQVBJR2F0ZXdheVByb3h5V2l0aENvZ25pdG9BdXRob3JpemVyRXZlbnQpOiBUIHtcbiAgbGV0IGJvZHkgPSBldmVudC5ib2R5O1xuXG4gIC8vIElmIHRoZSByZXF1ZXN0IGJvZHkgaXMgYmFzZTY0LWVuY29kZWQsIGRlY29kZSBpdFxuICBpZiAoZXZlbnQuYm9keSAmJiBldmVudC5pc0Jhc2U2NEVuY29kZWQpIHtcbiAgICBjb25zdCBidWZmID0gQnVmZmVyLmZyb20oZXZlbnQuYm9keSEsICdiYXNlNjQnKTtcbiAgICBib2R5ID0gYnVmZi50b1N0cmluZygndXRmOCcpO1xuICB9XG5cbiAgLy8gSWYgdGhlIHJlcXVlc3QgYm9keSBpcyBpbiBKU09OIGZvcm1hdCwgcGFyc2UgaXQgaW50byBhIEphdmFTY3JpcHQgb2JqZWN0XG4gIGlmIChoZWFkZXJWYWx1ZShldmVudC5oZWFkZXJzLCAnY29udGVudC10eXBlJyk/LmluY2x1ZGVzKCdhcHBsaWNhdGlvbi9qc29uJykpIHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShib2R5ID8/ICd7fScpO1xuICB9XG5cbiAgLy8gSWYgdGhlIHJlcXVlc3QgYm9keSBpcyBub3QgcHJlc2VudCBvciBub3QgaW4gSlNPTiBmb3JtYXQsIHJldHVybiBpdCBhcy1pc1xuICByZXR1cm4gYm9keSBhcyBhbnk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBDT1JTIGhlYWRlcnMgdG8gYmUgaW5jbHVkZWQgaW4gdGhlIEFQSSBHYXRld2F5IHJlc3BvbnNlLlxuICpcbiAqIEBwYXJhbSBldmVudCAtIFRoZSBBUEkgR2F0ZXdheSBldmVudCBvYmplY3QuXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgQ09SUyBoZWFkZXJzLlxuICovXG5mdW5jdGlvbiBjb3JzSGVhZGVyKGV2ZW50OiBBV1NMYW1iZGEuQVBJR2F0ZXdheVByb3h5V2l0aENvZ25pdG9BdXRob3JpemVyRXZlbnQpOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gIGNvbnN0IG9yaWdpbiA9IGhlYWRlclZhbHVlKGV2ZW50Py5oZWFkZXJzLCAnb3JpZ2luJyk7XG4gIHJldHVybiB7XG4gICAgJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbic6IG9yaWdpbiA/PyAnKicsIC8vIEFsbG93IHJlcXVlc3RzIGZyb20gdGhlIG9yaWdpbiBoZWFkZXIsIG9yIGFsbG93IGFueSBvcmlnaW4gaWYgbm90IHByZXNlbnRcbiAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctQ3JlZGVudGlhbHMnOiBvcmlnaW4gPyAndHJ1ZScgOiAnZmFsc2UnLCAvLyBJbmNsdWRlIGNvb2tpZXMgaW4gY3Jvc3Mtb3JpZ2luIHJlcXVlc3RzIGlmIHRoZSBvcmlnaW4gaGVhZGVyIGlzIHByZXNlbnRcbiAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctTWV0aG9kcyc6ICcqJywgLy8gQWxsb3cgYW55IEhUVFAgbWV0aG9kXG4gICAgJ0FjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnOiAnQXV0aG9yaXphdGlvbiwgKicsIC8vIEFsbG93IHRoZSBBdXRob3JpemF0aW9uIGhlYWRlciBhbmQgYW55IG90aGVyIGhlYWRlcnNcbiAgfTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLy8gQXBwU3luY1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogVGhlIGNvbnRleHQgZm9yIHRoZSBBcHBTeW5jIHJlc29sdmVyIGZ1bmN0aW9uLlxuICogQ29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGV2ZW50LCBsYW1iZGEgY29udGV4dCwgbG9nZ2VyLCBhbmQgQ29nbml0byBhdXRob3JpemVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcFN5bmNIYW5kbGVyQ29udGV4dDxUPiB7XG4gIGV2ZW50OiBBV1NMYW1iZGEuQXBwU3luY1Jlc29sdmVyRXZlbnQ8VD47XG4gIGxhbWJkYUNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0O1xuICBsb2dnZXI6IGxvZ2dlci5MYW1iZGFMb2c7XG4gIGNvZ25pdG9BdXRoOiBDb2duaXRvQXV0aG9yaXplcjtcbn1cblxuLyoqXG4gKiBBIGZ1bmN0aW9uIHRoYXQgaGFuZGxlcyBhbiBBcHBTeW5jIHJlc29sdmVyIGV2ZW50LlxuICogUmVjZWl2ZXMgdGhlIGNvbnRleHQgb2JqZWN0IGFuZCByZXR1cm5zIHRoZSByZXNwb25zZS5cbiAqL1xuZXhwb3J0IHR5cGUgQXBwU3luY0hhbmRsZXI8VCwgUj4gPSAoXG4gIGNvbnRleHQ6IEFwcFN5bmNIYW5kbGVyQ29udGV4dDxUPixcbikgPT4gUHJvbWlzZTxSPjtcblxuLyoqXG4gKiBNYXBzIGFuIEhUVFAgc3RhdHVzIGNvZGUgdG8gdGhlIEdyYXBoUUwgZXJyb3JUeXBlIHJlcG9ydGVkIHRvIEFwcFN5bmMuXG4gKlxuICogTG9jYWwgKG5vbi1leHBvcnRlZCkgaGVscGVyIHVzZWQgb25seSBieSBjcmVhdGVBcHBTeW5jSGFuZGxlciB3aGVuIGl0XG4gKiB0cmFuc2xhdGVzIGFuIGVycm9ycy5IdHRwRXJyb3IgaW50byBhIHR5cGVkIEFwcFN5bmMgZXJyb3IuIFRoZSBleHBsaWNpdFxuICogZGVmYXVsdCBrZWVwcyBhbnkgdW5tYXBwZWQgc3RhdHVzIChmb3IgZXhhbXBsZSBhIDQxOCBvciBhIDV4eCkgcmVwb3J0ZWQgYXNcbiAqIHRoZSBnZW5lcmljICdFcnJvcicgZXJyb3JUeXBlIHJhdGhlciB0aGFuIGxlYWtpbmcgdGhlIHJhdyBzdGF0dXMgY29kZS5cbiAqL1xuZnVuY3Rpb24gaHR0cFN0YXR1c1RvRXJyb3JUeXBlKHN0YXR1c0NvZGU6IG51bWJlcik6IHN0cmluZyB7XG4gIHN3aXRjaCAoc3RhdHVzQ29kZSkge1xuICAgIGNhc2UgNDAwOlxuICAgICAgcmV0dXJuICdCYWRSZXF1ZXN0JztcbiAgICBjYXNlIDQwMTpcbiAgICAgIHJldHVybiAnVW5hdXRob3JpemVkJztcbiAgICBjYXNlIDQwMzpcbiAgICAgIHJldHVybiAnRm9yYmlkZGVuJztcbiAgICBjYXNlIDQwNDpcbiAgICAgIHJldHVybiAnTm90Rm91bmQnO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gJ0Vycm9yJztcbiAgfVxufVxuXG4vKipcbiAqIFRoZSB0eXBlZC1lcnJvciBzaGFwZSBzaGFyZWQgYnkgY3JlYXRlQXBwU3luY0hhbmRsZXIgYW5kIGNyZWF0ZUFwcFN5bmNCYXRjaEhhbmRsZXIuXG4gKi9cbmludGVyZmFjZSBUeXBlZEFwcFN5bmNFcnJvciB7XG4gIGVycm9yVHlwZTogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIGVycm9ySW5mbz86IFJlY29yZDxzdHJpbmcsIGFueT47XG59XG5cbi8qKlxuICogTm9ybWFsaXNlcyB0aGUgdHdvIHJlY29nbmlzZWQgdHlwZWQtZXJyb3Igc2hhcGVzIHRvIGEgY29tbW9uXG4gKiB7IGVycm9yVHlwZSwgbWVzc2FnZSwgZXJyb3JJbmZvIH0gc28gdGhlIGdhdGUsIGVudmVsb3BlIGFuZCByZXRocm93IGFyZSBhXG4gKiBzaW5nbGUgY29kZSBwYXRoIGFjcm9zcyB0aGUgc2luZ2xlIGFuZCBiYXRjaCBoYW5kbGVycy4gUmV0dXJucyB1bmRlZmluZWQgZm9yXG4gKiBhbnl0aGluZyB0aGF0IGlzIG5laXRoZXIgKHBsYWluIEVycm9yLCBCb29tKSwgd2hpY2ggdGhlIGNhbGxlcnMgcmV0aHJvdy5cbiAqXG4gKiAtIGFwcHN5bmNFcnJvcnMuQXBwU3luY0Vycm9yIGNhcnJpZXMgaXRzIG93biBHcmFwaFFMIGVycm9yVHlwZSBhbmQgYW4gb3B0aW9uYWxcbiAqICAgZXJyb3JJbmZvLCB3aGljaCBmbG93IHRocm91Z2ggdW5jaGFuZ2VkLlxuICogLSBlcnJvcnMuSHR0cEVycm9yICh0aGUgSFRUUCBiYXNlIHRocm93biBieSB0aGUgc2hhcmVkIEp3dEF1dGhvcml6ZXIgdmlhXG4gKiAgIGFzc2VydEF1dGhlbnRpY2F0ZWQvYXNzZXJ0R3JvdXAvYXNzZXJ0QWRtaW4sIGFuZCBieSByZXNvbHZlciBjb2RlIGRpcmVjdGx5KVxuICogICBoYXMgbm8gR3JhcGhRTCBlcnJvclR5cGUsIHNvIG1hcCBpdHMgc3RhdHVzQ29kZSB3aXRoIGh0dHBTdGF0dXNUb0Vycm9yVHlwZS5cbiAqICAgSHR0cEVycm9yIGNhcnJpZXMgbm8gZXJyb3JJbmZvLCBzbyBlcnJvckluZm8gaXMgdW5kZWZpbmVkLlxuICpcbiAqIFRoZSB0d28gaW5zdGFuY2VvZiBjaGVja3MgYXJlIGRpc2pvaW50OiBIdHRwRXJyb3IgYW5kIEFwcFN5bmNFcnJvciBzaGFyZSBub1xuICogYW5jZXN0cnksIHNvIGFuIGFwcHN5bmMuRm9yYmlkZGVuRXJyb3IgdGFrZXMgdGhlIEFwcFN5bmNFcnJvciBicmFuY2ggYW5kIGFuXG4gKiBlcnJvcnMuRm9yYmlkZGVuRXJyb3IgdGhlIEh0dHBFcnJvciBicmFuY2guXG4gKi9cbmZ1bmN0aW9uIHRvVHlwZWRFcnJvcihlcnJvcjogYW55KTogVHlwZWRBcHBTeW5jRXJyb3IgfCB1bmRlZmluZWQge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBhcHBzeW5jRXJyb3JzLkFwcFN5bmNFcnJvcikge1xuICAgIHJldHVybiB7IGVycm9yVHlwZTogZXJyb3IuZXJyb3JUeXBlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLCBlcnJvckluZm86IGVycm9yLmVycm9ySW5mbyB9O1xuICB9IGVsc2UgaWYgKGVycm9yIGluc3RhbmNlb2YgZXJyb3JzLkh0dHBFcnJvcikge1xuICAgIHJldHVybiB7IGVycm9yVHlwZTogaHR0cFN0YXR1c1RvRXJyb3JUeXBlKGVycm9yLnN0YXR1c0NvZGUpLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLCBlcnJvckluZm86IHVuZGVmaW5lZCB9O1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBkaXJlY3QtTGFtYmRhIGVycm9yIGVudmVsb3BlIEFwcFN5bmMgc3VyZmFjZXMgYXMgYSB0eXBlZCBHcmFwaFFMXG4gKiBlcnJvci4gX19hcHBTeW5jRXJyb3IgaXMgYSByZXNlcnZlZCBzZW50aW5lbCBrZXkgdGhlIHJlc29sdmVyIHJlc3BvbnNlIGhhbmRsZXJcbiAqIGtleXMgb24gdG8gcmVjb2duaXNlIHRoaXMgZW52ZWxvcGUuIEJyYW5jaGluZyBvbiB0aGUgc2VudGluZWwgKHJhdGhlciB0aGFuIG9uXG4gKiBhIGJhcmUgZXJyb3JNZXNzYWdlKSBtZWFucyBhIGxlZ2l0aW1hdGUgcmVzb2x2ZXIgcmVzdWx0IHRoYXQgbWVyZWx5IGNvbnRhaW5zXG4gKiBhbiBlcnJvck1lc3NhZ2UgZmllbGQgaXMgbm90IG1pc2NsYXNzaWZpZWQgYXMgYSB0eXBlZCBlcnJvci5cbiAqL1xuZnVuY3Rpb24gYnVpbGRFcnJvckVudmVsb3BlPFI+KHR5cGVkOiBUeXBlZEFwcFN5bmNFcnJvcik6IFIge1xuICByZXR1cm4ge1xuICAgIF9fYXBwU3luY0Vycm9yOiB0cnVlLFxuICAgIGRhdGE6IG51bGwsXG4gICAgZXJyb3JUeXBlOiB0eXBlZC5lcnJvclR5cGUsXG4gICAgZXJyb3JNZXNzYWdlOiB0eXBlZC5tZXNzYWdlLFxuICAgIGVycm9ySW5mbzogdHlwZWQuZXJyb3JJbmZvLFxuICB9IGFzIHVua25vd24gYXMgUjtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIEFwcFN5bmMgcmVzb2x2ZXIgaGFuZGxlciBmcm9tIHRoZSBnaXZlbiBBcHBTeW5jSGFuZGxlci5cbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IGNhbiBiZSB1c2VkIGFzIGFuIEFwcFN5bmMgcmVzb2x2ZXIuXG4gKlxuICogQHBhcmFtIGhhbmRsZXIgVGhlIEFwcFN5bmNIYW5kbGVyIHRvIHVzZSBhcyB0aGUgcmVzb2x2ZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVBcHBTeW5jSGFuZGxlciA9XG4gIDxULCBSPihoYW5kbGVyOiBBcHBTeW5jSGFuZGxlcjxULCBSPik6IEFXU0xhbWJkYS5BcHBTeW5jUmVzb2x2ZXJIYW5kbGVyPFQsIFI+ID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKGV2ZW50LCBjb250ZXh0KSA9PiB7XG4gICAgICBjb25zdCBjdHg6IEFwcFN5bmNIYW5kbGVyQ29udGV4dDxUPiA9IHtcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIGxhbWJkYUNvbnRleHQ6IGNvbnRleHQsXG4gICAgICAgIGxvZ2dlcjogbG9nZ2VyIGFzIHVua25vd24gYXMgbG9nZ2VyLkxhbWJkYUxvZyxcbiAgICAgICAgY29nbml0b0F1dGg6IG5ldyBBcHBTeW5jQ29nbml0b0F1dGhvcml6ZXIoZXZlbnQpLFxuICAgICAgfTtcblxuICAgICAgLy8gc2V0IHRoZSBtZXRhIGluZm9ybWF0aW9uIGluIGxvZ2dlclxuICAgICAgY3R4LmxvZ2dlci5vcHRpb25zLm1ldGEucmVxdWVzdElkID0gY29udGV4dC5hd3NSZXF1ZXN0SWQ7XG4gICAgICAvLyBzZXQgdGhlIGRlYnVnIGZsYWcgZm9yIGxvZ2dlclxuICAgICAgY3R4LmxvZ2dlci5vcHRpb25zLmRlYnVnID0gcHJvY2Vzcy5lbnYuREVCVUcgPT09ICd0cnVlJztcblxuICAgICAgLy8gbG9nIHRoZSByZWNlaXZlZCBldmVudFxuICAgICAgY3R4LmxvZ2dlci5kZWJ1ZyhKU09OLnN0cmluZ2lmeShldmVudCkpO1xuXG4gICAgICB0cnkge1xuICAgICAgICAvLyBhdXRoZW50aWNhdGUgdGhlIGluY29taW5nIHJlcXVlc3RcbiAgICAgICAgYXdhaXQgY3R4LmNvZ25pdG9BdXRoLmF1dGhlbnRpY2F0ZSgpO1xuICAgICAgICAvLyBpbnZva2UgdGhlIGhhbmRsZXIgZnVuY3Rpb24gd2l0aCB0aGUgY29udGV4dFxuICAgICAgICByZXR1cm4gYXdhaXQgaGFuZGxlcihjdHgpO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICBjb25zdCB0eXBlZCA9IHRvVHlwZWRFcnJvcihlcnJvcik7XG5cbiAgICAgICAgaWYgKHR5cGVkICYmIHByb2Nlc3MuZW52LkFQUFNZTkNfVFlQRURfRVJST1JTID09PSAndHJ1ZScpIHtcbiAgICAgICAgICAvLyBUaGUgZW52ZWxvcGUtcmV0dXJuIGlzIGdhdGVkIG9uIEFQUFNZTkNfVFlQRURfRVJST1JTID09PSAndHJ1ZScuXG4gICAgICAgICAgLy8gR3JhcGhRbEFwaS5hZGRMYW1iZGFSZXNvbHZlciBpbmplY3RzIHRoYXQgZW52IHZhciBvbmx5IG9uIGl0c1xuICAgICAgICAgIC8vIHR5cGVkRXJyb3JzOiB0cnVlIHBhdGgsIHdob3NlIEFQUFNZTkNfSlMgcmVzb2x2ZXIgaGFzIGEgcmVzcG9uc2VcbiAgICAgICAgICAvLyBoYW5kbGVyIHRoYXQgcmVhZHMgdGhpcyBlbnZlbG9wZSBhbmQgY2FsbHNcbiAgICAgICAgICAvLyB1dGlsLmVycm9yKGVycm9yTWVzc2FnZSwgZXJyb3JUeXBlLCBudWxsLCBlcnJvckluZm8pLCB0dXJuaW5nIGl0IGludG9cbiAgICAgICAgICAvLyBhIEdyYXBoUUwgZXJyb3Igb24gYSBzdWNjZXNzZnVsIGludm9jYXRpb24uIFJldHVybmluZyAobm90IHRocm93aW5nKVxuICAgICAgICAgIC8vIGtlZXBzIHRoZSBpbnZvY2F0aW9uIG9mZiB0aGUgTGFtYmRhIEVycm9ycyBtZXRyaWMuXG4gICAgICAgICAgLy9cbiAgICAgICAgICAvLyBXaGVuIHRoZSBlbnYgdmFyIGlzIGFic2VudCAodGhlIGRlZmF1bHQgVU5JVCByZXNvbHZlciBwYXRoLCBvciBhXG4gICAgICAgICAgLy8gaGFuZC13aXJlZCBoYW5kbGVyIHVzZWQgd2l0aG91dCBHcmFwaFFsQXBpKSB0aGUgdHlwZWQgZXJyb3IgZmFsbHNcbiAgICAgICAgICAvLyB0aHJvdWdoIHRvIHRoZSByZXRocm93IGJlbG93LCBzbyB0aGUgaW52b2NhdGlvbiBmYWlscyBsb3VkbHkgaW5zdGVhZFxuICAgICAgICAgIC8vIG9mIHN1cmZhY2luZyB0aGUgZW52ZWxvcGUgYXMgZmllbGQgZGF0YS4gQW55IHZhbHVlIG90aGVyIHRoYW4gdGhlXG4gICAgICAgICAgLy8gZXhhY3Qgc3RyaW5nICd0cnVlJyBtZWFucyByZXRocm93LiBUaGlzIGlzIHdoeSBhIGRlZmF1bHQgVU5JVFxuICAgICAgICAgIC8vIHJlc29sdmVyIHdob3NlIGhhbmRsZXIgaGl0cyBhbiBhdXRoIGFzc2VydGlvbiAoYW4gSHR0cEVycm9yKSBzdGlsbFxuICAgICAgICAgIC8vIGZhaWxzIGxvdWRseSB1bmxlc3MgdHlwZWRFcnJvcnMgaXMgYWN0aXZlLlxuICAgICAgICAgIGN0eC5sb2dnZXIud2Fybih0eXBlZC5tZXNzYWdlLCB7IGVycm9yVHlwZTogdHlwZWQuZXJyb3JUeXBlLCBlcnJvckluZm86IHR5cGVkLmVycm9ySW5mbyB9KTtcbiAgICAgICAgICByZXR1cm4gYnVpbGRFcnJvckVudmVsb3BlPFI+KHR5cGVkKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBsb2cgdGhlIGVycm9yIGFuZCB0aHJvdyBpdCBhZ2FpblxuICAgICAgICBjdHgubG9nZ2VyLmVycm9yKGVycm9yKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfTtcbiAgfTtcblxuLyoqXG4gKiBUaGUgY29udGV4dCBmb3IgYSBiYXRjaGVkIEFwcFN5bmMgcmVzb2x2ZXIgZnVuY3Rpb24uXG4gKiBFeHRlbmRzIEFwcFN5bmNIYW5kbGVyQ29udGV4dCBzbyBoYW5kbGVyIGNvZGUgdGhhdCByZWFkcyBjdHguZXZlbnQuYXJndW1lbnRzIC9cbiAqIGN0eC5ldmVudC5pZGVudGl0eSBrZWVwcyB3b3JraW5nIGFnYWluc3QgdGhlIGZpcnN0IGV2ZW50LCBhbmQgYWRkaXRpb25hbGx5XG4gKiBleHBvc2VzIHRoZSBmdWxsIGJhdGNoIG9mIGV2ZW50cyBzbyB0aGUgaGFuZGxlciBjYW4gbWFwIG92ZXIgaXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBwU3luY0JhdGNoSGFuZGxlckNvbnRleHQ8VCwgUyBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gfCBudWxsID0gUmVjb3JkPHN0cmluZywgYW55PiB8IG51bGw+IGV4dGVuZHMgQXBwU3luY0hhbmRsZXJDb250ZXh0PFQ+IHtcbiAgZXZlbnQ6IEFXU0xhbWJkYS5BcHBTeW5jUmVzb2x2ZXJFdmVudDxULCBTPjtcbiAgZXZlbnRzOiBBV1NMYW1iZGEuQXBwU3luY1Jlc29sdmVyRXZlbnQ8VCwgUz5bXTtcbn1cblxuLyoqXG4gKiBBIGZ1bmN0aW9uIHRoYXQgaGFuZGxlcyBhbiBBcHBTeW5jIEJhdGNoSW52b2tlIGV2ZW50LlxuICogUmVjZWl2ZXMgdGhlIGJhdGNoIGNvbnRleHQgYW5kIHJldHVybnMgdGhlIHJlc3BvbnNlcyBpbiBzb3VyY2Ugb3JkZXIuXG4gKi9cbmV4cG9ydCB0eXBlIEFwcFN5bmNCYXRjaEhhbmRsZXI8VCwgUiwgUyBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gfCBudWxsID0gUmVjb3JkPHN0cmluZywgYW55PiB8IG51bGw+ID0gKFxuICBjb250ZXh0OiBBcHBTeW5jQmF0Y2hIYW5kbGVyQ29udGV4dDxULCBTPixcbikgPT4gUHJvbWlzZTxSW10+O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBiYXRjaGVkIEFwcFN5bmMgcmVzb2x2ZXIgaGFuZGxlciBmcm9tIHRoZSBnaXZlbiBBcHBTeW5jQmF0Y2hIYW5kbGVyLlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgYXMgYW4gQXBwU3luYyBCYXRjaEludm9rZSByZXNvbHZlcjogYXJyYXlcbiAqIGluLCBhcnJheSBvdXQsIG9yZGVyIHByZXNlcnZlZC5cbiAqXG4gKiBJdCBtaXJyb3JzIGNyZWF0ZUFwcFN5bmNIYW5kbGVyJ3MgY29udGV4dCBhbmQgYXV0aCBwbHVtYmluZyBidXQgb3BlcmF0ZXMgb24gYW5cbiAqIGFycmF5IG9mIGV2ZW50cy4gQXV0aGVudGljYXRpb24gcnVucyBvbmNlIHBlciBiYXRjaCBvZmYgdGhlIGZpcnN0IGV2ZW50LCBhbmRcbiAqIHRoZSBjb250ZXh0IGNhcnJpZXMgYm90aCB0aGUgZmlyc3QgZXZlbnQgKGN0eC5ldmVudCA9IGV2ZW50c1swXSkgYW5kIHRoZSBmdWxsXG4gKiBjdHguZXZlbnRzIGFycmF5LiBUaGUgaGFuZGxlciByZXR1cm5zIFJbXSBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGUgaW5wdXQgZXZlbnRzLlxuICpcbiAqIEBwYXJhbSBoYW5kbGVyIFRoZSBBcHBTeW5jQmF0Y2hIYW5kbGVyIHRvIHVzZSBhcyB0aGUgcmVzb2x2ZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVBcHBTeW5jQmF0Y2hIYW5kbGVyID1cbiAgPFQsIFIsIFMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgbnVsbCA9IFJlY29yZDxzdHJpbmcsIGFueT4gfCBudWxsPihcbiAgICBoYW5kbGVyOiBBcHBTeW5jQmF0Y2hIYW5kbGVyPFQsIFIsIFM+LFxuICApOiBBV1NMYW1iZGEuQXBwU3luY0JhdGNoUmVzb2x2ZXJIYW5kbGVyPFQsIFIsIFM+ID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKGV2ZW50cywgY29udGV4dCkgPT4ge1xuICAgICAgLy8gQmF0Y2hJbnZva2UgYWx3YXlzIGRlbGl2ZXJzIGEgbm9uLWVtcHR5IGFycmF5OyBhdXRoZW50aWNhdGUgYW5kIGJ1aWxkXG4gICAgICAvLyB0aGUgY29udGV4dCBvZmYgdGhlIGZpcnN0IGV2ZW50LCBleGFjdGx5IGxpa2UgY3JlYXRlQXBwU3luY0hhbmRsZXIuXG4gICAgICBjb25zdCBmaXJzdCA9IGV2ZW50c1swXTtcbiAgICAgIGNvbnN0IGN0eDogQXBwU3luY0JhdGNoSGFuZGxlckNvbnRleHQ8VCwgUz4gPSB7XG4gICAgICAgIGV2ZW50OiBmaXJzdCxcbiAgICAgICAgZXZlbnRzLFxuICAgICAgICBsYW1iZGFDb250ZXh0OiBjb250ZXh0LFxuICAgICAgICBsb2dnZXI6IGxvZ2dlciBhcyB1bmtub3duIGFzIGxvZ2dlci5MYW1iZGFMb2csXG4gICAgICAgIGNvZ25pdG9BdXRoOiBuZXcgQXBwU3luY0NvZ25pdG9BdXRob3JpemVyKGZpcnN0KSxcbiAgICAgIH07XG5cbiAgICAgIC8vIHNldCB0aGUgbWV0YSBpbmZvcm1hdGlvbiBpbiBsb2dnZXJcbiAgICAgIGN0eC5sb2dnZXIub3B0aW9ucy5tZXRhLnJlcXVlc3RJZCA9IGNvbnRleHQuYXdzUmVxdWVzdElkO1xuICAgICAgLy8gc2V0IHRoZSBkZWJ1ZyBmbGFnIGZvciBsb2dnZXJcbiAgICAgIGN0eC5sb2dnZXIub3B0aW9ucy5kZWJ1ZyA9IHByb2Nlc3MuZW52LkRFQlVHID09PSAndHJ1ZSc7XG5cbiAgICAgIC8vIGxvZyB0aGUgcmVjZWl2ZWQgYmF0Y2ggb2YgZXZlbnRzXG4gICAgICBjdHgubG9nZ2VyLmRlYnVnKEpTT04uc3RyaW5naWZ5KGV2ZW50cykpO1xuXG4gICAgICB0cnkge1xuICAgICAgICAvLyBhdXRoZW50aWNhdGUgb25jZSBwZXIgYmF0Y2ggb2ZmIHRoZSBmaXJzdCBldmVudFxuICAgICAgICBhd2FpdCBjdHguY29nbml0b0F1dGguYXV0aGVudGljYXRlKCk7XG4gICAgICAgIC8vIGludm9rZSB0aGUgaGFuZGxlciBmdW5jdGlvbiB3aXRoIHRoZSBiYXRjaCBjb250ZXh0OyBpdCByZXR1cm5zIFJbXSBpbiBzb3VyY2Ugb3JkZXJcbiAgICAgICAgcmV0dXJuIGF3YWl0IGhhbmRsZXIoY3R4KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgY29uc3QgdHlwZWQgPSB0b1R5cGVkRXJyb3IoZXJyb3IpO1xuXG4gICAgICAgIGlmICh0eXBlZCAmJiBwcm9jZXNzLmVudi5BUFBTWU5DX1RZUEVEX0VSUk9SUyA9PT0gJ3RydWUnKSB7XG4gICAgICAgICAgLy8gU2FtZSBnYXRlIGFuZCBlbnZlbG9wZSBhcyBjcmVhdGVBcHBTeW5jSGFuZGxlci4gQXBwU3luYyBleHBlY3RzIG9uZVxuICAgICAgICAgIC8vIHJlc3VsdCBwZXIgZXZlbnQgaW4gYSBCYXRjaEludm9rZSByZXNwb25zZSwgc28gYSBiYXRjaC1sZXZlbCB0eXBlZFxuICAgICAgICAgIC8vIGVycm9yIHJldHVybnMgYW4gYXJyYXkgb2YgZW52ZWxvcGVzIGFsaWduZWQgdG8gdGhlIGJhdGNoIGxlbmd0aDtcbiAgICAgICAgICAvLyBlYWNoIGl0ZW0gc3VyZmFjZXMgdGhlIHNhbWUgdHlwZWQgZXJyb3IuIFJldHVybmluZyAobm90IHRocm93aW5nKVxuICAgICAgICAgIC8vIGtlZXBzIHRoZSBpbnZvY2F0aW9uIG9mZiB0aGUgTGFtYmRhIEVycm9ycyBtZXRyaWMuIFdpdGhvdXQgdGhlIGZsYWdcbiAgICAgICAgICAvLyB0aGUgdHlwZWQgZXJyb3IgZmFsbHMgdGhyb3VnaCB0byB0aGUgcmV0aHJvdyBiZWxvdy5cbiAgICAgICAgICBjdHgubG9nZ2VyLndhcm4odHlwZWQubWVzc2FnZSwgeyBlcnJvclR5cGU6IHR5cGVkLmVycm9yVHlwZSwgZXJyb3JJbmZvOiB0eXBlZC5lcnJvckluZm8gfSk7XG4gICAgICAgICAgcmV0dXJuIGV2ZW50cy5tYXAoKCkgPT4gYnVpbGRFcnJvckVudmVsb3BlPFI+KHR5cGVkKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gbG9nIHRoZSBlcnJvciBhbmQgdGhyb3cgaXQgYWdhaW5cbiAgICAgICAgY3R4LmxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgIH07XG4gIH07XG5cbiJdfQ==
package/llm.md CHANGED
@@ -182,6 +182,49 @@ export const handler = createAppSyncHandler<GetItemsQuery, GetItemsResult>(async
182
182
  });
183
183
  ```
184
184
 
185
+ For AppSync BatchInvoke, use `createAppSyncBatchHandler`. It takes an array of resolver events and returns an array of results in the same order (array in, array out, order preserved). It uses the same context as `createAppSyncHandler`, with the logger and the Cognito authorizer resolved once per batch off the first event. The context exposes both the first event as `ctx.event` (so handler code that reads `ctx.event.arguments` / `ctx.event.identity` keeps working) and the full batch as `ctx.events`. The typed-error model is identical to `createAppSyncHandler`: with `APPSYNC_TYPED_ERRORS === 'true'` a thrown `errors.appsync.*` or `errors.HttpError` returns an array of error envelopes aligned to the batch length, and otherwise rethrows. A plain `Error` always fails the invocation.
186
+
187
+ ```typescript
188
+ import { createAppSyncBatchHandler } from 'cdk-serverless/lambda';
189
+
190
+ export const handler = createAppSyncBatchHandler<GetItemQuery, Item>(async (ctx) => {
191
+ return Promise.all(ctx.events.map((event) => getItem(event.arguments.id)));
192
+ });
193
+ ```
194
+
195
+ AppSync resolvers can throw typed errors from the `errors.appsync` namespace. `createAppSyncHandler` catches them and logs at `warn`. Whether it returns a `{ data, errorType, errorMessage, errorInfo }` envelope or rethrows is gated on the `APPSYNC_TYPED_ERRORS` environment variable. When `APPSYNC_TYPED_ERRORS === 'true'` the handler returns the envelope so the invocation stays off the Lambda Errors metric. Otherwise it rethrows the typed error, logging at `error`, so the invocation fails. A plain `Error` always fails the invocation regardless of the flag.
196
+
197
+ ```typescript
198
+ import { createAppSyncHandler, errors } from 'cdk-serverless/lambda';
199
+
200
+ export const handler = createAppSyncHandler<GetItemQuery, Item>(async (ctx) => {
201
+ const item = await getItem(ctx.arguments.id);
202
+
203
+ if (!item) {
204
+ throw new errors.appsync.NotFoundError('Item not found');
205
+ }
206
+
207
+ return item;
208
+ });
209
+ ```
210
+
211
+ HTTP errors from the shared authorizer are translated the same way. The shared `JwtAuthorizer` base throws `errors.UnauthenticatedError` (401) and `errors.ForbiddenError` (403) from `assertAuthenticated`/`assertGroup`/`assertAdmin`, and `AppSyncCognitoAuthorizer` extends that base, so these reach `createAppSyncHandler`'s catch. `createAppSyncHandler` treats any `errors.HttpError` like a typed error and maps its `statusCode` to an `errorType`: 400 `BadRequest`, 401 `Unauthorized`, 403 `Forbidden`, 404 `NotFound`, any other status `Error`. The mapped error goes through the same `APPSYNC_TYPED_ERRORS` gate and `{ __appSyncError: true, ... }` envelope as `errors.appsync.*` (with `errorInfo` undefined, since `HttpError` carries none). `src/lambda/auth.ts` and the HTTP handler `createHttpHandler` are unchanged. The same rethrow-when-not-activated rule applies, so a default UNIT resolver whose handler hits an auth assertion still fails loudly unless `typedErrors` is active.
212
+
213
+ The envelope only becomes a GraphQL error when the resolver is wired via `GraphQlApi.addLambdaResolver` and the API opts in with `typedErrors: true`. On that path the method creates an `APPSYNC_JS` pipeline resolver whose response handler reads the envelope and calls `util.error(errorMessage, errorType, null, errorInfo)` (and `util.appendError` for invoke-level errors), turning the typed error into a GraphQL error with the matching `errorType` and `errorInfo`. Without `typedErrors: true`, `addLambdaResolver` creates a plain direct-Lambda UNIT resolver with no response handler, so the envelope is surfaced as the field's data instead. If you build the resolver yourself, replicate that response handler.
214
+
215
+ The response handler recognises the envelope by a reserved `__appSyncError` sentinel key that `createAppSyncHandler` stamps, not by the presence of an `errorMessage` field. A resolver whose real return type happens to include an `errorMessage` field is therefore passed through unchanged.
216
+
217
+ Opting in with `typedErrors`: by default `addLambdaResolver` synthesizes a plain direct-Lambda UNIT resolver (the pre-#385 shape), so upgrading consumers who do not opt in see no resolver topology change and no `cdk diff` surprise. Set `typedErrors: true` on the `GraphQlApi` to get the typed `errors.appsync.*` behavior. With the flag enabled, each Lambda-backed field gains a new `AWS::AppSync::FunctionConfiguration` (`LambdaFn${type}.${field}`), and the resolver flips from a `dataSource` UNIT resolver to a `pipelineConfig` + `code` PIPELINE resolver with the response handler described above. The data source and resolver logical IDs are unchanged, so the resolver updates in place rather than being replaced, while the new per-field function resource is additive. The flag applies to all Lambda resolvers on the API, so run `cdk diff` after enabling it to review the topology change.
218
+
219
+ `maxBatchSize` wins over `typedErrors` per field. When a field passes `maxBatchSize` to `addLambdaResolver`, that field always gets the UNIT BatchInvoke resolver (MaxBatchSize plus the BatchInvoke request template and the `lambdaResult` response template), even when the API has `typedErrors: true`. The batch field gets no APPSYNC_JS pipeline, no `AWS::AppSync::FunctionConfiguration`, and no `APPSYNC_TYPED_ERRORS` env var on its Lambda, so it synthesizes identically whether or not the API enables `typedErrors`. The trade-off is that typed errors thrown by a batch handler are not converted to GraphQL errors. They rethrow and fail the invocation, so do not rely on the typed-error-to-GraphQL-error conversion in a batch handler. Non-batch fields on the same API keep the `typedErrors` pipeline behavior described above.
220
+
221
+ `APPSYNC_TYPED_ERRORS` is the coupling mechanism between the handler and the pipeline. `createAppSyncHandler` returns the `{ __appSyncError: true, ... }` sentinel envelope only when `APPSYNC_TYPED_ERRORS === 'true'` is set in the Lambda environment, and rethrows the `errors.appsync.*` error otherwise. `GraphQlApi.addLambdaResolver` injects `APPSYNC_TYPED_ERRORS=true` automatically on the `typedErrors: true` path, the same path that carries the response handler to translate the envelope. On the default UNIT path the flag is left unset, so a handler that throws an `errors.appsync.*` error fails the invocation loudly (rethrow) instead of returning a broken envelope as field data. If you wire `createAppSyncHandler` yourself without `GraphQlApi`, set `APPSYNC_TYPED_ERRORS=true` on the Lambda yourself to get envelope behavior and replicate the response handler. Without it, typed errors rethrow.
222
+
223
+ Two classes share the short names `ForbiddenError` and `NotFoundError`, so pick the namespace deliberately:
224
+
225
+ - `errors.ForbiddenError` / `errors.NotFoundError` are HTTP errors (HTTP 403 / 404) for `createHttpHandler`. They carry a `statusCode`.
226
+ - `errors.appsync.ForbiddenError` / `errors.appsync.NotFoundError` are AppSync errors for `createAppSyncHandler`. They carry a GraphQL `errorType` (`'Forbidden'` / `'NotFound'`), not an HTTP status code.
227
+
185
228
  #### Error Handling
186
229
 
187
230
  ```typescript
package/package.json CHANGED
@@ -101,7 +101,7 @@
101
101
  "publishConfig": {
102
102
  "access": "public"
103
103
  },
104
- "version": "3.3.3",
104
+ "version": "3.5.0",
105
105
  "jest": {
106
106
  "coverageProvider": "v8",
107
107
  "testMatch": [