@yopdev/dev-server 2.0.0-alpha.1 → 2.0.0-beta.1
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/dist/src/cloudformation-lambda-http-proxy.d.ts +9 -9
- package/dist/src/cloudformation-lambda-http-proxy.js +4 -3
- package/dist/src/container.js +1 -1
- package/dist/src/deferred.js +7 -6
- package/dist/src/dev-server.d.ts +1 -0
- package/dist/src/dev-server.js +7 -3
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +4 -1
- package/dist/src/internal-queue.js +5 -7
- package/dist/src/lambda-http-proxy.d.ts +18 -12
- package/dist/src/lambda-http-proxy.js +17 -8
- package/dist/src/mappers.d.ts +24 -3
- package/dist/src/mappers.js +122 -78
- package/dist/src/services.d.ts +1 -0
- package/dist/src/services.js +6 -2
- package/dist/src/sqs.js +1 -1
- package/package.json +1 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
import { CloudFormationSetupConfig } from './cloudformation';
|
|
3
2
|
import { DevServerConfig } from './config';
|
|
4
3
|
import { HttpSettings } from './http-server';
|
|
5
|
-
import {
|
|
4
|
+
import { Authorizer, Route } from './lambda-http-proxy';
|
|
6
5
|
import { Callback, Service, Startable } from './services';
|
|
7
|
-
import {
|
|
8
|
-
export declare const newLambdaProxyFromCloudFormationTemplate: <
|
|
9
|
-
type CloudFormationLambdaProxyConfig<
|
|
10
|
-
authorizer?: (config: DevServerConfig) =>
|
|
11
|
-
extraRoutes: Route<
|
|
6
|
+
import { LambdaMapperFactory, PathParameterResolver } from './mappers';
|
|
7
|
+
export declare const newLambdaProxyFromCloudFormationTemplate: <Context, AuthorizerContext, Event_1, HandlerResponse>(name: string, settings: HttpSettings, config: CloudFormationLambdaProxyConfig<Context, AuthorizerContext, Event_1, HandlerResponse>, callback: Callback<string>) => Startable<Service<string>>;
|
|
8
|
+
type CloudFormationLambdaProxyConfig<Context, AuthorizerContext, Event, HandlerResponse> = {
|
|
9
|
+
authorizer?: (config: DevServerConfig) => Authorizer<AuthorizerContext> | undefined;
|
|
10
|
+
extraRoutes: Route<Context, AuthorizerContext, Event, HandlerResponse>[];
|
|
11
|
+
pathParameterResolver: PathParameterResolver<Event>;
|
|
12
12
|
prepare?: (config: DevServerConfig) => Promise<void>;
|
|
13
|
-
context?: () =>
|
|
14
|
-
mapper?:
|
|
13
|
+
context?: () => Context;
|
|
14
|
+
mapper?: LambdaMapperFactory<AuthorizerContext, Event, HandlerResponse>;
|
|
15
15
|
} & CloudFormationSetupConfig;
|
|
16
16
|
export {};
|
|
@@ -31,13 +31,14 @@ class CloudFormationLambdaProxy extends cloudformation_1.CloudFormationSetup {
|
|
|
31
31
|
this.pathWithCapturingGroups = (source) => [...source.matchAll(PATH_VARIABLE_CAPTURE)].reduce((prev, curr) => prev.replaceAll(curr[0], `(?<${this.normalizeCaptureGroupName(curr[1])}>.*)`), source);
|
|
32
32
|
this.normalizeCaptureGroupName = (original) => (original === 'proxy+' ? PROXY_PATH_PARAM : original);
|
|
33
33
|
this.pathParameterCapture = (pathWithCapturingGroups, handler, context) => async (event) => {
|
|
34
|
-
const pathParameters = pathWithCapturingGroups.exec(event
|
|
35
|
-
event
|
|
36
|
-
.map(([k, v]) => [k, decodeURIComponent(v)]));
|
|
34
|
+
const pathParameters = pathWithCapturingGroups.exec(this.pathParameterResolver.locate(event))?.groups;
|
|
35
|
+
this.pathParameterResolver.store(event, Object.fromEntries((Object.entries(pathParameters ?? {}))
|
|
36
|
+
.map(([k, v]) => [k, decodeURIComponent(v)])));
|
|
37
37
|
return handler(event, context?.());
|
|
38
38
|
};
|
|
39
39
|
this.mapper = config?.mapper;
|
|
40
40
|
this.authorizer = config?.authorizer;
|
|
41
|
+
this.pathParameterResolver = config?.pathParameterResolver;
|
|
41
42
|
}
|
|
42
43
|
logHandler(handler) {
|
|
43
44
|
return `detected handler for ${handler.method} on ${handler.path} with weight ${handler.weight}`;
|
package/dist/src/container.js
CHANGED
|
@@ -18,7 +18,7 @@ class Container {
|
|
|
18
18
|
.then((started) => this.started = started)
|
|
19
19
|
.then(() => this.endpointBuilder(this.started.getFirstMappedPort()))
|
|
20
20
|
.tap((url) => this.LOGGER.debug(url));
|
|
21
|
-
this.stop = async () => this.started.stop().then(() => undefined);
|
|
21
|
+
this.stop = async () => (this.started ?? { stop: async () => { this.LOGGER.warn('no container'); } }).stop().then(() => undefined);
|
|
22
22
|
this.LOGGER = logging_1.LoggerFactory.create(`CONTAINER[${name}]`);
|
|
23
23
|
const generic = new testcontainers_1.GenericContainer(image);
|
|
24
24
|
const withEnvironment = environment ? generic.withEnvironment(environment) : generic;
|
package/dist/src/deferred.js
CHANGED
|
@@ -32,13 +32,14 @@ class Lazy {
|
|
|
32
32
|
}
|
|
33
33
|
class Promised {
|
|
34
34
|
constructor(configurable) {
|
|
35
|
-
this.configurable = configurable;
|
|
36
|
-
this.start = async (config) => this.configurable(config)
|
|
37
|
-
.then((service) => this.service = service)
|
|
38
|
-
.then((service) => this.LOGGER.info('DISCOVERY:%s', service.name))
|
|
39
|
-
.then(() => this.service.start(config));
|
|
40
|
-
this.stop = async () => this.service.stop();
|
|
41
35
|
this.name = (0, crypto_1.randomUUID)();
|
|
42
36
|
this.LOGGER = logging_1.LoggerFactory.create(`PROMISED[${this.name}]`);
|
|
37
|
+
let initialized;
|
|
38
|
+
this.start = async (config) => configurable(config)
|
|
39
|
+
.catch((e) => e?.cleanup?.() ?? Promise.reject(e))
|
|
40
|
+
.then((service) => initialized = service)
|
|
41
|
+
.tap((service) => this.LOGGER.info('DISCOVERY:%s', service.name))
|
|
42
|
+
.then((service) => service.start(config));
|
|
43
|
+
this.stop = async () => (initialized ?? { stop: async () => this.LOGGER.info('not started') }).stop();
|
|
43
44
|
}
|
|
44
45
|
}
|
package/dist/src/dev-server.d.ts
CHANGED
package/dist/src/dev-server.js
CHANGED
|
@@ -42,12 +42,16 @@ class DevServer {
|
|
|
42
42
|
}))))
|
|
43
43
|
.tap((config) => this.LOGGER.debug('config is %o', config))
|
|
44
44
|
.then((aws) => this.service.start(aws))
|
|
45
|
+
.catch((e) => this.shutdown()
|
|
46
|
+
.then(() => this.LOGGER.error('error starting service'))
|
|
47
|
+
.then(() => Promise.reject(e)))
|
|
45
48
|
.then(() => this.LOGGER.info('started'))
|
|
46
49
|
.then(() => this);
|
|
47
|
-
this.stop = () => this.
|
|
48
|
-
.then(tunnel_1.terminate)
|
|
49
|
-
.then(() => this.localStack?.stop())
|
|
50
|
+
this.stop = () => this.shutdown()
|
|
50
51
|
.then(() => this.LOGGER.info('stopped'));
|
|
52
|
+
this.shutdown = async () => this.service.stop()
|
|
53
|
+
.then(tunnel_1.terminate)
|
|
54
|
+
.then(() => this.localStack?.stop());
|
|
51
55
|
this.LOGGER = logging_1.LoggerFactory.create(`DEVSERVER[${name}]`);
|
|
52
56
|
const encodedName = Buffer.from(name).toString('hex').substring(0, 64);
|
|
53
57
|
this.eventProxyTopic = `EventProxyTopic${encodedName}`;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { DevServer } from './dev-server';
|
|
2
2
|
export { newHttpServer as httpServer, HttpSettings } from './http-server';
|
|
3
3
|
export { newLambdaHttpProxy as lambdaHttpProxy, UNAUTHORIZED } from './lambda-http-proxy';
|
|
4
|
+
export { v1 as v1LambdaProxyPayload, v2 as v2LambdaProxyPayload } from './mappers';
|
|
4
5
|
export { newLambdaProxyFromCloudFormationTemplate as cloudFormationLambdaProxy } from './cloudformation-lambda-http-proxy';
|
|
5
6
|
export { newSnsHttpProxy as snsHttpProxy } from './sns-http-proxy';
|
|
6
7
|
export { newInternalQueue as internalQueue } from './internal-queue';
|
package/dist/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Service = exports.promised = exports.lazy = exports.oneThenOther = exports.allOf = exports.tunnel = exports.container = exports.dynamoDbTable = exports.preTrafficHooks = exports.scheduledTasks = exports.cloudFormationSnsEventHandlers = exports.eventsProxy = exports.internalQueue = exports.snsHttpProxy = exports.cloudFormationLambdaProxy = exports.UNAUTHORIZED = exports.lambdaHttpProxy = exports.httpServer = exports.DevServer = void 0;
|
|
3
|
+
exports.Service = exports.promised = exports.lazy = exports.oneThenOther = exports.allOf = exports.tunnel = exports.container = exports.dynamoDbTable = exports.preTrafficHooks = exports.scheduledTasks = exports.cloudFormationSnsEventHandlers = exports.eventsProxy = exports.internalQueue = exports.snsHttpProxy = exports.cloudFormationLambdaProxy = exports.v2LambdaProxyPayload = exports.v1LambdaProxyPayload = exports.UNAUTHORIZED = exports.lambdaHttpProxy = exports.httpServer = exports.DevServer = void 0;
|
|
4
4
|
var dev_server_1 = require("./dev-server");
|
|
5
5
|
Object.defineProperty(exports, "DevServer", { enumerable: true, get: function () { return dev_server_1.DevServer; } });
|
|
6
6
|
var http_server_1 = require("./http-server");
|
|
@@ -8,6 +8,9 @@ Object.defineProperty(exports, "httpServer", { enumerable: true, get: function (
|
|
|
8
8
|
var lambda_http_proxy_1 = require("./lambda-http-proxy");
|
|
9
9
|
Object.defineProperty(exports, "lambdaHttpProxy", { enumerable: true, get: function () { return lambda_http_proxy_1.newLambdaHttpProxy; } });
|
|
10
10
|
Object.defineProperty(exports, "UNAUTHORIZED", { enumerable: true, get: function () { return lambda_http_proxy_1.UNAUTHORIZED; } });
|
|
11
|
+
var mappers_1 = require("./mappers");
|
|
12
|
+
Object.defineProperty(exports, "v1LambdaProxyPayload", { enumerable: true, get: function () { return mappers_1.v1; } });
|
|
13
|
+
Object.defineProperty(exports, "v2LambdaProxyPayload", { enumerable: true, get: function () { return mappers_1.v2; } });
|
|
11
14
|
var cloudformation_lambda_http_proxy_1 = require("./cloudformation-lambda-http-proxy");
|
|
12
15
|
Object.defineProperty(exports, "cloudFormationLambdaProxy", { enumerable: true, get: function () { return cloudformation_lambda_http_proxy_1.newLambdaProxyFromCloudFormationTemplate; } });
|
|
13
16
|
var sns_http_proxy_1 = require("./sns-http-proxy");
|
|
@@ -20,12 +20,13 @@ class InternalQueue {
|
|
|
20
20
|
.then((queue) => this
|
|
21
21
|
.createConsumer(sqs.client, this.name, queue.url, this.handler(queue), this.visibility)
|
|
22
22
|
.then(() => queue.url));
|
|
23
|
-
this.createConsumer = async (sqs, name, url, handler, visibility) => Promise.resolve(sqs_consumer_1.Consumer.create({
|
|
23
|
+
this.createConsumer = async (sqs, name, url, handler, visibility) => Promise.resolve(() => this.consumer = sqs_consumer_1.Consumer.create({
|
|
24
24
|
queueUrl: url,
|
|
25
25
|
waitTimeSeconds: visibility,
|
|
26
26
|
sqs: sqs,
|
|
27
27
|
handleMessage: async (message) => handler({ Records: [this.mapper(message)] }),
|
|
28
28
|
}))
|
|
29
|
+
.then((factory) => factory())
|
|
29
30
|
.then((consumer) => {
|
|
30
31
|
consumer.on('error', (err) => {
|
|
31
32
|
this.LOGGER.error(err, 'failed to handle message');
|
|
@@ -33,16 +34,13 @@ class InternalQueue {
|
|
|
33
34
|
consumer.on('processing_error', (err) => {
|
|
34
35
|
this.LOGGER.error(err, 'failed to process message');
|
|
35
36
|
});
|
|
36
|
-
consumer.start();
|
|
37
37
|
this.LOGGER.info('consumer for %s initialized', name);
|
|
38
|
-
|
|
39
|
-
consumer: consumer,
|
|
40
|
-
visibility: visibility,
|
|
41
|
-
};
|
|
38
|
+
return consumer;
|
|
42
39
|
})
|
|
40
|
+
.then(async (consumer) => consumer.start())
|
|
43
41
|
.then(() => this.LOGGER.info('started'))
|
|
44
42
|
.then(() => this);
|
|
45
|
-
this.stop = () => (0, stoppable_1.stopConsumer)(this.
|
|
43
|
+
this.stop = async () => this.consumer !== undefined ? (0, stoppable_1.stopConsumer)(this.visibility, this.consumer) : this.LOGGER.warn('no consumer');
|
|
46
44
|
this.LOGGER = logging_1.LoggerFactory.create(`INTERNALQUEUE[${name}]`);
|
|
47
45
|
}
|
|
48
46
|
async createQueue(sqs, name) {
|
|
@@ -1,21 +1,27 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { HttpSettings } from "./http-server";
|
|
2
|
-
import {
|
|
3
|
-
import { IncomingMessage } from "http";
|
|
3
|
+
import { LambdaMapperFactory } from "./mappers";
|
|
4
4
|
import { Service, Callback } from "./services";
|
|
5
5
|
export declare const UNAUTHORIZED: Error;
|
|
6
|
-
export declare const newLambdaHttpProxy: <
|
|
6
|
+
export declare const newLambdaHttpProxy: <Context, AuthorizerContext, Event_1, HandlerResponse>(name: string, config: {
|
|
7
7
|
settings: HttpSettings;
|
|
8
|
-
routes: Route<
|
|
9
|
-
mapper
|
|
10
|
-
authorizer?: Authorizer<
|
|
11
|
-
context?: () =>
|
|
8
|
+
routes: Route<Context, AuthorizerContext, Event_1, HandlerResponse>[];
|
|
9
|
+
mapper: LambdaMapperFactory<AuthorizerContext, Event_1, HandlerResponse>;
|
|
10
|
+
authorizer?: Authorizer<AuthorizerContext>;
|
|
11
|
+
context?: () => Context;
|
|
12
12
|
}, callback?: Callback<string>) => Service<string>;
|
|
13
|
-
export
|
|
14
|
-
|
|
13
|
+
export declare abstract class Response {
|
|
14
|
+
readonly statusCode: number;
|
|
15
|
+
readonly contentType: string | undefined;
|
|
16
|
+
readonly location: string | undefined;
|
|
17
|
+
constructor(statusCode: number, contentType: string | undefined, location: string | undefined);
|
|
18
|
+
body: () => string | Buffer | undefined;
|
|
19
|
+
}
|
|
20
|
+
export type Route<Context, AuthorizerContext, Event, HandlerResponse> = {
|
|
15
21
|
method: RegExp;
|
|
16
22
|
path: RegExp;
|
|
17
23
|
weight: number;
|
|
18
|
-
authorizer?: Authorizer<
|
|
19
|
-
handler: (event:
|
|
24
|
+
authorizer?: Authorizer<AuthorizerContext>;
|
|
25
|
+
handler: (event: Event, context: Context) => Promise<HandlerResponse>;
|
|
20
26
|
};
|
|
21
|
-
export type Authorizer<
|
|
27
|
+
export type Authorizer<Context> = (authorization: string) => Promise<Context | undefined>;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.newLambdaHttpProxy = exports.UNAUTHORIZED = void 0;
|
|
3
|
+
exports.Response = exports.newLambdaHttpProxy = exports.UNAUTHORIZED = void 0;
|
|
4
4
|
const logging_1 = require("@yopdev/logging");
|
|
5
5
|
const http_server_1 = require("./http-server");
|
|
6
|
-
const mappers_1 = require("./mappers");
|
|
7
6
|
const responses_1 = require("./responses");
|
|
8
7
|
const services_1 = require("./services");
|
|
9
8
|
exports.UNAUTHORIZED = new Error('UNAUTHORIZED');
|
|
10
|
-
const newLambdaHttpProxy = (name, config, callback) => new services_1.Service(new LambdaHttpProxy(name, config.settings, config.routes, config.mapper
|
|
9
|
+
const newLambdaHttpProxy = (name, config, callback) => new services_1.Service(new LambdaHttpProxy(name, config.settings, config.routes, config.mapper, config.authorizer ?? (() => Promise.resolve(undefined)), config.context), callback);
|
|
11
10
|
exports.newLambdaHttpProxy = newLambdaHttpProxy;
|
|
12
11
|
class LambdaHttpProxy {
|
|
13
12
|
constructor(name, settings, routes, mapper, defaultAuthorizer, context = () => undefined) {
|
|
@@ -18,12 +17,14 @@ class LambdaHttpProxy {
|
|
|
18
17
|
this.context = context;
|
|
19
18
|
this.start = () => this.server.start();
|
|
20
19
|
this.stop = () => this.server.stop();
|
|
21
|
-
this.handler = (authorizer, lambdaHandler) => (request, body, response) => this.mapper(request, body)
|
|
22
|
-
.then(async (
|
|
20
|
+
this.handler = (authorizer, lambdaHandler) => (request, body, response) => this.mapper.newInstance(request, body)
|
|
21
|
+
.then(async (mapper) => authorizer(mapper.authorization())
|
|
23
22
|
.then(async (context) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
return lambdaHandler(mapper.event(context), this.context())
|
|
24
|
+
.then((lambda) => {
|
|
25
|
+
const result = mapper.toResponse(lambda);
|
|
26
|
+
return (0, responses_1.writeResponse)(response, result.statusCode, result.body(), result.contentType, result.location);
|
|
27
|
+
})
|
|
27
28
|
.catch((e) => {
|
|
28
29
|
this.LOGGER.error(e, 'request failed to execute');
|
|
29
30
|
(0, responses_1.internalServerError)(response, e.body);
|
|
@@ -40,3 +41,11 @@ class LambdaHttpProxy {
|
|
|
40
41
|
this.LOGGER.info('registered %i routes', routes.length);
|
|
41
42
|
}
|
|
42
43
|
}
|
|
44
|
+
class Response {
|
|
45
|
+
constructor(statusCode, contentType, location) {
|
|
46
|
+
this.statusCode = statusCode;
|
|
47
|
+
this.contentType = contentType;
|
|
48
|
+
this.location = location;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.Response = Response;
|
package/dist/src/mappers.d.ts
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { Message } from "@aws-sdk/client-sqs";
|
|
3
|
-
import { SQSRecord } from "aws-lambda";
|
|
3
|
+
import { APIGatewayEventRequestContextV2WithAuthorizer, APIGatewayProxyEvent, APIGatewayProxyEventPathParameters, APIGatewayProxyEventV2, APIGatewayProxyEventV2WithRequestContext, APIGatewayProxyResult, APIGatewayProxyStructuredResultV2, SQSRecord } from "aws-lambda";
|
|
4
4
|
import { IncomingMessage } from "http";
|
|
5
|
-
import {
|
|
5
|
+
import { Response } from "./lambda-http-proxy";
|
|
6
6
|
export declare const mapToLambdaSqsRecord: (message: Message) => SQSRecord;
|
|
7
|
-
export declare
|
|
7
|
+
export declare const v1: {
|
|
8
|
+
mapper: LambdaMapperFactory<unknown, APIGatewayProxyEvent, APIGatewayProxyResult>;
|
|
9
|
+
resolver: PathParameterResolver<APIGatewayProxyEvent>;
|
|
10
|
+
};
|
|
11
|
+
export declare const v2: {
|
|
12
|
+
mapper: LambdaMapperFactory<unknown, APIGatewayEventRequestContextV2WithGenericAuthorizer<unknown>, APIGatewayProxyStructuredResultV2>;
|
|
13
|
+
resolver: PathParameterResolver<APIGatewayProxyEventV2>;
|
|
14
|
+
};
|
|
15
|
+
interface LambdaMapper<AuthorizerContext, Event, HandlerResponse> {
|
|
16
|
+
event(context: AuthorizerContext): Event;
|
|
17
|
+
authorization(): string;
|
|
18
|
+
toResponse: (response: HandlerResponse) => Response;
|
|
19
|
+
}
|
|
20
|
+
export interface LambdaMapperFactory<AuthorizerContext, Event, LambdaResponse> {
|
|
21
|
+
newInstance(request: IncomingMessage, body: string): Promise<LambdaMapper<AuthorizerContext, Event, LambdaResponse>>;
|
|
22
|
+
}
|
|
23
|
+
type APIGatewayEventRequestContextV2WithGenericAuthorizer<AuthorizerContext> = APIGatewayProxyEventV2WithRequestContext<APIGatewayEventRequestContextV2WithAuthorizer<AuthorizerContext>>;
|
|
24
|
+
export type PathParameterResolver<Event> = {
|
|
25
|
+
locate: (event: Event) => string;
|
|
26
|
+
store: (event: Event, params: APIGatewayProxyEventPathParameters) => void;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
package/dist/src/mappers.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.v2 = exports.v1 = exports.mapToLambdaSqsRecord = void 0;
|
|
4
4
|
const url_1 = require("url");
|
|
5
|
+
const lambda_http_proxy_1 = require("./lambda-http-proxy");
|
|
5
6
|
const mapToLambdaSqsRecord = (message) => {
|
|
6
7
|
if (!message.Body)
|
|
7
8
|
throw new Error('message Body must be present');
|
|
@@ -23,84 +24,127 @@ const mapToLambdaSqsRecord = (message) => {
|
|
|
23
24
|
};
|
|
24
25
|
};
|
|
25
26
|
exports.mapToLambdaSqsRecord = mapToLambdaSqsRecord;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
domainPrefix: '',
|
|
59
|
-
http: {
|
|
60
|
-
method: req.method,
|
|
61
|
-
path: url.pathname,
|
|
62
|
-
protocol: 'http',
|
|
63
|
-
sourceIp: '127.0.0.1',
|
|
64
|
-
userAgent: req.headers['user-agent'],
|
|
65
|
-
},
|
|
27
|
+
const payloadV1JwtAuthorizerLambdaMapper = () => ({
|
|
28
|
+
newInstance: (request, body) => Promise.resolve(new DefaultLambdaMapper(request, body))
|
|
29
|
+
});
|
|
30
|
+
const payloadV2LambdaAuthorizerLambdaMapper = () => ({
|
|
31
|
+
newInstance: (request, body) => Promise.resolve(new DefaultLambdaMapper(request, body))
|
|
32
|
+
});
|
|
33
|
+
const payloadV1PathParameterResolver = {
|
|
34
|
+
locate: (event) => event.path,
|
|
35
|
+
store: (event, params) => event.pathParameters = params
|
|
36
|
+
};
|
|
37
|
+
const payloadV2PathParameterResolver = {
|
|
38
|
+
locate: (event) => event.rawPath,
|
|
39
|
+
store: (event, params) => event.pathParameters = params
|
|
40
|
+
};
|
|
41
|
+
exports.v1 = {
|
|
42
|
+
mapper: payloadV1JwtAuthorizerLambdaMapper(),
|
|
43
|
+
resolver: payloadV1PathParameterResolver,
|
|
44
|
+
};
|
|
45
|
+
exports.v2 = {
|
|
46
|
+
mapper: payloadV2LambdaAuthorizerLambdaMapper(),
|
|
47
|
+
resolver: payloadV2PathParameterResolver,
|
|
48
|
+
};
|
|
49
|
+
class DefaultLambdaMapper {
|
|
50
|
+
constructor(request, body) {
|
|
51
|
+
this.body = body;
|
|
52
|
+
this.toResponse = (response) => response.isBase64Encoded ?
|
|
53
|
+
new Base64EncodedResponse(response.statusCode, response.headers?.['content-type']?.toString(), response.headers?.['location']?.toString(), response.body) :
|
|
54
|
+
new StringResponse(response.statusCode, response.headers?.['content-type']?.toString(), response.headers?.['location']?.toString(), response.body);
|
|
55
|
+
this.event = (context) => ({
|
|
56
|
+
version: '2.0',
|
|
57
|
+
rawPath: this.url.pathname,
|
|
58
|
+
rawQueryString: this.url.search,
|
|
66
59
|
routeKey: '',
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
60
|
+
httpMethod: this.method,
|
|
61
|
+
body: this.body,
|
|
62
|
+
headers: this.headers,
|
|
63
|
+
path: this.url.pathname,
|
|
64
|
+
pathParameters: null,
|
|
65
|
+
queryStringParameters: this.queryStringParameters,
|
|
66
|
+
resource: '',
|
|
67
|
+
multiValueHeaders: {},
|
|
68
|
+
isBase64Encoded: false,
|
|
69
|
+
multiValueQueryStringParameters: null,
|
|
70
|
+
stageVariables: null,
|
|
71
|
+
requestContext: {
|
|
72
|
+
domainName: this.headers.host,
|
|
73
|
+
domainPrefix: '',
|
|
74
|
+
http: {
|
|
75
|
+
method: this.method,
|
|
76
|
+
path: this.url.pathname,
|
|
77
|
+
protocol: 'http',
|
|
78
|
+
sourceIp: '127.0.0.1',
|
|
79
|
+
userAgent: this.headers['user-agent'],
|
|
80
|
+
},
|
|
81
|
+
routeKey: '',
|
|
82
|
+
time: new Date(this.time).toString(),
|
|
83
|
+
timeEpoch: this.time,
|
|
75
84
|
accountId: '',
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
apiId: '',
|
|
86
|
+
authorizer: context,
|
|
87
|
+
httpMethod: '',
|
|
88
|
+
identity: {
|
|
89
|
+
accessKey: '',
|
|
90
|
+
accountId: '',
|
|
91
|
+
apiKey: '',
|
|
92
|
+
apiKeyId: '',
|
|
93
|
+
caller: '',
|
|
94
|
+
clientCert: {
|
|
95
|
+
clientCertPem: '',
|
|
96
|
+
issuerDN: '',
|
|
97
|
+
serialNumber: '',
|
|
98
|
+
subjectDN: '',
|
|
99
|
+
validity: { notAfter: '', notBefore: '' },
|
|
100
|
+
},
|
|
101
|
+
cognitoAuthenticationProvider: '',
|
|
102
|
+
cognitoAuthenticationType: '',
|
|
103
|
+
cognitoIdentityId: '',
|
|
104
|
+
cognitoIdentityPoolId: '',
|
|
105
|
+
principalOrgId: '',
|
|
106
|
+
sourceIp: '',
|
|
107
|
+
user: '',
|
|
108
|
+
userAgent: '',
|
|
109
|
+
userArn: '',
|
|
85
110
|
},
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
111
|
+
path: '',
|
|
112
|
+
protocol: '',
|
|
113
|
+
requestId: '',
|
|
114
|
+
requestTimeEpoch: this.time,
|
|
115
|
+
resourceId: '',
|
|
116
|
+
resourcePath: '',
|
|
117
|
+
stage: '',
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
this.authorization = () => this.authorizationHeaderValue;
|
|
121
|
+
if (!request.url || !request.method)
|
|
122
|
+
throw new Error('url and method are required');
|
|
123
|
+
const url = new url_1.URL(request.url, `http://${request.headers.host}`);
|
|
124
|
+
const qsp = {};
|
|
125
|
+
url.searchParams.forEach((v, k) => (qsp[k] = decodeURIComponent(v)));
|
|
126
|
+
this.queryStringParameters = qsp;
|
|
127
|
+
const headers = {};
|
|
128
|
+
if (request.headers['content-type'])
|
|
129
|
+
headers['content-type'] = request.headers['content-type'];
|
|
130
|
+
if (request.headers['accept'])
|
|
131
|
+
headers['accept'] = request.headers['accept'];
|
|
132
|
+
if (request.headers['authorization'])
|
|
133
|
+
headers['authorization'] = request.headers['authorization'];
|
|
134
|
+
this.headers = headers;
|
|
135
|
+
this.url = url;
|
|
136
|
+
this.time = 1428582896000;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
class StringResponse extends lambda_http_proxy_1.Response {
|
|
140
|
+
constructor(statusCode, contentType, location, body) {
|
|
141
|
+
super(statusCode, contentType, location);
|
|
142
|
+
this.body = () => body;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
class Base64EncodedResponse extends lambda_http_proxy_1.Response {
|
|
146
|
+
constructor(statusCode, contentType, location, body) {
|
|
147
|
+
super(statusCode, contentType, location);
|
|
148
|
+
this.body = () => Buffer.from(body, 'base64');
|
|
149
|
+
}
|
|
105
150
|
}
|
|
106
|
-
exports.mapToLambdaEvent = mapToLambdaEvent;
|
package/dist/src/services.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export declare class Service<I> implements Lifecycle<I> {
|
|
|
15
15
|
readonly name: string;
|
|
16
16
|
readonly start: (config: DevServerConfig) => Promise<I>;
|
|
17
17
|
readonly stop: () => Promise<void>;
|
|
18
|
+
private doStop;
|
|
18
19
|
private readonly LOGGER;
|
|
19
20
|
constructor(service: Lifecycle<I>, callback?: Callback<I>);
|
|
20
21
|
private callbackOrDefault;
|
package/dist/src/services.js
CHANGED
|
@@ -9,14 +9,18 @@ class Service {
|
|
|
9
9
|
this.callbackOrDefault = async (instance) => (this.callback ?? this.DEFAULT_CALLBACK)(instance);
|
|
10
10
|
this.name = service.name;
|
|
11
11
|
this.LOGGER = logging_1.LoggerFactory.create(`SERVICE[${this.name}]`);
|
|
12
|
+
const stop = async () => service.stop();
|
|
12
13
|
this.start = (config) => service.start(config)
|
|
14
|
+
.catch((error) => stop()
|
|
15
|
+
.then(() => this.doStop = () => Promise.resolve(this.LOGGER.error(error, 'failed')))
|
|
16
|
+
.then(() => Promise.reject(error)))
|
|
13
17
|
.then((started) => this
|
|
14
18
|
.callbackOrDefault(started)
|
|
15
19
|
.then(() => this.LOGGER.info('started'))
|
|
16
20
|
.then(() => started));
|
|
17
|
-
this.
|
|
18
|
-
.stop()
|
|
21
|
+
this.doStop = () => stop()
|
|
19
22
|
.then(() => this.LOGGER.info('stopped'));
|
|
23
|
+
this.stop = () => this.doStop();
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
26
|
exports.Service = Service;
|
package/dist/src/sqs.js
CHANGED