Socket
Socket
Sign inDemoInstall

@aesop-fables/triginta

Package Overview
Dependencies
Maintainers
2
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aesop-fables/triginta - npm Package Compare versions

Comparing version 0.3.4 to 0.4.0

1

lib/Decorators.js

@@ -13,2 +13,3 @@ "use strict";

const params = { method, route, constructor: target };
console.log('wtf', params);
Reflect.defineMetadata(exports.endpointMetadataKey, params, target);

@@ -15,0 +16,0 @@ RouteRegistry_1.default.register(params);

15

lib/HttpLambda.d.ts
import { IServiceContainer, IServiceModule, Newable } from '@aesop-fables/containr';
import { APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2, Handler } from 'aws-lambda';
import { IHttpEndpoint } from './IHttpEndpoint';
import { IHttpEndpoint, IHttpEventHandler } from './IHttpEndpoint';
export declare type NonNoisyEvent = Omit<APIGatewayProxyEventV2, 'requestContext'>;
export interface BootstrappedHttpLambdaContext {
createHttpEventLambda<Output>(newable: Newable<IHttpEventHandler<Output>>): Handler<APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2>;
createHttpLambda<Input, Output>(newable: Newable<IHttpEndpoint<Input, Output>>): Handler<APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2>;
}
export interface IHttpLambdaFactory {
createHandler<Input, Output>(newable: Newable<IHttpEndpoint<Input, Output>>): Handler<APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2>;
createHandler<Input, Output>(newable: Newable<IHttpEndpoint<Input, Output> | IHttpEventHandler<Output>>): Handler<APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2>;
createEventHandler<Output>(newable: Newable<IHttpEventHandler<Output>>): Handler<APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2>;
}
export interface IHttpResponseGenerator {
generateResponse(response?: any): Promise<APIGatewayProxyStructuredResultV2>;
}
export declare class HttpResponseGenerator implements IHttpResponseGenerator {
generateResponse(response?: any): Promise<APIGatewayProxyStructuredResultV2>;
}
export declare class HttpLambdaFactory implements IHttpLambdaFactory {
private readonly container;
constructor(container: IServiceContainer);
createHandler<Input, Output>(newable: Newable<IHttpEndpoint<Input, Output>>): Handler<APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2>;
createEventHandler<Output>(newable: Newable<IHttpEventHandler<Output>>): Handler<APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2>;
createHandler<Input, Output>(newable: Newable<IHttpEndpoint<Input, Output> | IHttpEventHandler<Output>>): Handler<APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2>;
}

@@ -16,0 +25,0 @@ export declare const useTrigintaHttp: IServiceModule;

@@ -15,3 +15,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpLambda = exports.useTrigintaHttp = exports.HttpLambdaFactory = void 0;
exports.HttpLambda = exports.useTrigintaHttp = exports.HttpLambdaFactory = exports.HttpResponseGenerator = void 0;
/* eslint-disable @typescript-eslint/ban-types */

@@ -24,2 +24,18 @@ /* eslint-disable @typescript-eslint/no-explicit-any */

const HttpLambdaServices_1 = require("./HttpLambdaServices");
class HttpResponseGenerator {
generateResponse(response) {
return __awaiter(this, void 0, void 0, function* () {
let proxyResponse = response;
if (typeof (proxyResponse === null || proxyResponse === void 0 ? void 0 : proxyResponse.statusCode) === 'undefined') {
// TODO -- Is 200 always correct here?
proxyResponse = {
statusCode: 200,
body: response ? JSON.stringify(response) : undefined,
};
}
return proxyResponse;
});
}
}
exports.HttpResponseGenerator = HttpResponseGenerator;
class HttpLambdaFactory {

@@ -29,19 +45,23 @@ constructor(container) {

}
createEventHandler(newable) {
return this.createHandler(newable);
}
createHandler(newable) {
const handler = (event) => __awaiter(this, void 0, void 0, function* () {
const childContainer = this.container.createChildContainer('httpLambda');
// TODO -- Containr doens't have a way to inject itself YET so we'll just pull the dependency out of the container directly
const responseGenerator = childContainer.get(HttpLambdaServices_1.HttpLambdaServices.HttpResponseGenerator);
try {
const endpoint = this.container.resolve(newable);
const handler = this.container.resolve(newable);
const { body: request } = event;
const response = (yield endpoint.handle(request, event));
// TODO -- Break this out into a response writer
let proxyResponse = response;
if (typeof (proxyResponse === null || proxyResponse === void 0 ? void 0 : proxyResponse.statusCode) === 'undefined') {
// TODO -- Is 200 always correct here?
proxyResponse = {
statusCode: 200,
body: response ? JSON.stringify(response) : undefined,
};
let response;
if (request) {
const endpoint = handler;
response = (yield endpoint.handle(request, event));
}
return proxyResponse;
else {
const eventHandler = handler;
response = (yield eventHandler.handle(event));
}
return responseGenerator.generateResponse(response);
}

@@ -72,2 +92,3 @@ finally {

exports.useTrigintaHttp = (0, containr_1.createServiceModule)('triginta/http', (services) => {
services.use(HttpLambdaServices_1.HttpLambdaServices.HttpResponseGenerator, HttpResponseGenerator);
services.register(HttpLambdaServices_1.HttpLambdaServices.HttpLambdaFactory, (container) => new HttpLambdaFactory(container));

@@ -81,2 +102,6 @@ });

return {
createHttpEventLambda(newable) {
const factory = container.get(HttpLambdaServices_1.HttpLambdaServices.HttpLambdaFactory);
return factory.createEventHandler(newable);
},
createHttpLambda(newable) {

@@ -83,0 +108,0 @@ const factory = container.get(HttpLambdaServices_1.HttpLambdaServices.HttpLambdaFactory);

export declare const HttpLambdaServices: {
HttpLambdaFactory: string;
HttpResponseGenerator: string;
};

@@ -6,2 +6,3 @@ "use strict";

HttpLambdaFactory: 'HttpLambdaFactory',
HttpResponseGenerator: 'HttpResponseGenerator',
};

@@ -1,3 +0,6 @@

export interface IHandler<Message, Event = any, Return = void> {
export interface IEventHandler<Event = any, Return = void> {
handle(event: Event): Promise<Return>;
}
export interface IMessageHandler<Message, Event = any, Return = void> {
handle(message: Message, event: Event): Promise<Return>;
}
"use strict";
/* eslint-disable @typescript-eslint/no-explicit-any */
Object.defineProperty(exports, "__esModule", { value: true });
import { APIGatewayProxyEventV2 } from 'aws-lambda';
import { IHandler } from './IHandler';
export interface IHttpEndpoint<Input, Output> extends IHandler<Input, APIGatewayProxyEventV2, Output> {
import { IEventHandler, IMessageHandler } from './IHandler';
export interface IHttpEventHandler<Output = void> extends IEventHandler<APIGatewayProxyEventV2, Output> {
}
export interface IHttpEndpoint<Input, Output> extends IMessageHandler<Input, APIGatewayProxyEventV2, Output> {
}

@@ -1,4 +0,3 @@

import 'reflect-metadata';
import { IHandler } from './IHandler';
import { IHttpEndpoint } from './IHttpEndpoint';
export * from './IHandler';
export * from './IHttpEndpoint';
export * from './Decorators';

@@ -11,2 +10,1 @@ export * from './HttpLambda';

export * from './TrigintaConfig';
export { IHandler, IHttpEndpoint };

@@ -21,5 +21,5 @@ "use strict";

exports.RouteRegistry = void 0;
require("reflect-metadata");
__exportStar(require("./IHandler"), exports);
__exportStar(require("./IHttpEndpoint"), exports);
__exportStar(require("./Decorators"), exports);
// export * from './Middleware';
__exportStar(require("./HttpLambda"), exports);

@@ -26,0 +26,0 @@ __exportStar(require("./HttpLambdaServices"), exports);

import { APIGatewayProxyEventPathParameters, APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2 } from 'aws-lambda';
import { IServiceContainer } from '@aesop-fables/containr';
import { IConfiguredRoute } from './IConfiguredRoute';
export interface InvocationContext {
declare type InvocableEvent = Omit<APIGatewayProxyEventV2, 'body'> & {
body: any;
};
export interface InvocationContext extends Partial<InvocableEvent> {
configuredRoute: IConfiguredRoute;
container: IServiceContainer;
body?: any;
path: string;
}

@@ -15,1 +16,2 @@ export declare function parseRouteParams(route: string, path: string): APIGatewayProxyEventPathParameters;

export declare function invokeHttpHandler<Output>(context: InvocationContext): Promise<APIGatewayProxyStructuredResultV2>;
export {};

@@ -55,6 +55,7 @@ "use strict";

function parsePathParameters(context) {
const { path } = context;
var _a;
const { rawPath } = context;
let queryStringParameters = {};
if (path.indexOf('?') !== -1) {
const values = path.split('?');
if ((rawPath === null || rawPath === void 0 ? void 0 : rawPath.indexOf('?')) !== -1) {
const values = (_a = rawPath === null || rawPath === void 0 ? void 0 : rawPath.split('?')) !== null && _a !== void 0 ? _a : [];
if (values.length > 1) {

@@ -65,4 +66,4 @@ queryStringParameters = node_querystring_1.default.parse(values[1]);

return {
rawPath: path,
pathParameters: parseRouteParams(context.configuredRoute.route, context.path),
rawPath,
pathParameters: parseRouteParams(context.configuredRoute.route, context.rawPath),
queryStringParameters,

@@ -72,17 +73,27 @@ };

exports.parsePathParameters = parsePathParameters;
function stringOrJsonStringify(input) {
if (typeof input === 'undefined') {
return undefined;
}
if (typeof input === 'string') {
return input;
}
return JSON.stringify(input);
}
const DEFAULT_HEADERS = {
accept: '*/*',
'accept-encoding': 'gzip, deflate, br',
// 'content-length': '0',
'content-type': 'application/json',
host: '',
'user-agent': 'triginta/1.0',
'x-amzn-trace-id': 'Root=1-63e26f79-577a8db87d3b31fa4da65566',
'x-forwarded-for': '127.0.0.1',
'x-forwarded-port': '80',
'x-forwarded-proto': 'http',
};
function createApiGatewayEvent(context) {
const { configuredRoute, path, body } = context;
const { configuredRoute, rawPath, body, headers } = context;
const routeKey = `${configuredRoute.method} ${configuredRoute.route}`;
const event = Object.assign({ version: '2.0', routeKey, headers: {
accept: '*/*',
'accept-encoding': 'gzip, deflate, br',
// 'content-length': '0',
'content-type': 'application/json',
host: '',
'user-agent': 'triginta/1.0',
'x-amzn-trace-id': 'Root=1-63e26f79-577a8db87d3b31fa4da65566',
'x-forwarded-for': '127.0.0.1',
'x-forwarded-port': '80',
'x-forwarded-proto': 'http',
}, requestContext: {
const event = Object.assign({ version: '2.0', routeKey, headers: Object.assign(Object.assign({}, DEFAULT_HEADERS), headers), requestContext: {
accountId: '888888888888',

@@ -94,3 +105,3 @@ apiId: 'trigintaLocal',

method: configuredRoute.method,
path,
path: rawPath !== null && rawPath !== void 0 ? rawPath : '',
protocol: 'HTTP/1.1',

@@ -105,3 +116,3 @@ sourceIp: '127.0.0.1',

timeEpoch: Date.now(),
}, body: body ? JSON.stringify(body) : undefined }, parsePathParameters(context));
}, body: stringOrJsonStringify(body) }, parsePathParameters(context));
return event;

@@ -108,0 +119,0 @@ }

{
"name": "@aesop-fables/triginta",
"version": "0.3.4",
"version": "0.4.0",
"description": "A lightweight framework that wraps the basic infrastructure usages of AWS Lambda (SQS, Kinesis, etc.).",

@@ -27,12 +27,15 @@ "type": "commonjs",

"devDependencies": {
"@aesop-fables/containr": "^0.1.5",
"@aesop-fables/containr": "^0.2.3",
"@middy/core": "^4.2.7",
"@middy/http-error-handler": "^4.2.3",
"@middy/http-json-body-parser": "^4.2.3",
"@types/aws-lambda": "^8.10.109",
"@types/jest": "^29.2.4",
"@types/jest": "^29.5.0",
"@types/node": "^18.11.11",
"@typescript-eslint/eslint-plugin": "^5.45.1",
"@typescript-eslint/parser": "5.52.0",
"@typescript-eslint/parser": "5.55.0",
"esbuild": "^0.17.8",
"eslint": "8.34.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-jest": "27.1.6",
"eslint-plugin-jest": "27.2.1",
"eslint-plugin-prettier": "^4.2.1",

@@ -42,3 +45,4 @@ "jest": "29.3.1",

"prettier": "^2.8.1",
"ts-jest": "29.0.1",
"reflect-metadata": "^0.1.13",
"ts-jest": "29.0.5",
"typescript": "4.9.5"

@@ -49,8 +53,8 @@ },

],
"dependencies": {
"@middy/core": "^4.2.3",
"@middy/http-error-handler": "^4.2.3",
"@middy/http-json-body-parser": "^4.2.3",
"reflect-metadata": "^0.1.13",
"xss": "^1.0.9"
"peerDependencies": {
"@aesop-fables/containr": "0.2.x",
"@middy/core": "4.x",
"@middy/http-error-handler": "4.x",
"@middy/http-json-body-parser": "4.x",
"reflect-metadata": "0.1.x"
},

@@ -57,0 +61,0 @@ "repository": {

# @aesop-fables/triginta
`triginta` is a lightweight framework that wraps the basic infrastructure usages of AWS Lambda (SQS, Kinesis, etc.). For APIs, see our `API framework`. It aims
to conventionalize logging, error handling, and X-Ray integration.
`triginta` is a lightweight framework that wraps the basic infrastructure usages of AWS Lambda (SQS, Kinesis, etc.) and is entirely based on top of Middyjs.

@@ -14,35 +13,13 @@ ## Installation

## Supported Lambdas
The following can be created via the `ILambdaFactory` interface:
## Docs
1. SQS Lambdas (`createSqsLambda`)
2. S3 Lambdas (`createS3Lambda`)
3. Kinesis Lambdas (`createKinesisLambda`)
Docs are coming. In the meantime, we recommend you checkout the docs from middyjs and our example repo:
https://github.com/aesop-fables/triginta-example
## Known issues
We're missing unit tests, logging, error handling, middleware support, and X-Ray integration. This will all come soon - I just wanted to get the basic structure published.
## Example
```typescript
// index.ts
interface MyQueuedMessage {
message: string;
}
## Breaking Changes
class MyLambda implements IHandler<MyQueuedMessage> {
async handle(message: MyQueuedMessage): Promise<void> {
console.log('HELLO, WORLD!');
console.log(JSON.stringify(message, null, 2));
}
}
### v0.4.0
// obviously you need to register all of your stuff
const container = bootstrap();
// triginta doesn't depend on containr but it abstracts out the creation of your handler
// so that you can easily plug it in (see the `factory` property)
const lambdaFactory = container.get<ILambdaFactory>();
export const handler = lambdaFactory.createSqsLambda<MyLambda>({
factory: () => container.get<MyLambda>('lambda'),
});
```
The `path` property of the `InvocationContext` (used in `invokeHttpHandler`) was renamed to `rawPath` to properly match the
expected API Gateway Event.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc