@bitblit/ratchet-epsilon-common 6.0.146-alpha → 6.0.147-alpha
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/package.json +10 -9
- package/src/background/background-dynamo-log-table-handler.ts +44 -0
- package/src/background/background-entry.ts +4 -0
- package/src/background/background-execution-event-type.ts +9 -0
- package/src/background/background-execution-event.ts +9 -0
- package/src/background/background-execution-listener.ts +6 -0
- package/src/background/background-handler.ts +352 -0
- package/src/background/background-http-adapter-handler.ts +166 -0
- package/src/background/background-meta-response-internal.ts +5 -0
- package/src/background/background-process-handling.ts +6 -0
- package/src/background/background-process-log-table-entry.ts +11 -0
- package/src/background/background-queue-response-internal.ts +9 -0
- package/src/background/background-validator.ts +105 -0
- package/src/background/epsilon-background-process-error.ts +110 -0
- package/src/background/internal-background-entry.ts +10 -0
- package/src/background/manager/abstract-background-manager.ts +120 -0
- package/src/background/manager/aws-large-payload-s3-sqs-sns-background-manager.ts +87 -0
- package/src/background/manager/aws-sqs-sns-background-manager.ts +201 -0
- package/src/background/manager/background-manager-like.ts +44 -0
- package/src/background/manager/background-manager.spec.ts +89 -0
- package/src/background/manager/single-thread-local-background-manager.ts +58 -0
- package/src/background/s3-background-transaction-logger.ts +65 -0
- package/src/build/ratchet-epsilon-common-info.ts +19 -0
- package/src/built-in/background/echo-processor.ts +17 -0
- package/src/built-in/background/log-and-enqueue-echo-processor.ts +14 -0
- package/src/built-in/background/log-message-background-error-processor.ts +10 -0
- package/src/built-in/background/no-op-processor.ts +12 -0
- package/src/built-in/background/retry-processor.ts +51 -0
- package/src/built-in/background/sample-delay-processor.ts +15 -0
- package/src/built-in/background/sample-input-validated-processor-data.ts +4 -0
- package/src/built-in/background/sample-input-validated-processor.ts +14 -0
- package/src/built-in/built-in-trace-id-generators.ts +22 -0
- package/src/built-in/daemon/daemon-authorizer-function.ts +4 -0
- package/src/built-in/daemon/daemon-config.ts +9 -0
- package/src/built-in/daemon/daemon-group-selection-function.ts +3 -0
- package/src/built-in/daemon/daemon-handler.ts +87 -0
- package/src/built-in/daemon/daemon-process-state-list.ts +9 -0
- package/src/built-in/http/apollo/apollo-util.ts +43 -0
- package/src/built-in/http/apollo/default-epsilon-apollo-context.ts +11 -0
- package/src/built-in/http/apollo/epsilon-apollo-context-builder-options.ts +5 -0
- package/src/built-in/http/apollo/epsilon-lambda-apollo-context-function-argument.ts +6 -0
- package/src/built-in/http/apollo/epsilon-lambda-apollo-options.ts +11 -0
- package/src/built-in/http/apollo-filter.ts +151 -0
- package/src/built-in/http/built-in-auth-filters.ts +73 -0
- package/src/built-in/http/built-in-authorizers.ts +22 -0
- package/src/built-in/http/built-in-filters.spec.ts +26 -0
- package/src/built-in/http/built-in-filters.ts +300 -0
- package/src/built-in/http/built-in-handlers.ts +85 -0
- package/src/built-in/http/log-level-manipulation-filter.ts +26 -0
- package/src/built-in/http/run-handler-as-filter.spec.ts +67 -0
- package/src/built-in/http/run-handler-as-filter.ts +102 -0
- package/src/cli/ratchet-cli-handler.ts +23 -0
- package/src/cli/run-background-process-from-command-line.ts +32 -0
- package/src/config/background/background-aws-config.ts +8 -0
- package/src/config/background/background-config.ts +15 -0
- package/src/config/background/background-error-processor.ts +5 -0
- package/src/config/background/background-processor.ts +14 -0
- package/src/config/background/background-transaction-log.ts +9 -0
- package/src/config/background/background-transaction-logger.ts +6 -0
- package/src/config/cron/abstract-cron-entry.ts +17 -0
- package/src/config/cron/cron-background-entry.ts +17 -0
- package/src/config/cron/cron-config.ts +10 -0
- package/src/config/dynamo-db-config.ts +6 -0
- package/src/config/epsilon-config.ts +30 -0
- package/src/config/epsilon-lambda-event-handler.ts +12 -0
- package/src/config/epsilon-logger-config.ts +23 -0
- package/src/config/espilon-server-mode.ts +10 -0
- package/src/config/generic-aws-event-handler-function.ts +1 -0
- package/src/config/http/authorizer-function.ts +9 -0
- package/src/config/http/epsilon-authorization-context.ts +5 -0
- package/src/config/http/epsilon-cors-approach.ts +7 -0
- package/src/config/http/extended-api-gateway-event.ts +8 -0
- package/src/config/http/filter-chain-context.ts +15 -0
- package/src/config/http/filter-function.ts +3 -0
- package/src/config/http/handler-function.ts +4 -0
- package/src/config/http/http-config.ts +27 -0
- package/src/config/http/http-processing-config.ts +23 -0
- package/src/config/http/mapped-http-processing-config.ts +12 -0
- package/src/config/http/null-returned-object-handling.ts +7 -0
- package/src/config/inter-api/inter-api-aws-config.ts +5 -0
- package/src/config/inter-api/inter-api-config.ts +7 -0
- package/src/config/inter-api/inter-api-process-mapping.ts +11 -0
- package/src/config/local-server/local-server-event-logging-style.ts +8 -0
- package/src/config/local-server/local-server-http-method-handling.ts +7 -0
- package/src/config/local-server/local-server-options.ts +12 -0
- package/src/config/logging-trace-id-generator.ts +3 -0
- package/src/config/no-handlers-found-error.ts +6 -0
- package/src/config/open-api/open-api-document-components.ts +4 -0
- package/src/config/open-api/open-api-document.ts +7 -0
- package/src/config/s3-config.ts +8 -0
- package/src/config/sns-config.ts +7 -0
- package/src/config/sqs-config.ts +7 -0
- package/src/epsilon-build-properties.ts +21 -0
- package/src/epsilon-constants.ts +62 -0
- package/src/epsilon-global-handler.ts +238 -0
- package/src/epsilon-instance.ts +20 -0
- package/src/epsilon-logging-extension-processor.ts +19 -0
- package/src/http/auth/api-gateway-adapter-authentication-handler.ts +95 -0
- package/src/http/auth/auth0-web-token-manipulator.ts +69 -0
- package/src/http/auth/basic-auth-token.ts +7 -0
- package/src/http/auth/google-web-token-manipulator.spec.ts +15 -0
- package/src/http/auth/google-web-token-manipulator.ts +80 -0
- package/src/http/auth/jwt-ratchet-local-web-token-manipulator.ts +37 -0
- package/src/http/auth/local-web-token-manipulator.spec.ts +34 -0
- package/src/http/auth/local-web-token-manipulator.ts +114 -0
- package/src/http/auth/web-token-manipulator.ts +9 -0
- package/src/http/error/bad-gateway.ts +11 -0
- package/src/http/error/bad-request-error.ts +11 -0
- package/src/http/error/conflict-error.ts +12 -0
- package/src/http/error/forbidden-error.ts +12 -0
- package/src/http/error/gateway-timeout.ts +12 -0
- package/src/http/error/method-not-allowed-error.ts +12 -0
- package/src/http/error/misconfigured-error.ts +12 -0
- package/src/http/error/not-found-error.ts +12 -0
- package/src/http/error/not-implemented.ts +12 -0
- package/src/http/error/request-timeout-error.ts +12 -0
- package/src/http/error/service-unavailable.ts +12 -0
- package/src/http/error/too-many-requests-error.ts +12 -0
- package/src/http/error/unauthorized-error.ts +12 -0
- package/src/http/event-util.spec.ts +190 -0
- package/src/http/event-util.ts +272 -0
- package/src/http/response-util.spec.ts +117 -0
- package/src/http/response-util.ts +164 -0
- package/src/http/route/epsilon-router.ts +9 -0
- package/src/http/route/extended-auth-response-context.ts +7 -0
- package/src/http/route/route-and-parse.ts +8 -0
- package/src/http/route/route-mapping.ts +21 -0
- package/src/http/route/route-validator-config.ts +5 -0
- package/src/http/route/router-util.spec.ts +33 -0
- package/src/http/route/router-util.ts +314 -0
- package/src/http/web-handler.spec.ts +99 -0
- package/src/http/web-handler.ts +157 -0
- package/src/http/web-v2-handler.ts +34 -0
- package/src/inter-api/inter-api-entry.ts +8 -0
- package/src/inter-api/inter-api-util.spec.ts +77 -0
- package/src/inter-api/inter-api-util.ts +71 -0
- package/src/inter-api-manager.ts +75 -0
- package/src/lambda-event-handler/cron-epsilon-lambda-event-handler.spec.ts +130 -0
- package/src/lambda-event-handler/cron-epsilon-lambda-event-handler.ts +132 -0
- package/src/lambda-event-handler/dynamo-epsilon-lambda-event-handler.ts +42 -0
- package/src/lambda-event-handler/generic-sns-epsilon-lambda-event-handler.ts +38 -0
- package/src/lambda-event-handler/generic-sqs-epsilon-lambda-event-handler.ts +43 -0
- package/src/lambda-event-handler/inter-api-epsilon-lambda-event-handler.ts +33 -0
- package/src/lambda-event-handler/s3-epsilon-lambda-event-handler.ts +50 -0
- package/src/local-container-server.ts +128 -0
- package/src/local-server.spec.ts +16 -0
- package/src/local-server.ts +426 -0
- package/src/open-api-util/open-api-doc-modifications.ts +9 -0
- package/src/open-api-util/open-api-doc-modifier.spec.ts +22 -0
- package/src/open-api-util/open-api-doc-modifier.ts +90 -0
- package/src/open-api-util/yaml-combiner.spec.ts +26 -0
- package/src/open-api-util/yaml-combiner.ts +35 -0
- package/src/sample/sample-server-components-with-apollo.ts +87 -0
- package/src/sample/sample-server-components.ts +183 -0
- package/src/sample/sample-server-static-files.ts +614 -0
- package/src/sample/test-error-server.ts +140 -0
- package/src/util/aws-util.ts +89 -0
- package/src/util/context-global-data.ts +13 -0
- package/src/util/context-util.ts +156 -0
- package/src/util/cron-util.spec.ts +190 -0
- package/src/util/cron-util.ts +86 -0
- package/src/util/epsilon-config-parser.ts +90 -0
- package/src/util/epsilon-server-util.spec.ts +18 -0
- package/src/util/epsilon-server-util.ts +16 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { EpsilonRouter } from './epsilon-router.js';
|
|
2
|
+
import { MisconfiguredError } from '../error/misconfigured-error.js';
|
|
3
|
+
import { Logger } from '@bitblit/ratchet-common/logger/logger';
|
|
4
|
+
import { RouteMapping } from './route-mapping.js';
|
|
5
|
+
import { RouteValidatorConfig } from './route-validator-config.js';
|
|
6
|
+
import { JwtTokenBase } from '@bitblit/ratchet-common/jwt/jwt-token-base';
|
|
7
|
+
import { BooleanRatchet } from '@bitblit/ratchet-common/lang/boolean-ratchet';
|
|
8
|
+
import { OpenApiDocument } from '../../config/open-api/open-api-document.js';
|
|
9
|
+
import { ModelValidator } from '@bitblit/ratchet-misc/model-validator/model-validator';
|
|
10
|
+
import { BackgroundHttpAdapterHandler } from '../../background/background-http-adapter-handler.js';
|
|
11
|
+
import { HandlerFunction } from '../../config/http/handler-function.js';
|
|
12
|
+
import { HttpConfig } from '../../config/http/http-config.js';
|
|
13
|
+
import { AuthorizerFunction } from '../../config/http/authorizer-function.js';
|
|
14
|
+
import { HttpProcessingConfig } from '../../config/http/http-processing-config.js';
|
|
15
|
+
import { NullReturnedObjectHandling } from '../../config/http/null-returned-object-handling.js';
|
|
16
|
+
import { MappedHttpProcessingConfig } from '../../config/http/mapped-http-processing-config.js';
|
|
17
|
+
import { BuiltInFilters } from '../../built-in/http/built-in-filters.js';
|
|
18
|
+
import { WebTokenManipulator } from '../auth/web-token-manipulator.js';
|
|
19
|
+
import { BuiltInHandlers } from '../../built-in/http/built-in-handlers.js';
|
|
20
|
+
import { FilterFunction } from '../../config/http/filter-function.js';
|
|
21
|
+
import { BuiltInAuthFilters } from '../../built-in/http/built-in-auth-filters.js';
|
|
22
|
+
import { LogLevelManipulationFilter } from '../../built-in/http/log-level-manipulation-filter.js';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Endpoints about the api itself
|
|
26
|
+
*/
|
|
27
|
+
export class RouterUtil {
|
|
28
|
+
// Prevent instantiation
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
30
|
+
private constructor() {}
|
|
31
|
+
|
|
32
|
+
public static defaultAuthenticationHeaderParsingEpsilonPreFilters(
|
|
33
|
+
webTokenManipulator: WebTokenManipulator<JwtTokenBase>,
|
|
34
|
+
): FilterFunction[] {
|
|
35
|
+
return [
|
|
36
|
+
(fCtx) => BuiltInAuthFilters.parseAuthorizationHeader(fCtx, webTokenManipulator),
|
|
37
|
+
(fCtx) => BuiltInAuthFilters.applyOpenApiAuthorization(fCtx),
|
|
38
|
+
].concat(RouterUtil.defaultEpsilonPreFilters());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public static defaultEpsilonPreFilters(): FilterFunction[] {
|
|
42
|
+
return [
|
|
43
|
+
(fCtx) => BuiltInFilters.autoRespondToOptionsRequestWithCors(fCtx),
|
|
44
|
+
(fCtx) => BuiltInFilters.ensureEventMaps(fCtx),
|
|
45
|
+
(fCtx) => LogLevelManipulationFilter.setLogLevelForTransaction(fCtx),
|
|
46
|
+
(fCtx) => BuiltInFilters.parseJsonBodyToObject(fCtx),
|
|
47
|
+
(fCtx) => BuiltInFilters.fixStillEncodedQueryParams(fCtx),
|
|
48
|
+
(fCtx) => BuiltInFilters.uriDecodeQueryParams(fCtx),
|
|
49
|
+
(fCtx) => BuiltInFilters.disallowStringNullAsPathParameter(fCtx),
|
|
50
|
+
(fCtx) => BuiltInFilters.disallowStringNullAsQueryStringParameter(fCtx),
|
|
51
|
+
(fCtx) => BuiltInFilters.validateInboundBody(fCtx),
|
|
52
|
+
(fCtx) => BuiltInFilters.validateInboundQueryParams(fCtx),
|
|
53
|
+
(fCtx) => BuiltInFilters.validateInboundQueryParams(fCtx),
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public static defaultEpsilonPostFilters(): FilterFunction[] {
|
|
58
|
+
return [
|
|
59
|
+
(fCtx) => BuiltInFilters.validateOutboundResponse(fCtx),
|
|
60
|
+
(fCtx) => BuiltInFilters.addAWSRequestIdHeader(fCtx),
|
|
61
|
+
(fCtx) => BuiltInFilters.addAllowReflectionCORSHeaders(fCtx),
|
|
62
|
+
(fCtx) => BuiltInFilters.applyGzipIfPossible(fCtx),
|
|
63
|
+
(fCtx) => BuiltInFilters.checkMaximumLambdaBodySize(fCtx),
|
|
64
|
+
(fCtx) => LogLevelManipulationFilter.clearLogLevelForTransaction(fCtx),
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public static defaultEpsilonErrorFilters(): FilterFunction[] {
|
|
69
|
+
return [
|
|
70
|
+
(fCtx) => BuiltInFilters.addAWSRequestIdHeader(fCtx),
|
|
71
|
+
(fCtx) => BuiltInFilters.addAllowReflectionCORSHeaders(fCtx),
|
|
72
|
+
(fCtx) => LogLevelManipulationFilter.clearLogLevelForTransaction(fCtx),
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public static defaultHttpMetaProcessingConfigWithAuthenticationHeaderParsing(
|
|
77
|
+
webTokenManipulator: WebTokenManipulator<JwtTokenBase>,
|
|
78
|
+
): HttpProcessingConfig {
|
|
79
|
+
const defaults: HttpProcessingConfig = {
|
|
80
|
+
configName: 'EpsilonDefaultHttpMetaProcessingConfig',
|
|
81
|
+
timeoutMS: 30_000,
|
|
82
|
+
overrideAuthorizerName: null,
|
|
83
|
+
preFilters: RouterUtil.defaultAuthenticationHeaderParsingEpsilonPreFilters(webTokenManipulator),
|
|
84
|
+
postFilters: RouterUtil.defaultEpsilonPostFilters(),
|
|
85
|
+
errorFilters: RouterUtil.defaultEpsilonErrorFilters(),
|
|
86
|
+
nullReturnedObjectHandling: NullReturnedObjectHandling.Return404NotFoundResponse,
|
|
87
|
+
};
|
|
88
|
+
return defaults;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public static defaultHttpMetaProcessingConfig(): HttpProcessingConfig {
|
|
92
|
+
const defaults: HttpProcessingConfig = {
|
|
93
|
+
configName: 'EpsilonDefaultHttpMetaProcessingConfig',
|
|
94
|
+
timeoutMS: 30_000,
|
|
95
|
+
overrideAuthorizerName: null,
|
|
96
|
+
preFilters: RouterUtil.defaultEpsilonPreFilters(),
|
|
97
|
+
postFilters: RouterUtil.defaultEpsilonPostFilters(),
|
|
98
|
+
errorFilters: RouterUtil.defaultEpsilonErrorFilters(),
|
|
99
|
+
nullReturnedObjectHandling: NullReturnedObjectHandling.Return404NotFoundResponse,
|
|
100
|
+
};
|
|
101
|
+
return defaults;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public static assignDefaultsOnHttpConfig(cfg: HttpConfig): HttpConfig {
|
|
105
|
+
const defaults: HttpConfig = {
|
|
106
|
+
handlers: new Map<string, HandlerFunction<any>>(),
|
|
107
|
+
authorizers: new Map<string, AuthorizerFunction>(),
|
|
108
|
+
defaultMetaHandling: this.defaultHttpMetaProcessingConfig(),
|
|
109
|
+
staticContentRoutes: {},
|
|
110
|
+
prefixesToStripBeforeRouteMatch: [],
|
|
111
|
+
filterHandledRouteMatches: ['options .*'], // Ignore all Options since they are handled by the default prefilter
|
|
112
|
+
};
|
|
113
|
+
const rval: HttpConfig = Object.assign({}, defaults, cfg || {});
|
|
114
|
+
return rval;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Search the overrides in order to find a match, otherwise return default
|
|
118
|
+
public static findApplicableMeta(httpConfig: HttpConfig, method: string, path: string): HttpProcessingConfig {
|
|
119
|
+
let rval: HttpProcessingConfig = null;
|
|
120
|
+
if (httpConfig?.overrideMetaHandling) {
|
|
121
|
+
for (let i = 0; i < httpConfig.overrideMetaHandling.length && !rval; i++) {
|
|
122
|
+
const test: MappedHttpProcessingConfig = httpConfig.overrideMetaHandling[i];
|
|
123
|
+
if (
|
|
124
|
+
!test.methods ||
|
|
125
|
+
test.methods.length === 0 ||
|
|
126
|
+
test.methods.map((s) => s.toLocaleLowerCase()).includes(method.toLocaleLowerCase())
|
|
127
|
+
) {
|
|
128
|
+
const matches: boolean = !!path.match(test.pathRegex); // .match(path);
|
|
129
|
+
if ((matches && !test.invertPathMatching) || (!matches && test.invertPathMatching)) {
|
|
130
|
+
rval = test.config;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (!rval) {
|
|
136
|
+
rval = httpConfig.defaultMetaHandling || RouterUtil.defaultHttpMetaProcessingConfig(); // If nothing found, use epsilon defaults
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return rval;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Parses an open api file to create a router config
|
|
143
|
+
public static openApiYamlToRouterConfig(
|
|
144
|
+
httpConfig: HttpConfig,
|
|
145
|
+
openApiDoc: OpenApiDocument,
|
|
146
|
+
modelValidator: ModelValidator,
|
|
147
|
+
backgroundHttpAdapterHandler: BackgroundHttpAdapterHandler,
|
|
148
|
+
): EpsilonRouter {
|
|
149
|
+
if (!openApiDoc || !httpConfig) {
|
|
150
|
+
throw new MisconfiguredError('Cannot configure, missing either yaml or cfg');
|
|
151
|
+
}
|
|
152
|
+
const rval: EpsilonRouter = {
|
|
153
|
+
routes: [],
|
|
154
|
+
openApiModelValidator: modelValidator,
|
|
155
|
+
config: RouterUtil.assignDefaultsOnHttpConfig(httpConfig),
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
if (openApiDoc?.components?.securitySchemes) {
|
|
159
|
+
// Just validation, nothing to wire here
|
|
160
|
+
Object.keys(openApiDoc.components.securitySchemes).forEach((sk) => {
|
|
161
|
+
if (!rval.config.authorizers || !rval.config.authorizers.get(sk)) {
|
|
162
|
+
throw new MisconfiguredError().withFormattedErrorMessage('Doc requires authorizer %s but not found in map', sk);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const missingPaths: string[] = [];
|
|
168
|
+
const filterHandledPathMatches: string[] = httpConfig.filterHandledRouteMatches || [];
|
|
169
|
+
|
|
170
|
+
if (openApiDoc?.paths) {
|
|
171
|
+
Object.keys(openApiDoc.paths).forEach((path) => {
|
|
172
|
+
Object.keys(openApiDoc.paths[path]).forEach((method) => {
|
|
173
|
+
const convertedPath: string = RouterUtil.openApiPathToRouteParserPath(path);
|
|
174
|
+
const finder: string = method + ' ' + path;
|
|
175
|
+
const applicableMeta: HttpProcessingConfig = RouterUtil.findApplicableMeta(httpConfig, method, path);
|
|
176
|
+
|
|
177
|
+
const entry: any = openApiDoc.paths[path][method];
|
|
178
|
+
const isBackgroundEndpoint: boolean = path.startsWith(backgroundHttpAdapterHandler.httpSubmissionPath);
|
|
179
|
+
const isBackgroundMetaEndpoint: boolean = path === backgroundHttpAdapterHandler.httpMetaEndpoint;
|
|
180
|
+
const isBackgroundStatusEndpoint: boolean = path === backgroundHttpAdapterHandler.httpStatusPath;
|
|
181
|
+
// Auto-assign the background handler endpoints
|
|
182
|
+
if (isBackgroundEndpoint) {
|
|
183
|
+
rval.config.handlers.set(finder, (evt, ctx) => backgroundHttpAdapterHandler.handleBackgroundSubmission(evt, ctx));
|
|
184
|
+
}
|
|
185
|
+
if (isBackgroundMetaEndpoint) {
|
|
186
|
+
rval.config.handlers.set(finder, (evt, ctx) => backgroundHttpAdapterHandler.handleBackgroundMetaRequest(evt, ctx));
|
|
187
|
+
}
|
|
188
|
+
if (isBackgroundStatusEndpoint) {
|
|
189
|
+
rval.config.handlers.set(finder, (evt, ctx) => backgroundHttpAdapterHandler.handleBackgroundStatusRequest(evt, ctx));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (!rval.config.handlers || !rval.config.handlers.get(finder)) {
|
|
193
|
+
const match: string = filterHandledPathMatches.find((reg) => finder.match(reg));
|
|
194
|
+
if (match) {
|
|
195
|
+
Logger.debug('Adding filter-handled handler for %s', finder);
|
|
196
|
+
// Insert a placeholder for these, which still handles them in runtime if the filter is misconfigured
|
|
197
|
+
rval.config.handlers.set(finder, (evt) => BuiltInHandlers.expectedHandledByFilter(evt));
|
|
198
|
+
} else {
|
|
199
|
+
missingPaths.push(finder);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (entry && entry['security'] && entry['security'].length > 1) {
|
|
204
|
+
throw new MisconfiguredError('Epsilon does not currently support multiple security (path was ' + finder + ')');
|
|
205
|
+
}
|
|
206
|
+
const authorizerName: string = entry['security'] && entry['security'].length == 1 ? Object.keys(entry['security'][0])[0] : null;
|
|
207
|
+
|
|
208
|
+
const newRoute: RouteMapping = {
|
|
209
|
+
path: convertedPath,
|
|
210
|
+
method: method,
|
|
211
|
+
function: rval.config.handlers.get(finder),
|
|
212
|
+
authorizerName: applicableMeta.overrideAuthorizerName || authorizerName,
|
|
213
|
+
metaProcessingConfig: applicableMeta,
|
|
214
|
+
validation: null,
|
|
215
|
+
outboundValidation: null,
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// Add inbound validation, if available
|
|
219
|
+
if (
|
|
220
|
+
entry['requestBody'] &&
|
|
221
|
+
entry['requestBody']['content'] &&
|
|
222
|
+
entry['requestBody']['content']['application/json'] &&
|
|
223
|
+
entry['requestBody']['content']['application/json']['schema']
|
|
224
|
+
) {
|
|
225
|
+
// TODO: this is brittle as hell, need to firm up
|
|
226
|
+
const schema: any = entry['requestBody']['content'];
|
|
227
|
+
Logger.silly('Applying schema %j to %s', schema, finder);
|
|
228
|
+
|
|
229
|
+
const modelName = this.findAndValidateModelName(
|
|
230
|
+
method,
|
|
231
|
+
path,
|
|
232
|
+
schema,
|
|
233
|
+
rval.config.overrideModelValidator || rval.openApiModelValidator,
|
|
234
|
+
);
|
|
235
|
+
const required: boolean = BooleanRatchet.parseBool(entry['requestBody']['required']);
|
|
236
|
+
const validation: RouteValidatorConfig = {
|
|
237
|
+
extraPropertiesAllowed: true,
|
|
238
|
+
emptyAllowed: !required,
|
|
239
|
+
modelName: modelName,
|
|
240
|
+
} as RouteValidatorConfig;
|
|
241
|
+
|
|
242
|
+
newRoute.validation = validation;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Add outbound validation, if available
|
|
246
|
+
if (
|
|
247
|
+
entry['responses'] &&
|
|
248
|
+
entry['responses']['200'] &&
|
|
249
|
+
entry['responses']['200']['content'] &&
|
|
250
|
+
entry['responses']['200']['content']['application/json'] &&
|
|
251
|
+
entry['responses']['200']['content']['application/json']['schema']
|
|
252
|
+
) {
|
|
253
|
+
// TODO: this is brittle as hell, need to firm up
|
|
254
|
+
const schema: any = entry['responses']['200']['content'];
|
|
255
|
+
Logger.silly('Applying schema %j to %s', schema, finder);
|
|
256
|
+
const modelName = this.findAndValidateModelName(
|
|
257
|
+
method,
|
|
258
|
+
path,
|
|
259
|
+
schema,
|
|
260
|
+
rval.config.overrideModelValidator || rval.openApiModelValidator,
|
|
261
|
+
);
|
|
262
|
+
const validation: RouteValidatorConfig = {
|
|
263
|
+
extraPropertiesAllowed: false,
|
|
264
|
+
emptyAllowed: false, // Its a 200 response, must be non-null
|
|
265
|
+
modelName: modelName,
|
|
266
|
+
} as RouteValidatorConfig;
|
|
267
|
+
|
|
268
|
+
newRoute.outboundValidation = validation;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
rval.routes.push(newRoute);
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (missingPaths.length > 0) {
|
|
277
|
+
throw new MisconfiguredError().withFormattedErrorMessage('Missing expected handlers : %j', missingPaths);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return rval;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
private static findAndValidateModelName(method: string, path: string, schema: any, modelValidator: ModelValidator): string | undefined {
|
|
284
|
+
let rval: string | undefined = undefined;
|
|
285
|
+
const schemaPath: string = schema['application/json']['schema']['$ref'];
|
|
286
|
+
const inlinePath: string = schema['application/json']['schema']['type'];
|
|
287
|
+
if (schemaPath) {
|
|
288
|
+
rval = schemaPath.substring(schemaPath.lastIndexOf('/') + 1);
|
|
289
|
+
if (!modelValidator.fetchModel(rval)) {
|
|
290
|
+
throw new MisconfiguredError(`Path ${method} ${path} refers to schema ${rval} but its not in the schema section`);
|
|
291
|
+
}
|
|
292
|
+
} else if (inlinePath) {
|
|
293
|
+
rval = `${method}-${path}-requestBodyModel`;
|
|
294
|
+
const model = schema['application/json']['schema'];
|
|
295
|
+
modelValidator.addModel(rval, model);
|
|
296
|
+
}
|
|
297
|
+
return rval;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
public static openApiPathToRouteParserPath(input: string): string {
|
|
301
|
+
let rval: string = input;
|
|
302
|
+
|
|
303
|
+
if (rval) {
|
|
304
|
+
let sIdx: number = rval.indexOf('{');
|
|
305
|
+
while (sIdx > -1) {
|
|
306
|
+
const eIdx: number = rval.indexOf('}');
|
|
307
|
+
rval = rval.substring(0, sIdx) + ':' + rval.substring(sIdx + 1, eIdx) + rval.substring(eIdx + 1);
|
|
308
|
+
sIdx = rval.indexOf('{');
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return rval;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { APIGatewayEvent, APIGatewayEventRequestContext, Context, ProxyResult } from 'aws-lambda';
|
|
2
|
+
import { Logger } from '@bitblit/ratchet-common/logger/logger';
|
|
3
|
+
import { EpsilonGlobalHandler } from '../epsilon-global-handler.js';
|
|
4
|
+
import { SampleServerComponents } from '../sample/sample-server-components.js';
|
|
5
|
+
import { LoggerLevelName } from '@bitblit/ratchet-common/logger/logger-level-name';
|
|
6
|
+
import { describe, expect, test } from 'vitest';
|
|
7
|
+
|
|
8
|
+
describe('#errorToProxyResult', function () {
|
|
9
|
+
/*
|
|
10
|
+
test('should set the default status code to 500', function() {
|
|
11
|
+
|
|
12
|
+
let err:Error = new BadRequestError('this is a test','a1','a2');
|
|
13
|
+
let res:ProxyResult = ResponseUtil.errorToProxyResult(err);
|
|
14
|
+
|
|
15
|
+
expect(res.statusCode).toEqual(400);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('should parse a request body correctly', function() {
|
|
19
|
+
|
|
20
|
+
let evt:APIGatewayEvent = {
|
|
21
|
+
httpMethod:'post',
|
|
22
|
+
path:'/test',
|
|
23
|
+
pathParameters: null,
|
|
24
|
+
queryStringParameters: null,
|
|
25
|
+
stageVariables:null,
|
|
26
|
+
requestContext:{} as APIGatewayEventRequestContext,
|
|
27
|
+
resource:'/test',
|
|
28
|
+
headers: {
|
|
29
|
+
'content-type':'application/json'
|
|
30
|
+
},
|
|
31
|
+
isBase64Encoded: true,
|
|
32
|
+
body: 'ew0KICJtZXNzYWdlIiA6ICJ0aGlzIGlzIGEgdGVzdCIsDQogIm51bWJlciIgOiAxDQp9'
|
|
33
|
+
|
|
34
|
+
} as APIGatewayEvent;
|
|
35
|
+
|
|
36
|
+
let body = EventUtil.bodyObject(evt);
|
|
37
|
+
expect(body).toBeTruthy();
|
|
38
|
+
expect(body.message).toEqual('this is a test');
|
|
39
|
+
expect(body.number).toEqual(1);
|
|
40
|
+
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('should parse a request body correctly part 2', function() {
|
|
44
|
+
|
|
45
|
+
let evt:APIGatewayEvent = {
|
|
46
|
+
httpMethod:'post',
|
|
47
|
+
path:'/test',
|
|
48
|
+
pathParameters: null,
|
|
49
|
+
queryStringParameters: null,
|
|
50
|
+
stageVariables:null,
|
|
51
|
+
requestContext:{} as APIGatewayEventRequestContext,
|
|
52
|
+
resource:'/test',
|
|
53
|
+
headers: {
|
|
54
|
+
'content-type':'application/json; charset=UTF-8'
|
|
55
|
+
},
|
|
56
|
+
isBase64Encoded: true,
|
|
57
|
+
body: 'ew0KICJtZXNzYWdlIiA6ICJ0aGlzIGlzIGEgdGVzdCIsDQogIm51bWJlciIgOiAxDQp9'
|
|
58
|
+
|
|
59
|
+
} as APIGatewayEvent;
|
|
60
|
+
|
|
61
|
+
let body = EventUtil.bodyObject(evt);
|
|
62
|
+
expect(body).toBeTruthy();
|
|
63
|
+
expect(body.message).toEqual('this is a test');
|
|
64
|
+
expect(body.number).toEqual(1);
|
|
65
|
+
});
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
test('should gzip responses correctly', async () => {
|
|
69
|
+
const inst: EpsilonGlobalHandler = await SampleServerComponents.createSampleEpsilonGlobalHandler('jest-gzip');
|
|
70
|
+
|
|
71
|
+
expect(inst.epsilon.modelValidator).toBeTruthy();
|
|
72
|
+
|
|
73
|
+
const evt: APIGatewayEvent = {
|
|
74
|
+
httpMethod: 'get',
|
|
75
|
+
multiValueHeaders: {},
|
|
76
|
+
multiValueQueryStringParameters: {},
|
|
77
|
+
path: '/meta/server',
|
|
78
|
+
pathParameters: null,
|
|
79
|
+
queryStringParameters: null,
|
|
80
|
+
stageVariables: null,
|
|
81
|
+
requestContext: {} as APIGatewayEventRequestContext,
|
|
82
|
+
resource: '/meta/server',
|
|
83
|
+
headers: {
|
|
84
|
+
'content-type': 'application/json; charset=UTF-8',
|
|
85
|
+
'accept-encoding': 'gzip, deflate, br',
|
|
86
|
+
},
|
|
87
|
+
isBase64Encoded: true,
|
|
88
|
+
body: null,
|
|
89
|
+
} as APIGatewayEvent;
|
|
90
|
+
|
|
91
|
+
Logger.setLevel(LoggerLevelName.silly);
|
|
92
|
+
const result: ProxyResult = await inst.epsilon.webHandler.processEvent(evt, {} as Context);
|
|
93
|
+
|
|
94
|
+
expect(result).toBeTruthy();
|
|
95
|
+
expect(result.isBase64Encoded).toEqual(true);
|
|
96
|
+
expect(result.headers).toBeTruthy();
|
|
97
|
+
expect(result.headers['Content-Encoding']).toEqual('gzip');
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { EpsilonRouter } from './route/epsilon-router.js';
|
|
2
|
+
import { APIGatewayEvent, Context, ProxyResult } from 'aws-lambda';
|
|
3
|
+
|
|
4
|
+
import { RequireRatchet } from '@bitblit/ratchet-common/lang/require-ratchet';
|
|
5
|
+
import { Logger } from '@bitblit/ratchet-common/logger/logger';
|
|
6
|
+
import { StringRatchet } from '@bitblit/ratchet-common/lang/string-ratchet';
|
|
7
|
+
import { RestfulApiHttpError } from '@bitblit/ratchet-common/network/restful-api-http-error';
|
|
8
|
+
import { ResponseUtil } from './response-util.js';
|
|
9
|
+
import { ExtendedAPIGatewayEvent } from '../config/http/extended-api-gateway-event.js';
|
|
10
|
+
import { BuiltInFilters } from '../built-in/http/built-in-filters.js';
|
|
11
|
+
import { HttpProcessingConfig } from '../config/http/http-processing-config.js';
|
|
12
|
+
import { FilterFunction } from '../config/http/filter-function.js';
|
|
13
|
+
import { RunHandlerAsFilter } from '../built-in/http/run-handler-as-filter.js';
|
|
14
|
+
import { FilterChainContext } from '../config/http/filter-chain-context.js';
|
|
15
|
+
import { ContextUtil } from '../util/context-util.js';
|
|
16
|
+
import { EpsilonLambdaEventHandler } from '../config/epsilon-lambda-event-handler.js';
|
|
17
|
+
import { LambdaEventDetector } from '@bitblit/ratchet-aws/lambda/lambda-event-detector';
|
|
18
|
+
import { RouteAndParse } from './route/route-and-parse.js';
|
|
19
|
+
import Route from 'route-parser';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* This class functions as the adapter from a default lambda function to the handlers exposed via Epsilon
|
|
23
|
+
*/
|
|
24
|
+
export class WebHandler implements EpsilonLambdaEventHandler<APIGatewayEvent> {
|
|
25
|
+
public static readonly MAXIMUM_LAMBDA_BODY_SIZE_BYTES: number = 1024 * 1024 * 5 - 1024 * 100; // 5Mb - 100k buffer
|
|
26
|
+
|
|
27
|
+
constructor(private routerConfig: EpsilonRouter) {
|
|
28
|
+
RequireRatchet.notNullOrUndefined(routerConfig);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public get router(): EpsilonRouter {
|
|
32
|
+
return this.routerConfig;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public extractLabel(evt: APIGatewayEvent, _context: Context): string {
|
|
36
|
+
return 'WEB:' + StringRatchet.trimToEmpty(evt.httpMethod).toUpperCase() + ':' + evt.path;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public handlesEvent(evt: any): boolean {
|
|
40
|
+
return LambdaEventDetector.isValidApiGatewayEvent(evt);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public async processEvent(event: APIGatewayEvent, context: Context): Promise<ProxyResult> {
|
|
44
|
+
if (!this.routerConfig) {
|
|
45
|
+
throw new Error('Router config not found');
|
|
46
|
+
}
|
|
47
|
+
const asExtended: ExtendedAPIGatewayEvent = Object.assign(
|
|
48
|
+
{},
|
|
49
|
+
{ parsedBody: null, authorization: null, convertedFromV2Event: false },
|
|
50
|
+
event,
|
|
51
|
+
);
|
|
52
|
+
const rval: ProxyResult = await this.openApiLambdaHandler(asExtended, context);
|
|
53
|
+
ContextUtil.addTraceToProxyResult(rval);
|
|
54
|
+
Logger.updateTracePrefix(null); // Just in case it was set
|
|
55
|
+
return rval;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public async openApiLambdaHandler(evt: ExtendedAPIGatewayEvent, context: Context): Promise<ProxyResult> {
|
|
59
|
+
const rm: RouteAndParse = this.findBestMatchingRoute(evt);
|
|
60
|
+
const procConfig: HttpProcessingConfig = rm?.mapping?.metaProcessingConfig
|
|
61
|
+
? rm.mapping.metaProcessingConfig
|
|
62
|
+
: this.routerConfig.config.defaultMetaHandling;
|
|
63
|
+
const fCtx: FilterChainContext = {
|
|
64
|
+
event: evt,
|
|
65
|
+
context: context,
|
|
66
|
+
result: null,
|
|
67
|
+
rawResult: null,
|
|
68
|
+
routeAndParse: rm,
|
|
69
|
+
modelValidator: this.routerConfig.config.overrideModelValidator || this.routerConfig.openApiModelValidator,
|
|
70
|
+
authenticators: this.routerConfig.config.authorizers,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
let filterChain: FilterFunction[] = Object.assign([], procConfig.preFilters || []);
|
|
75
|
+
RunHandlerAsFilter.addRunHandlerAsFilterToList(filterChain, rm);
|
|
76
|
+
filterChain = filterChain.concat(procConfig.postFilters || []);
|
|
77
|
+
await BuiltInFilters.combineFilters(fCtx, filterChain);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
// Convert to an epsilon error
|
|
80
|
+
const wrapper: RestfulApiHttpError = RestfulApiHttpError.wrapError(err as Error);
|
|
81
|
+
fCtx.result = ResponseUtil.errorResponse(wrapper);
|
|
82
|
+
try {
|
|
83
|
+
await BuiltInFilters.combineFilters(fCtx, procConfig.errorFilters);
|
|
84
|
+
} catch (convErr) {
|
|
85
|
+
Logger.error('REALLY BAD - FAILED WHILE PROCESSING ERROR FILTERS : %s', convErr);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return fCtx.result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public findBestMatchingRoute(event: APIGatewayEvent): RouteAndParse {
|
|
92
|
+
let rval: RouteAndParse = null;
|
|
93
|
+
// See: https://www.npmjs.com/package/route-parser
|
|
94
|
+
const cleanPath: string = this.cleanPath(event);
|
|
95
|
+
|
|
96
|
+
// Filter routes to only matches
|
|
97
|
+
const methodLower: string = event.httpMethod.toLowerCase();
|
|
98
|
+
const matchRoutes: RouteAndParse[] = this.routerConfig.routes
|
|
99
|
+
.map((r) => {
|
|
100
|
+
let rval: RouteAndParse = null;
|
|
101
|
+
if (r.method && r.method.toLowerCase() === methodLower) {
|
|
102
|
+
const routeParser: Route = new Route(r.path);
|
|
103
|
+
const parsed: any = routeParser.match(cleanPath);
|
|
104
|
+
if (parsed !== false) {
|
|
105
|
+
rval = {
|
|
106
|
+
mapping: r,
|
|
107
|
+
route: routeParser,
|
|
108
|
+
parsed: parsed,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return rval;
|
|
113
|
+
})
|
|
114
|
+
.filter((r) => r != null);
|
|
115
|
+
// Pick the 'best' match
|
|
116
|
+
matchRoutes.sort((a, b) => {
|
|
117
|
+
return Object.keys(a.parsed).length - Object.keys(b.parsed).length;
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
rval = matchRoutes && matchRoutes.length > 0 ? matchRoutes[0] : null;
|
|
121
|
+
|
|
122
|
+
if (!rval) {
|
|
123
|
+
Logger.debug(
|
|
124
|
+
'Failed to find handler for %s (cleaned path was %s, strip prefixes were %j)',
|
|
125
|
+
event.path,
|
|
126
|
+
cleanPath,
|
|
127
|
+
this.routerConfig.config.prefixesToStripBeforeRouteMatch,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
return rval;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private cleanPath(event: APIGatewayEvent): string {
|
|
134
|
+
let rval: string = event.path;
|
|
135
|
+
// First, strip any leading /
|
|
136
|
+
while (rval.startsWith('/')) {
|
|
137
|
+
rval = rval.substring(1);
|
|
138
|
+
}
|
|
139
|
+
// If there are any listed prefixes, strip them
|
|
140
|
+
if (this.routerConfig.config.prefixesToStripBeforeRouteMatch) {
|
|
141
|
+
this.routerConfig.config.prefixesToStripBeforeRouteMatch.forEach((prefix) => {
|
|
142
|
+
if (rval.toLowerCase().startsWith(prefix.toLowerCase() + '/')) {
|
|
143
|
+
rval = rval.substring(prefix.length);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Strip any more leading /
|
|
149
|
+
while (rval.startsWith('/')) {
|
|
150
|
+
rval = rval.substring(1);
|
|
151
|
+
}
|
|
152
|
+
// Finally, put back exactly 1 leading / to match what comes out of open api
|
|
153
|
+
rval = '/' + rval;
|
|
154
|
+
|
|
155
|
+
return rval;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { APIGatewayEvent, APIGatewayProxyEventV2, Context, ProxyResult } from 'aws-lambda';
|
|
2
|
+
import { ExtendedAPIGatewayEvent } from '../config/http/extended-api-gateway-event.js';
|
|
3
|
+
import { AwsUtil } from '../util/aws-util.js';
|
|
4
|
+
import { EpsilonLambdaEventHandler } from '../config/epsilon-lambda-event-handler.js';
|
|
5
|
+
import { LambdaEventDetector } from '@bitblit/ratchet-aws/lambda/lambda-event-detector';
|
|
6
|
+
import { WebHandler } from './web-handler.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* This class functions as the adapter from a default lambda function to the handlers exposed via Epsilon
|
|
10
|
+
*/
|
|
11
|
+
export class WebV2Handler implements EpsilonLambdaEventHandler<APIGatewayProxyEventV2> {
|
|
12
|
+
constructor(private webHandler: WebHandler) {}
|
|
13
|
+
|
|
14
|
+
public extractLabel(evt: APIGatewayProxyEventV2, context: Context): string {
|
|
15
|
+
let rval: string = this.webHandler.extractLabel(AwsUtil.apiGatewayV2ToApiGatewayV1(evt), context);
|
|
16
|
+
rval = rval.replace('WEB:', 'WEB2:');
|
|
17
|
+
return rval;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public handlesEvent(evt: any): boolean {
|
|
21
|
+
return LambdaEventDetector.isValidApiGatewayV2WithRequestContextEvent(evt);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public async processEvent(evt: APIGatewayProxyEventV2, context: Context): Promise<ProxyResult> {
|
|
25
|
+
const conv: APIGatewayEvent = AwsUtil.apiGatewayV2ToApiGatewayV1(evt);
|
|
26
|
+
const asExtended: ExtendedAPIGatewayEvent = Object.assign(
|
|
27
|
+
{},
|
|
28
|
+
{ parsedBody: null, authorization: null, convertedFromV2Event: true },
|
|
29
|
+
conv,
|
|
30
|
+
);
|
|
31
|
+
const rval: ProxyResult = await this.webHandler.openApiLambdaHandler(asExtended, context);
|
|
32
|
+
return rval;
|
|
33
|
+
}
|
|
34
|
+
}
|