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.
- 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/GraphQlApiProps.html +24 -3
- 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/experiments/appsync-unit-resolver-error-probe.md +201 -0
- 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 +3 -3
- package/docs/lambda/classes/errors.HttpError.html +3 -3
- package/docs/lambda/classes/errors.NotFoundError.html +3 -3
- package/docs/lambda/classes/errors.UnauthenticatedError.html +1 -1
- package/docs/lambda/classes/errors.appsync.AppSyncError.html +193 -0
- package/docs/lambda/classes/errors.appsync.ConflictError.html +184 -0
- package/docs/lambda/classes/errors.appsync.ForbiddenError.html +184 -0
- package/docs/lambda/classes/errors.appsync.NotFoundError.html +184 -0
- package/docs/lambda/classes/errors.appsync.ValidationError.html +184 -0
- package/docs/lambda/functions/api.createAppSyncBatchHandler.html +57 -0
- package/docs/lambda/hierarchy.html +16 -5
- 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/modules/errors.appsync.html +38 -0
- package/docs/lambda/modules/errors.html +4 -0
- package/docs/lambda/types/api.AppSyncBatchHandler.html +53 -0
- package/lib/constructs/graphql.d.ts +40 -1
- package/lib/constructs/graphql.js +103 -3
- package/lib/lambda/appsync-errors.d.ts +67 -0
- package/lib/lambda/appsync-errors.js +91 -0
- package/lib/lambda/errors.d.ts +1 -0
- package/lib/lambda/errors.js +36 -2
- package/lib/lambda/handler.d.ts +28 -0
- package/lib/lambda/handler.js +142 -2
- package/llm.md +43 -0
- package/package.json +1 -1
package/lib/lambda/handler.js
CHANGED
|
@@ -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
|