cdk-serverless 3.4.0 → 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.
- package/docs/constructs/assets/hierarchy.js +1 -1
- package/docs/constructs/assets/navigation.js +1 -1
- package/docs/constructs/assets/search.js +1 -1
- package/docs/constructs/classes/GraphQlApi.html +4 -3
- package/docs/constructs/classes/McpAuth.html +1 -1
- package/docs/constructs/classes/McpCognitoAuth.html +1 -1
- package/docs/constructs/classes/RestApi.html +1 -1
- package/docs/constructs/classes/SingleTableDatastore.html +1 -1
- package/docs/constructs/classes/Workflow.html +1 -1
- package/docs/constructs/hierarchy.html +5 -5
- package/docs/constructs/interfaces/LambdaResolverOptions.html +72 -0
- package/docs/constructs/interfaces/RestApiProps.html +1 -1
- package/docs/constructs/modules.html +2 -2
- package/docs/lambda/assets/hierarchy.js +1 -1
- package/docs/lambda/assets/navigation.js +1 -1
- package/docs/lambda/assets/search.js +1 -1
- package/docs/lambda/classes/errors.BadRequestError.html +1 -1
- package/docs/lambda/classes/errors.ForbiddenError.html +1 -1
- package/docs/lambda/classes/errors.HttpError.html +1 -1
- package/docs/lambda/classes/errors.NotFoundError.html +1 -1
- package/docs/lambda/classes/errors.UnauthenticatedError.html +1 -1
- package/docs/lambda/classes/errors.appsync.AppSyncError.html +1 -1
- package/docs/lambda/classes/errors.appsync.ConflictError.html +1 -1
- package/docs/lambda/classes/errors.appsync.ForbiddenError.html +1 -1
- package/docs/lambda/classes/errors.appsync.NotFoundError.html +1 -1
- package/docs/lambda/classes/errors.appsync.ValidationError.html +1 -1
- package/docs/lambda/functions/api.createAppSyncBatchHandler.html +57 -0
- package/docs/lambda/hierarchy.html +14 -10
- package/docs/lambda/interfaces/api.AppSyncBatchHandlerContext.html +89 -0
- package/docs/lambda/interfaces/api.AppSyncHandlerContext.html +6 -0
- package/docs/lambda/modules/api.html +6 -6
- package/docs/lambda/types/api.AppSyncBatchHandler.html +53 -0
- package/lib/constructs/graphql.d.ts +23 -1
- package/lib/constructs/graphql.js +26 -2
- package/lib/lambda/handler.d.ts +28 -0
- package/lib/lambda/handler.js +101 -38
- package/llm.md +12 -0
- package/package.json +1 -1
package/lib/lambda/handler.js
CHANGED
|
@@ -36,7 +36,7 @@ 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
42
|
const appsyncErrors = __importStar(require("./appsync-errors"));
|
|
@@ -221,6 +221,48 @@ function httpStatusToErrorType(statusCode) {
|
|
|
221
221
|
return 'Error';
|
|
222
222
|
}
|
|
223
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
|
+
}
|
|
224
266
|
/**
|
|
225
267
|
* Creates an AppSync resolver handler from the given AppSyncHandler.
|
|
226
268
|
* Returns a function that can be used as an AppSync resolver.
|
|
@@ -248,29 +290,7 @@ const createAppSyncHandler = (handler) => {
|
|
|
248
290
|
return await handler(ctx);
|
|
249
291
|
}
|
|
250
292
|
catch (error) {
|
|
251
|
-
|
|
252
|
-
// { errorType, message, errorInfo } so the gate, envelope and rethrow
|
|
253
|
-
// below are a single code path.
|
|
254
|
-
//
|
|
255
|
-
// - appsyncErrors.AppSyncError carries its own GraphQL errorType and an
|
|
256
|
-
// optional errorInfo, which flow through unchanged.
|
|
257
|
-
// - errors.HttpError (the HTTP base thrown by the shared JwtAuthorizer
|
|
258
|
-
// via assertAuthenticated/assertGroup/assertAdmin, and by resolver
|
|
259
|
-
// code directly) has no GraphQL errorType, so map its statusCode with
|
|
260
|
-
// httpStatusToErrorType. HttpError carries no errorInfo, so errorInfo
|
|
261
|
-
// is undefined.
|
|
262
|
-
//
|
|
263
|
-
// The two instanceof checks are disjoint: HttpError and AppSyncError
|
|
264
|
-
// share no ancestry, so an appsync.ForbiddenError takes the AppSyncError
|
|
265
|
-
// branch and an errors.ForbiddenError the HttpError branch. Anything that
|
|
266
|
-
// is neither (plain Error, Boom) leaves typed undefined and rethrows.
|
|
267
|
-
let typed;
|
|
268
|
-
if (error instanceof appsyncErrors.AppSyncError) {
|
|
269
|
-
typed = { errorType: error.errorType, message: error.message, errorInfo: error.errorInfo };
|
|
270
|
-
}
|
|
271
|
-
else if (error instanceof errors.HttpError) {
|
|
272
|
-
typed = { errorType: httpStatusToErrorType(error.statusCode), message: error.message, errorInfo: undefined };
|
|
273
|
-
}
|
|
293
|
+
const typed = toTypedError(error);
|
|
274
294
|
if (typed && process.env.APPSYNC_TYPED_ERRORS === 'true') {
|
|
275
295
|
// The envelope-return is gated on APPSYNC_TYPED_ERRORS === 'true'.
|
|
276
296
|
// GraphQlApi.addLambdaResolver injects that env var only on its
|
|
@@ -287,20 +307,8 @@ const createAppSyncHandler = (handler) => {
|
|
|
287
307
|
// exact string 'true' means rethrow. This is why a default UNIT
|
|
288
308
|
// resolver whose handler hits an auth assertion (an HttpError) still
|
|
289
309
|
// fails loudly unless typedErrors is active.
|
|
290
|
-
//
|
|
291
|
-
// __appSyncError is a reserved sentinel key the resolver response
|
|
292
|
-
// handler keys on to recognise this envelope. Branching on the sentinel
|
|
293
|
-
// (rather than on a bare errorMessage) means a legitimate resolver result
|
|
294
|
-
// that merely contains an errorMessage field is not misclassified as a
|
|
295
|
-
// typed error.
|
|
296
310
|
ctx.logger.warn(typed.message, { errorType: typed.errorType, errorInfo: typed.errorInfo });
|
|
297
|
-
return
|
|
298
|
-
__appSyncError: true,
|
|
299
|
-
data: null,
|
|
300
|
-
errorType: typed.errorType,
|
|
301
|
-
errorMessage: typed.message,
|
|
302
|
-
errorInfo: typed.errorInfo,
|
|
303
|
-
};
|
|
311
|
+
return buildErrorEnvelope(typed);
|
|
304
312
|
}
|
|
305
313
|
// log the error and throw it again
|
|
306
314
|
ctx.logger.error(error);
|
|
@@ -309,4 +317,59 @@ const createAppSyncHandler = (handler) => {
|
|
|
309
317
|
};
|
|
310
318
|
};
|
|
311
319
|
exports.createAppSyncHandler = createAppSyncHandler;
|
|
312
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sYW1iZGEvaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxxQ0FBOEI7QUFDOUIsNERBQStDO0FBQy9DLGdFQUFrRDtBQUNsRCxpQ0FNZ0I7QUFDaEIsaURBQW1DO0FBNkRuQzs7R0FFRztBQUNJLE1BQU0sbUNBQW1DLEdBQUcsQ0FBK0QsT0FBMEgsRUFBdUIsRUFBRTtJQUNuUSxPQUFPLElBQUEseUJBQWlCLEVBQUMsT0FBTyxDQUFDLENBQUM7QUFDcEMsQ0FBQyxDQUFDO0FBRlcsUUFBQSxtQ0FBbUMsdUNBRTlDO0FBRUY7O0dBRUc7QUFDSSxNQUFNLDZDQUE2QyxHQUFHLENBQXNDLE9BQTRFLEVBQXVCLEVBQUU7SUFDdE0sT0FBTyxJQUFBLHlCQUFpQixFQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3BDLENBQUMsQ0FBQztBQUZXLFFBQUEsNkNBQTZDLGlEQUV4RDtBQUVGOztHQUVHO0FBQ0ksTUFBTSxvQkFBb0IsR0FBRyxDQUFnRCxPQUE2RSxFQUF1QixFQUFFO0lBQ3hMLE9BQU8sSUFBQSx5QkFBaUIsRUFBQyxPQUFPLENBQUMsQ0FBQztBQUNwQyxDQUFDLENBQUM7QUFGVyxRQUFBLG9CQUFvQix3QkFFL0I7QUFFRjs7R0FFRztBQUNILE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxLQUFxRixFQUFFLEdBQWMsRUFBRSxFQUFFO0lBQ2pJLGlIQUFpSDtJQUNqSCxJQUFJLGFBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNyQixPQUFPLElBQUksb0NBQTZCLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7U0FBTSxDQUFDO1FBQ04sZ0dBQWdHO1FBQ2hHLE9BQU8sSUFBSSxnQ0FBeUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lB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RSxJQUFJO29CQUNWLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUztvQkFDMUIsWUFBWSxFQUFFLEtBQUssQ0FBQyxPQUFPO29CQUMzQixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7aUJBQ1gsQ0FBQztZQUNwQixDQUFDO1lBQ0QsbUNBQW1DO1lBQ25DLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3hCLE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUMsQ0FBQztBQUNKLENBQUMsQ0FBQztBQW5GUyxRQUFBLG9CQUFvQix3QkFtRjdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZW52IH0gZnJvbSAncHJvY2Vzcyc7XG5pbXBvcnQgbG9nZ2VyLCB7IExhbWJkYUxvZyB9IGZyb20gJ2xhbWJkYS1sb2cnO1xuaW1wb3J0ICogYXMgYXBwc3luY0Vycm9ycyBmcm9tICcuL2FwcHN5bmMtZXJyb3JzJztcbmltcG9ydCB7XG4gIEFwaUdhdGV3YXl2MUNvZ25pdG9BdXRob3JpemVyLFxuICBBcGlHYXRld2F5djFKd3RBdXRob3JpemVyLFxuICBBcHBTeW5jQ29nbml0b0F1dGhvcml6ZXIsXG4gIENvZ25pdG9BdXRob3JpemVyLFxuICBKd3RBdXRob3JpemVyLFxufSBmcm9tICcuL2F1dGgnO1xuaW1wb3J0ICogYXMgZXJyb3JzIGZyb20gJy4vZXJyb3JzJztcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLyBIVFRQIEFwaVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHByb3BlcnRpZXMgZm9yIGFuIEhUVFAgcmVzcG9uc2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSHR0cFJlc3BvbnNlQ29udGV4dCB7XG4gIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gIGhlYWRlcnM6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9O1xuICBqc29uOiBib29sZWFuO1xufVxuXG4vKipcbiAqIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIGZvciBhbiBIVFRQIHJlcXVlc3QgaGFuZGxlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIdHRwSGFuZGxlckNvbnRleHQge1xuICBldmVudDogQVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eVdpdGhDb2duaXRvQXV0aG9yaXplckV2ZW50O1xuICBsYW1iZGFDb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dDtcbiAgbG9nZ2VyOiBsb2dnZXIuTGFtYmRhTG9nO1xuICByZXNwb25zZTogSHR0cFJlc3BvbnNlQ29udGV4dDtcbiAgYXV0aDogSnd0QXV0aG9yaXplcjtcbn1cblxuLyoqXG4gKiBBIHR5cGUgZGVmaW5pdGlvbiBmb3IgYW4gSFRUUCBoYW5kbGVyLlxuICovXG5leHBvcnQgdHlwZSBIdHRwSGFuZGxlcjxULCBSPiA9IChcbiAgY29udGV4dDogSHR0cEhhbmRsZXJDb250ZXh0LFxuICBib2R5OiBULFxuKSA9PiBQcm9taXNlPFI+O1xuXG4vKipcbiAqIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIGZvciBhbiBPcGVuQVBJIG9wZXJhdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcGVyYXRpb24ge1xuICByZXNwb25zZXM6IHtcbiAgICBbc3RhdHVzQ29kZTogbnVtYmVyXToge1xuICAgICAgY29udGVudDoge1xuICAgICAgICAnYXBwbGljYXRpb24vanNvbic6IGFueTtcbiAgICAgIH07XG4gICAgfSB8IGFueTtcbiAgfTtcbn1cblxuLyoqXG4gKiBBIHR5cGUgZGVmaW5pdGlvbiBmb3IgYW4gQVBJIEdhdGV3YXkgdjEgcmVxdWVzdCBoYW5kbGVyLlxuICovXG5leHBvcnQgdHlwZSBBUElHYXRld2F5djFIYW5kbGVyID1cbiAgQVdTTGFtYmRhLkhhbmRsZXI8QVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eVdpdGhDb2duaXRvQXV0aG9yaXplckV2ZW50LCBBV1NMYW1iZGEuQVBJR2F0ZXdheVByb3h5UmVzdWx0IHwgdW5kZWZpbmVkPjtcblxuLyoqXG4gKiBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgcHJvcGVydGllcyBmb3IgYW4gT3BlbkFQSSBvcGVyYXRpb24gd2l0aCBhIHJlcXVlc3QgYm9keS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcGVyYXRpb25XaXRoUmVxdWVzdEJvZHkgZXh0ZW5kcyBPcGVyYXRpb24ge1xuICByZXF1ZXN0Qm9keTogeyBjb250ZW50OiB7ICdhcHBsaWNhdGlvbi9qc29uJzogYW55IH0gfTtcbn1cblxuLyoqXG4gKiBBIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIGFuIEhUVFAgcmVxdWVzdCBoYW5kbGVyIGZvciBhbiBPcGVuQVBJIG9wZXJhdGlvbiB3aXRoIGEgcmVxdWVzdCBib2R5LlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlT3BlbkFwaUhhbmRsZXJXaXRoUmVxdWVzdEJvZHkgPSA8T1AgZXh0ZW5kcyBPcGVyYXRpb25XaXRoUmVxdWVzdEJvZHksIFNDIGV4dGVuZHMgbnVtYmVyID0gMjAwPihoYW5kbGVyOiBIdHRwSGFuZGxlcjxPUFsncmVxdWVzdEJvZHknXVsnY29udGVudCddWydhcHBsaWNhdGlvbi9qc29uJ10sIE9QWydyZXNwb25zZXMnXVtTQ11bJ2NvbnRlbnQnXVsnYXBwbGljYXRpb24vanNvbiddPik6IEFQSUdhdGV3YXl2MUhhbmRsZXIgPT4ge1xuICByZXR1cm4gY3JlYXRlSHR0cEhhbmRsZXIoaGFuZGxlcik7XG59O1xuXG4vKipcbiAqIEEgZmFjdG9yeSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYW4gSFRUUCByZXF1ZXN0IGhhbmRsZXIgZm9yIGFuIE9wZW5BUEkgb3BlcmF0aW9uIHdpdGggYSByZXF1ZXN0IGJvZHkgYW5kIG5vIHJlc3BvbnNlLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlT3BlbkFwaUhhbmRsZXJXaXRoUmVxdWVzdEJvZHlOb1Jlc3BvbnNlID0gPE9QIGV4dGVuZHMgT3BlcmF0aW9uV2l0aFJlcXVlc3RCb2R5PihoYW5kbGVyOiBIdHRwSGFuZGxlcjxPUFsncmVxdWVzdEJvZHknXVsnY29udGVudCddWydhcHBsaWNhdGlvbi9qc29uJ10sIHZvaWQ+KTogQVBJR2F0ZXdheXYxSGFuZGxlciA9PiB7XG4gIHJldHVybiBjcmVhdGVIdHRwSGFuZGxlcihoYW5kbGVyKTtcbn07XG5cbi8qKlxuICogQSBmYWN0b3J5IGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhbiBIVFRQIHJlcXVlc3QgaGFuZGxlciBmb3IgYW4gT3BlbkFQSSBvcGVyYXRpb24uXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVPcGVuQXBpSGFuZGxlciA9IDxPUCBleHRlbmRzIE9wZXJhdGlvbiwgU0MgZXh0ZW5kcyBudW1iZXIgPSAyMDA+KGhhbmRsZXI6IEh0dHBIYW5kbGVyPGFueSwgT1BbJ3Jlc3BvbnNlcyddW1NDXVsnY29udGVudCddWydhcHBsaWNhdGlvbi9qc29uJ10+KTogQVBJR2F0ZXdheXYxSGFuZGxlciA9PiB7XG4gIHJldHVybiBjcmVhdGVIdHRwSGFuZGxlcihoYW5kbGVyKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGFuIGF1dGhvcml6ZXIgZm9yIHRoZSBhdXRoZW50aWNhdGlvbiBtZXRob2QgY2hvc2VuIChKV1Qgb3IgQ29nbml0bykuXG4gKi9cbmNvbnN0IGNyZWF0ZUF1dGhvcml6ZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlFdmVudEJhc2U8QVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eUNvZ25pdG9BdXRob3JpemVyPiwgbG9nOiBMYW1iZGFMb2cpID0+IHtcbiAgLy8gSWYgQ29nbml0byBpcyB1c2VkLCBVU0VSX1BPT0xfSUQgaXMgaW5qZWN0ZWQgaW50byB0aGUgZnVuY3Rpb24ncyBlbnZpcm9ubWVudC4gQ3VycmVudGx5IGFzc3VtZXMgSldUIG90aGVyd2lzZS5cbiAgaWYgKGVudi5VU0VSX1BPT0xfSUQpIHtcbiAgICByZXR1cm4gbmV3IEFwaUdhdGV3YXl2MUNvZ25pdG9BdXRob3JpemVyKGV2ZW50LCBsb2cpO1xuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgbWlnaHQgbmVlZCB0byBnZXQgbW9yZSBzb3BoaXN0aWNhdGVkIGlmIG1vcmUgYXV0aG9yaXphdGlvbiBtZXRob2RzIG5lZWQgdG8gYmUgc3VwcG9ydGVkLlxuICAgIHJldHVybiBuZXcgQXBpR2F0ZXdheXYxSnd0QXV0aG9yaXplcihldmVudCwgJ2FkbWluJywgbG9nKTtcbiAgfVxufTtcblxuLyoqXG4gKiBBIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIGFuIEhUVFAgcmVxdWVzdCBoYW5kbGVyLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlSHR0cEhhbmRsZXIgPVxuICA8VCwgUj4oaGFuZGxlcjogSHR0cEhhbmRsZXI8VCwgUj4pOiBBUElHYXRld2F5djFIYW5kbGVyID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKGV2ZW50LCBjb250ZXh0KSA9PiB7XG4gICAgICAvLyBDcmVhdGUgYW4gb2JqZWN0IHRvIGhvbGQgdGhlIGNvbnRleHQgZm9yIHRoaXMgSFRUUCByZXF1ZXN0XG4gICAgICBjb25zdCBhdXRoID0gY3JlYXRlQXV0aG9yaXplcihldmVudCwgbG9nZ2VyIGFzIHVua25vd24gYXMgbG9nZ2VyLkxhbWJkYUxvZyk7XG4gICAgICBjb25zdCBjdHg6IEh0dHBIYW5kbGVyQ29udGV4dCA9IHtcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIGF1dGgsXG4gICAgICAgIGxhbWJkYUNvbnRleHQ6IGNvbnRleHQsXG4gICAgICAgIGxvZ2dlcjogbG9nZ2VyIGFzIHVua25vd24gYXMgbG9nZ2VyLkxhbWJkYUxvZyxcbiAgICAgICAgcmVzcG9uc2U6IHsgaGVhZGVyczoge30sIGpzb246IHRydWUgfSxcbiAgICAgIH07XG4gICAgICAvLyBBZGQgdGhlIHJlcXVlc3QgSUQgdG8gdGhlIGxvZ2dpbmcgbWV0YWRhdGEsIGFuZCBlbmFibGUgZGVidWcgbG9nZ2luZyBpZiB0aGUgREVCVUcgZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgc2V0IHRvIFwidHJ1ZVwiXG4gICAgICBjdHgubG9nZ2VyLm9wdGlvbnMubWV0YS5yZXF1ZXN0SWQgPSBjb250ZXh0LmF3c1JlcXVlc3RJZDtcbiAgICAgIGN0eC5sb2dnZXIub3B0aW9ucy5kZWJ1ZyA9IHByb2Nlc3MuZW52LkRFQlVHID09PSAndHJ1ZSc7XG5cbiAgICAgIC8vIExvZyB0aGUgZXZlbnQgb2JqZWN0IGZvciBkZWJ1Z2dpbmcgcHVycG9zZXNcbiAgICAgIGN0eC5sb2dnZXIuZGVidWcoSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gQXV0aGVudGljYXRlIHRoZSB1c2VyIHVzaW5nIHRoZSBDb2duaXRvIGF1dGhvcml6ZXJcbiAgICAgICAgYXdhaXQgY3R4LmF1dGguYXV0aGVudGljYXRlKCk7XG5cbiAgICAgICAgLy8gQ2FsbCB0aGUgdXNlci1kZWZpbmVkIGhhbmRsZXIgZnVuY3Rpb24sIHBhc3NpbmcgaW4gdGhlIHJlcXVlc3QgY29udGV4dCBvYmplY3QgYW5kIHRoZSBwYXJzZWQgcmVxdWVzdCBib2R5XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGhhbmRsZXIoY3R4LCBwYXJzZUJvZHkoZXZlbnQpKTtcblxuICAgICAgICAvLyBDb25zdHJ1Y3QgYW5kIHJldHVybiB0aGUgSFRUUCByZXNwb25zZVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN0YXR1c0NvZGU6IGN0eC5yZXNwb25zZS5zdGF0dXNDb2RlID8/IChyZXMgPyAyMDAgOiAyMDQpLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgIC4uLmN0eC5yZXNwb25zZS5oZWFkZXJzLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYm9keTogcmVzID8gKGN0eC5yZXNwb25zZS5qc29uID8gSlNPTi5zdHJpbmdpZnkocmVzKSA6IHJlcykgOiAnJyxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgLy8gSGFuZGxlIGFueSBlcnJvcnMgdGhhdCBvY2N1ciBkdXJpbmcgcmVxdWVzdCBwcm9jZXNzaW5nXG5cbiAgICAgICAgLy8gSWYgdGhlIGVycm9yIGlzIGFuIGluc3RhbmNlIG9mIEh0dHBFcnJvciwgcmV0dXJuIGFuIEhUVFAgcmVzcG9uc2Ugd2l0aCB0aGUgZXJyb3Igc3RhdHVzIGNvZGUgYW5kIG1lc3NhZ2VcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgZXJyb3JzLkh0dHBFcnJvcikge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXNDb2RlOiBlcnJvci5zdGF0dXNDb2RlLFxuICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgICAgLi4uY3R4LnJlc3BvbnNlLmhlYWRlcnMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYm9keTogZXJyb3IubWVzc2FnZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIC8vIElmIHRoZSBlcnJvciBpcyBhIEJvb20gZXJyb3IgKGZyb20gdGhlIGhhcGkuanMgZnJhbWV3b3JrKSwgcmV0dXJuIGFuIEhUVFAgcmVzcG9uc2Ugd2l0aCB0aGUgZXJyb3Igc3RhdHVzIGNvZGUgYW5kIHBheWxvYWRcbiAgICAgICAgaWYgKGVycm9yLmlzQm9vbSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXNDb2RlOiBlcnJvci5vdXRwdXQuc3RhdHVzQ29kZSxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgICAgLi4uZXJyb3Iub3V0cHV0LmhlYWRlcnMsXG4gICAgICAgICAgICAgIC4uLmNvcnNIZWFkZXIoZXZlbnQpLFxuICAgICAgICAgICAgICAuLi5jdHgucmVzcG9uc2UuaGVhZGVycyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShlcnJvci5vdXRwdXQucGF5bG9hZCksXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICAvLyBGb3IgYWxsIG90aGVyIHR5cGVzIG9mIGVycm9ycywgbG9nIHRoZSBlcnJvciBhbmQgcmV0dXJuIGEgNTAwIHN0YXR1cyBjb2RlIHdpdGggdGhlIGVycm9yIG1lc3NhZ2VcbiAgICAgICAgY3R4LmxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3RhdHVzQ29kZTogY3R4LnJlc3BvbnNlLnN0YXR1c0NvZGUgPz8gNTAwLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgIC4uLmN0eC5yZXNwb25zZS5oZWFkZXJzLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYm9keTogZXJyb3IudG9TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuXG4vKipcbiAqIExvb2tzIHVwIGEgaGVhZGVyIHZhbHVlIGNhc2UtaW5zZW5zaXRpdmVseS5cbiAqIEhUVFAgaGVhZGVyIG5hbWVzIGFyZSBjYXNlLWluc2Vuc2l0aXZlIHBlciBSRkMgOTExMCDCpzUuMS5cbiAqL1xuZnVuY3Rpb24gaGVhZGVyVmFsdWUoaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB8IG51bGwgfCB1bmRlZmluZWQsIG5hbWU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghaGVhZGVycykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3Qga2V5ID0gT2JqZWN0LmtleXMoaGVhZGVycykuZmluZChrID0+IGsudG9Mb3dlckNhc2UoKSA9PT0gbmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgcmV0dXJuIGtleSA/IGhlYWRlcnNba2V5XSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIHRha2VzIGFuIGV2ZW50IG9iamVjdCByZXByZXNlbnRpbmcgYW4gQVBJIEdhdGV3YXkgUHJveHkgZXZlbnRcbiAqIHdpdGggYSBDb2duaXRvIGF1dGhvcml6ZXIsIGFuZCBleHRyYWN0cyBhbmQgcGFyc2VzIHRoZSByZXF1ZXN0IGJvZHksIGlmIHByZXNlbnQuXG4gKlxuICogQHBhcmFtIGV2ZW50IFRoZSBBUEkgR2F0ZXdheSBQcm94eSBldmVudCB3aXRoIGEgQ29nbml0byBhdXRob3JpemVyXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIHJlcXVlc3QgYm9keVxuICovXG5mdW5jdGlvbiBwYXJzZUJvZHk8VD4oZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlXaXRoQ29nbml0b0F1dGhvcml6ZXJFdmVudCk6IFQge1xuICBsZXQgYm9keSA9IGV2ZW50LmJvZHk7XG5cbiAgLy8gSWYgdGhlIHJlcXVlc3QgYm9keSBpcyBiYXNlNjQtZW5jb2RlZCwgZGVjb2RlIGl0XG4gIGlmIChldmVudC5ib2R5ICYmIGV2ZW50LmlzQmFzZTY0RW5jb2RlZCkge1xuICAgIGNvbnN0IGJ1ZmYgPSBCdWZmZXIuZnJvbShldmVudC5ib2R5ISwgJ2Jhc2U2NCcpO1xuICAgIGJvZHkgPSBidWZmLnRvU3RyaW5nKCd1dGY4Jyk7XG4gIH1cblxuICAvLyBJZiB0aGUgcmVxdWVzdCBib2R5IGlzIGluIEpTT04gZm9ybWF0LCBwYXJzZSBpdCBpbnRvIGEgSmF2YVNjcmlwdCBvYmplY3RcbiAgaWYgKGhlYWRlclZhbHVlKGV2ZW50LmhlYWRlcnMsICdjb250ZW50LXR5cGUnKT8uaW5jbHVkZXMoJ2FwcGxpY2F0aW9uL2pzb24nKSkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKGJvZHkgPz8gJ3t9Jyk7XG4gIH1cblxuICAvLyBJZiB0aGUgcmVxdWVzdCBib2R5IGlzIG5vdCBwcmVzZW50IG9yIG5vdCBpbiBKU09OIGZvcm1hdCwgcmV0dXJuIGl0IGFzLWlzXG4gIHJldHVybiBib2R5IGFzIGFueTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgdGhlIENPUlMgaGVhZGVycyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgQVBJIEdhdGV3YXkgcmVzcG9uc2UuXG4gKlxuICogQHBhcmFtIGV2ZW50IC0gVGhlIEFQSSBHYXRld2F5IGV2ZW50IG9iamVjdC5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBDT1JTIGhlYWRlcnMuXG4gKi9cbmZ1bmN0aW9uIGNvcnNIZWFkZXIoZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlXaXRoQ29nbml0b0F1dGhvcml6ZXJFdmVudCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgY29uc3Qgb3JpZ2luID0gaGVhZGVyVmFsdWUoZXZlbnQ/LmhlYWRlcnMsICdvcmlnaW4nKTtcbiAgcmV0dXJuIHtcbiAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJzogb3JpZ2luID8/ICcqJywgLy8gQWxsb3cgcmVxdWVzdHMgZnJvbSB0aGUgb3JpZ2luIGhlYWRlciwgb3IgYWxsb3cgYW55IG9yaWdpbiBpZiBub3QgcHJlc2VudFxuICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFscyc6IG9yaWdpbiA/ICd0cnVlJyA6ICdmYWxzZScsIC8vIEluY2x1ZGUgY29va2llcyBpbiBjcm9zcy1vcmlnaW4gcmVxdWVzdHMgaWYgdGhlIG9yaWdpbiBoZWFkZXIgaXMgcHJlc2VudFxuICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJzogJyonLCAvLyBBbGxvdyBhbnkgSFRUUCBtZXRob2RcbiAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyc6ICdBdXRob3JpemF0aW9uLCAqJywgLy8gQWxsb3cgdGhlIEF1dGhvcml6YXRpb24gaGVhZGVyIGFuZCBhbnkgb3RoZXIgaGVhZGVyc1xuICB9O1xufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLyBBcHBTeW5jXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBUaGUgY29udGV4dCBmb3IgdGhlIEFwcFN5bmMgcmVzb2x2ZXIgZnVuY3Rpb24uXG4gKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZXZlbnQsIGxhbWJkYSBjb250ZXh0LCBsb2dnZXIsIGFuZCBDb2duaXRvIGF1dGhvcml6ZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBwU3luY0hhbmRsZXJDb250ZXh0PFQ+IHtcbiAgZXZlbnQ6IEFXU0xhbWJkYS5BcHBTeW5jUmVzb2x2ZXJFdmVudDxUPjtcbiAgbGFtYmRhQ29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQ7XG4gIGxvZ2dlcjogbG9nZ2VyLkxhbWJkYUxvZztcbiAgY29nbml0b0F1dGg6IENvZ25pdG9BdXRob3JpemVyO1xufVxuXG4vKipcbiAqIEEgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIGFuIEFwcFN5bmMgcmVzb2x2ZXIgZXZlbnQuXG4gKiBSZWNlaXZlcyB0aGUgY29udGV4dCBvYmplY3QgYW5kIHJldHVybnMgdGhlIHJlc3BvbnNlLlxuICovXG5leHBvcnQgdHlwZSBBcHBTeW5jSGFuZGxlcjxULCBSPiA9IChcbiAgY29udGV4dDogQXBwU3luY0hhbmRsZXJDb250ZXh0PFQ+LFxuKSA9PiBQcm9taXNlPFI+O1xuXG4vKipcbiAqIE1hcHMgYW4gSFRUUCBzdGF0dXMgY29kZSB0byB0aGUgR3JhcGhRTCBlcnJvclR5cGUgcmVwb3J0ZWQgdG8gQXBwU3luYy5cbiAqXG4gKiBMb2NhbCAobm9uLWV4cG9ydGVkKSBoZWxwZXIgdXNlZCBvbmx5IGJ5IGNyZWF0ZUFwcFN5bmNIYW5kbGVyIHdoZW4gaXRcbiAqIHRyYW5zbGF0ZXMgYW4gZXJyb3JzLkh0dHBFcnJvciBpbnRvIGEgdHlwZWQgQXBwU3luYyBlcnJvci4gVGhlIGV4cGxpY2l0XG4gKiBkZWZhdWx0IGtlZXBzIGFueSB1bm1hcHBlZCBzdGF0dXMgKGZvciBleGFtcGxlIGEgNDE4IG9yIGEgNXh4KSByZXBvcnRlZCBhc1xuICogdGhlIGdlbmVyaWMgJ0Vycm9yJyBlcnJvclR5cGUgcmF0aGVyIHRoYW4gbGVha2luZyB0aGUgcmF3IHN0YXR1cyBjb2RlLlxuICovXG5mdW5jdGlvbiBodHRwU3RhdHVzVG9FcnJvclR5cGUoc3RhdHVzQ29kZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgc3dpdGNoIChzdGF0dXNDb2RlKSB7XG4gICAgY2FzZSA0MDA6XG4gICAgICByZXR1cm4gJ0JhZFJlcXVlc3QnO1xuICAgIGNhc2UgNDAxOlxuICAgICAgcmV0dXJuICdVbmF1dGhvcml6ZWQnO1xuICAgIGNhc2UgNDAzOlxuICAgICAgcmV0dXJuICdGb3JiaWRkZW4nO1xuICAgIGNhc2UgNDA0OlxuICAgICAgcmV0dXJuICdOb3RGb3VuZCc7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAnRXJyb3InO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBBcHBTeW5jIHJlc29sdmVyIGhhbmRsZXIgZnJvbSB0aGUgZ2l2ZW4gQXBwU3luY0hhbmRsZXIuXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCBhcyBhbiBBcHBTeW5jIHJlc29sdmVyLlxuICpcbiAqIEBwYXJhbSBoYW5kbGVyIFRoZSBBcHBTeW5jSGFuZGxlciB0byB1c2UgYXMgdGhlIHJlc29sdmVyLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlQXBwU3luY0hhbmRsZXIgPVxuICA8VCwgUj4oaGFuZGxlcjogQXBwU3luY0hhbmRsZXI8VCwgUj4pOiBBV1NMYW1iZGEuQXBwU3luY1Jlc29sdmVySGFuZGxlcjxULCBSPiA9PiB7XG4gICAgcmV0dXJuIGFzeW5jIChldmVudCwgY29udGV4dCkgPT4ge1xuICAgICAgY29uc3QgY3R4OiBBcHBTeW5jSGFuZGxlckNvbnRleHQ8VD4gPSB7XG4gICAgICAgIGV2ZW50LFxuICAgICAgICBsYW1iZGFDb250ZXh0OiBjb250ZXh0LFxuICAgICAgICBsb2dnZXI6IGxvZ2dlciBhcyB1bmtub3duIGFzIGxvZ2dlci5MYW1iZGFMb2csXG4gICAgICAgIGNvZ25pdG9BdXRoOiBuZXcgQXBwU3luY0NvZ25pdG9BdXRob3JpemVyKGV2ZW50KSxcbiAgICAgIH07XG5cbiAgICAgIC8vIHNldCB0aGUgbWV0YSBpbmZvcm1hdGlvbiBpbiBsb2dnZXJcbiAgICAgIGN0eC5sb2dnZXIub3B0aW9ucy5tZXRhLnJlcXVlc3RJZCA9IGNvbnRleHQuYXdzUmVxdWVzdElkO1xuICAgICAgLy8gc2V0IHRoZSBkZWJ1ZyBmbGFnIGZvciBsb2dnZXJcbiAgICAgIGN0eC5sb2dnZXIub3B0aW9ucy5kZWJ1ZyA9IHByb2Nlc3MuZW52LkRFQlVHID09PSAndHJ1ZSc7XG5cbiAgICAgIC8vIGxvZyB0aGUgcmVjZWl2ZWQgZXZlbnRcbiAgICAgIGN0eC5sb2dnZXIuZGVidWcoSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gYXV0aGVudGljYXRlIHRoZSBpbmNvbWluZyByZXF1ZXN0XG4gICAgICAgIGF3YWl0IGN0eC5jb2duaXRvQXV0aC5hdXRoZW50aWNhdGUoKTtcbiAgICAgICAgLy8gaW52b2tlIHRoZSBoYW5kbGVyIGZ1bmN0aW9uIHdpdGggdGhlIGNvbnRleHRcbiAgICAgICAgcmV0dXJuIGF3YWl0IGhhbmRsZXIoY3R4KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgLy8gTm9ybWFsaXNlIHRoZSB0d28gcmVjb2duaXNlZCB0eXBlZC1lcnJvciBzaGFwZXMgdG8gYSBjb21tb25cbiAgICAgICAgLy8geyBlcnJvclR5cGUsIG1lc3NhZ2UsIGVycm9ySW5mbyB9IHNvIHRoZSBnYXRlLCBlbnZlbG9wZSBhbmQgcmV0aHJvd1xuICAgICAgICAvLyBiZWxvdyBhcmUgYSBzaW5nbGUgY29kZSBwYXRoLlxuICAgICAgICAvL1xuICAgICAgICAvLyAtIGFwcHN5bmNFcnJvcnMuQXBwU3luY0Vycm9yIGNhcnJpZXMgaXRzIG93biBHcmFwaFFMIGVycm9yVHlwZSBhbmQgYW5cbiAgICAgICAgLy8gICBvcHRpb25hbCBlcnJvckluZm8sIHdoaWNoIGZsb3cgdGhyb3VnaCB1bmNoYW5nZWQuXG4gICAgICAgIC8vIC0gZXJyb3JzLkh0dHBFcnJvciAodGhlIEhUVFAgYmFzZSB0aHJvd24gYnkgdGhlIHNoYXJlZCBKd3RBdXRob3JpemVyXG4gICAgICAgIC8vICAgdmlhIGFzc2VydEF1dGhlbnRpY2F0ZWQvYXNzZXJ0R3JvdXAvYXNzZXJ0QWRtaW4sIGFuZCBieSByZXNvbHZlclxuICAgICAgICAvLyAgIGNvZGUgZGlyZWN0bHkpIGhhcyBubyBHcmFwaFFMIGVycm9yVHlwZSwgc28gbWFwIGl0cyBzdGF0dXNDb2RlIHdpdGhcbiAgICAgICAgLy8gICBodHRwU3RhdHVzVG9FcnJvclR5cGUuIEh0dHBFcnJvciBjYXJyaWVzIG5vIGVycm9ySW5mbywgc28gZXJyb3JJbmZvXG4gICAgICAgIC8vICAgaXMgdW5kZWZpbmVkLlxuICAgICAgICAvL1xuICAgICAgICAvLyBUaGUgdHdvIGluc3RhbmNlb2YgY2hlY2tzIGFyZSBkaXNqb2ludDogSHR0cEVycm9yIGFuZCBBcHBTeW5jRXJyb3JcbiAgICAgICAgLy8gc2hhcmUgbm8gYW5jZXN0cnksIHNvIGFuIGFwcHN5bmMuRm9yYmlkZGVuRXJyb3IgdGFrZXMgdGhlIEFwcFN5bmNFcnJvclxuICAgICAgICAvLyBicmFuY2ggYW5kIGFuIGVycm9ycy5Gb3JiaWRkZW5FcnJvciB0aGUgSHR0cEVycm9yIGJyYW5jaC4gQW55dGhpbmcgdGhhdFxuICAgICAgICAvLyBpcyBuZWl0aGVyIChwbGFpbiBFcnJvciwgQm9vbSkgbGVhdmVzIHR5cGVkIHVuZGVmaW5lZCBhbmQgcmV0aHJvd3MuXG4gICAgICAgIGxldCB0eXBlZDogeyBlcnJvclR5cGU6IHN0cmluZzsgbWVzc2FnZTogc3RyaW5nOyBlcnJvckluZm8/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+IH0gfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIGFwcHN5bmNFcnJvcnMuQXBwU3luY0Vycm9yKSB7XG4gICAgICAgICAgdHlwZWQgPSB7IGVycm9yVHlwZTogZXJyb3IuZXJyb3JUeXBlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLCBlcnJvckluZm86IGVycm9yLmVycm9ySW5mbyB9O1xuICAgICAgICB9IGVsc2UgaWYgKGVycm9yIGluc3RhbmNlb2YgZXJyb3JzLkh0dHBFcnJvcikge1xuICAgICAgICAgIHR5cGVkID0geyBlcnJvclR5cGU6IGh0dHBTdGF0dXNUb0Vycm9yVHlwZShlcnJvci5zdGF0dXNDb2RlKSwgbWVzc2FnZTogZXJyb3IubWVzc2FnZSwgZXJyb3JJbmZvOiB1bmRlZmluZWQgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlZCAmJiBwcm9jZXNzLmVudi5BUFBTWU5DX1RZUEVEX0VSUk9SUyA9PT0gJ3RydWUnKSB7XG4gICAgICAgICAgLy8gVGhlIGVudmVsb3BlLXJldHVybiBpcyBnYXRlZCBvbiBBUFBTWU5DX1RZUEVEX0VSUk9SUyA9PT0gJ3RydWUnLlxuICAgICAgICAgIC8vIEdyYXBoUWxBcGkuYWRkTGFtYmRhUmVzb2x2ZXIgaW5qZWN0cyB0aGF0IGVudiB2YXIgb25seSBvbiBpdHNcbiAgICAgICAgICAvLyB0eXBlZEVycm9yczogdHJ1ZSBwYXRoLCB3aG9zZSBBUFBTWU5DX0pTIHJlc29sdmVyIGhhcyBhIHJlc3BvbnNlXG4gICAgICAgICAgLy8gaGFuZGxlciB0aGF0IHJlYWRzIHRoaXMgZW52ZWxvcGUgYW5kIGNhbGxzXG4gICAgICAgICAgLy8gdXRpbC5lcnJvcihlcnJvck1lc3NhZ2UsIGVycm9yVHlwZSwgbnVsbCwgZXJyb3JJbmZvKSwgdHVybmluZyBpdCBpbnRvXG4gICAgICAgICAgLy8gYSBHcmFwaFFMIGVycm9yIG9uIGEgc3VjY2Vzc2Z1bCBpbnZvY2F0aW9uLiBSZXR1cm5pbmcgKG5vdCB0aHJvd2luZylcbiAgICAgICAgICAvLyBrZWVwcyB0aGUgaW52b2NhdGlvbiBvZmYgdGhlIExhbWJkYSBFcnJvcnMgbWV0cmljLlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gV2hlbiB0aGUgZW52IHZhciBpcyBhYnNlbnQgKHRoZSBkZWZhdWx0IFVOSVQgcmVzb2x2ZXIgcGF0aCwgb3IgYVxuICAgICAgICAgIC8vIGhhbmQtd2lyZWQgaGFuZGxlciB1c2VkIHdpdGhvdXQgR3JhcGhRbEFwaSkgdGhlIHR5cGVkIGVycm9yIGZhbGxzXG4gICAgICAgICAgLy8gdGhyb3VnaCB0byB0aGUgcmV0aHJvdyBiZWxvdywgc28gdGhlIGludm9jYXRpb24gZmFpbHMgbG91ZGx5IGluc3RlYWRcbiAgICAgICAgICAvLyBvZiBzdXJmYWNpbmcgdGhlIGVudmVsb3BlIGFzIGZpZWxkIGRhdGEuIEFueSB2YWx1ZSBvdGhlciB0aGFuIHRoZVxuICAgICAgICAgIC8vIGV4YWN0IHN0cmluZyAndHJ1ZScgbWVhbnMgcmV0aHJvdy4gVGhpcyBpcyB3aHkgYSBkZWZhdWx0IFVOSVRcbiAgICAgICAgICAvLyByZXNvbHZlciB3aG9zZSBoYW5kbGVyIGhpdHMgYW4gYXV0aCBhc3NlcnRpb24gKGFuIEh0dHBFcnJvcikgc3RpbGxcbiAgICAgICAgICAvLyBmYWlscyBsb3VkbHkgdW5sZXNzIHR5cGVkRXJyb3JzIGlzIGFjdGl2ZS5cbiAgICAgICAgICAvL1xuICAgICAgICAgIC8vIF9fYXBwU3luY0Vycm9yIGlzIGEgcmVzZXJ2ZWQgc2VudGluZWwga2V5IHRoZSByZXNvbHZlciByZXNwb25zZVxuICAgICAgICAgIC8vIGhhbmRsZXIga2V5cyBvbiB0byByZWNvZ25pc2UgdGhpcyBlbnZlbG9wZS4gQnJhbmNoaW5nIG9uIHRoZSBzZW50aW5lbFxuICAgICAgICAgIC8vIChyYXRoZXIgdGhhbiBvbiBhIGJhcmUgZXJyb3JNZXNzYWdlKSBtZWFucyBhIGxlZ2l0aW1hdGUgcmVzb2x2ZXIgcmVzdWx0XG4gICAgICAgICAgLy8gdGhhdCBtZXJlbHkgY29udGFpbnMgYW4gZXJyb3JNZXNzYWdlIGZpZWxkIGlzIG5vdCBtaXNjbGFzc2lmaWVkIGFzIGFcbiAgICAgICAgICAvLyB0eXBlZCBlcnJvci5cbiAgICAgICAgICBjdHgubG9nZ2VyLndhcm4odHlwZWQubWVzc2FnZSwgeyBlcnJvclR5cGU6IHR5cGVkLmVycm9yVHlwZSwgZXJyb3JJbmZvOiB0eXBlZC5lcnJvckluZm8gfSk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIF9fYXBwU3luY0Vycm9yOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogbnVsbCxcbiAgICAgICAgICAgIGVycm9yVHlwZTogdHlwZWQuZXJyb3JUeXBlLFxuICAgICAgICAgICAgZXJyb3JNZXNzYWdlOiB0eXBlZC5tZXNzYWdlLFxuICAgICAgICAgICAgZXJyb3JJbmZvOiB0eXBlZC5lcnJvckluZm8sXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gbG9nIHRoZSBlcnJvciBhbmQgdGhyb3cgaXQgYWdhaW5cbiAgICAgICAgY3R4LmxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgIH07XG4gIH07XG5cbiJdfQ==
|
|
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,16 @@ 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
|
+
|
|
185
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.
|
|
186
196
|
|
|
187
197
|
```typescript
|
|
@@ -206,6 +216,8 @@ The response handler recognises the envelope by a reserved `__appSyncError` sent
|
|
|
206
216
|
|
|
207
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.
|
|
208
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
|
+
|
|
209
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.
|
|
210
222
|
|
|
211
223
|
Two classes share the short names `ForbiddenError` and `NotFoundError`, so pick the namespace deliberately:
|