@serverless-seoul/corgi
Advanced tools
Comparing version 3.2.0 to 3.2.1
@@ -1,13 +0,5 @@ | ||
import { ErrorObject } from "ajv"; | ||
import { Route } from "./route"; | ||
export declare class TimeoutError extends Error { | ||
readonly route: Route<any, any>; | ||
readonly name = "TimeoutError"; | ||
constructor(route: Route<any, any>); | ||
readonly route: Route; | ||
constructor(route: Route); | ||
} | ||
export declare class ValidationError extends Error { | ||
readonly message: string; | ||
readonly details: ErrorObject[]; | ||
readonly name = "ValidationError"; | ||
constructor(message: string, details: ErrorObject[]); | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ValidationError = exports.TimeoutError = void 0; | ||
exports.TimeoutError = void 0; | ||
class TimeoutError extends Error { | ||
@@ -8,15 +8,5 @@ constructor(route) { | ||
this.route = route; | ||
this.name = "TimeoutError"; | ||
} | ||
} | ||
exports.TimeoutError = TimeoutError; | ||
class ValidationError extends Error { | ||
constructor(message, details) { | ||
super(message); | ||
this.message = message; | ||
this.details = details; | ||
this.name = "ValidationError"; | ||
} | ||
} | ||
exports.ValidationError = ValidationError; | ||
//# sourceMappingURL=errors.js.map |
@@ -11,11 +11,11 @@ import { Response } from "./lambda-proxy"; | ||
export interface MiddlewareBeforeOptions<Metadata> { | ||
routingContext: RoutingContext<any, any>; | ||
currentRoute: Route<any, any>; | ||
routingContext: RoutingContext; | ||
currentRoute: Route; | ||
metadata?: Metadata; | ||
} | ||
export interface MiddlewareAfterOptions<Metadata> { | ||
routingContext: RoutingContext<any, any>; | ||
currentRoute: Route<any, any>; | ||
routingContext: RoutingContext; | ||
currentRoute: Route; | ||
metadata?: Metadata; | ||
response: Response; | ||
} |
@@ -1,37 +0,28 @@ | ||
import { TStatic } from "@catchfashion/typebox"; | ||
import * as Joi from "joi"; | ||
import { Response } from "./lambda-proxy"; | ||
import { Route } from "./route"; | ||
import { RoutingContext } from "./routing-context"; | ||
declare type MergeParams<T, U> = string extends keyof U ? T : T & U; | ||
export declare class Namespace<T extends { | ||
[P in keyof T]: TStatic; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
} = { | ||
[key: string]: TStatic; | ||
}> { | ||
export declare class Namespace { | ||
readonly path: string; | ||
readonly params: T; | ||
readonly options: { | ||
before?: (this: RoutingContext<any, MergeParams<T, U>>) => Promise<void>; | ||
exceptionHandler?: ExceptionHandler<Partial<MergeParams<T, U>>>; | ||
/** | ||
* All the params are from 'PATH'. namespace currently won't support query param validation or access | ||
*/ | ||
children: Routes<MergeParams<T, U>>; | ||
private options; | ||
constructor(path: string, options: NamespaceOptions); | ||
get before(): ((this: RoutingContext) => Promise<void>) | undefined; | ||
get children(): Routes; | ||
get params(): { | ||
[name: string]: Joi.Schema; | ||
} | undefined; | ||
get exceptionHandler(): ExceptionHandler | undefined; | ||
} | ||
export declare type ExceptionHandler = (this: RoutingContext, error: Error) => Promise<Response | void>; | ||
export interface NamespaceOptions { | ||
before?: (this: RoutingContext) => Promise<void>; | ||
exceptionHandler?: ExceptionHandler; | ||
/** | ||
* All the params are from 'PATH'. namespace currently won't support query param validation or access | ||
*/ | ||
params?: { | ||
[name: string]: Joi.Schema; | ||
}; | ||
constructor(path: string, params: T, options: { | ||
before?: (this: RoutingContext<any, MergeParams<T, U>>) => Promise<void>; | ||
exceptionHandler?: ExceptionHandler<Partial<MergeParams<T, U>>>; | ||
/** | ||
* All the params are from 'PATH'. namespace currently won't support query param validation or access | ||
*/ | ||
children: Routes<MergeParams<T, U>>; | ||
}); | ||
get before(): ((this: RoutingContext<any, MergeParams<T, U>>) => Promise<void>) | undefined; | ||
get children(): Routes<MergeParams<T, U>>; | ||
get exceptionHandler(): ExceptionHandler<Partial<MergeParams<T, U>>> | undefined; | ||
children: Routes; | ||
} | ||
export declare type ExceptionHandler<T> = (this: RoutingContext<any, T>, error: Error) => Promise<Response | void>; | ||
export declare type Routes<T = any> = Array<Namespace<any, T> | Route<any, T>>; | ||
export {}; | ||
export declare type Routes = Array<Namespace | Route>; |
@@ -6,8 +6,7 @@ "use strict"; | ||
class Namespace { | ||
constructor(path, params, options) { | ||
constructor(path, options) { | ||
this.path = path; | ||
this.params = params; | ||
this.options = options; | ||
if (options.children.length === 0) { | ||
throw new Error("Namespace must have children"); | ||
throw new Error("Namespace must have childrens"); | ||
} | ||
@@ -17,2 +16,3 @@ } | ||
get children() { return this.options.children; } | ||
get params() { return this.options.params; } | ||
get exceptionHandler() { return this.options.exceptionHandler; } | ||
@@ -19,0 +19,0 @@ } |
@@ -13,3 +13,3 @@ import * as OpenApi from "openapi3-ts"; | ||
}); | ||
export declare class OpenAPIRoute extends Namespace<any, any> { | ||
export declare class OpenAPIRoute extends Namespace { | ||
constructor(path: string, info: OpenAPIRouteOptions, routes: Routes); | ||
@@ -16,0 +16,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.OpenAPIGenerator = exports.OpenAPIRoute = void 0; | ||
const typebox_1 = require("@catchfashion/typebox"); | ||
const _ = require("lodash"); | ||
const JoiToJSONSchema = require("vingle-corgi-joi-to-json-schema"); | ||
const namespace_1 = require("../namespace"); | ||
const route_1 = require("../route"); | ||
const router_1 = require("../router"); | ||
function deepOmit(obj, keysToOmit) { | ||
const keysToOmitIndex = _.keyBy(keysToOmit); // create an index object of the keys that should be omitted | ||
const omitFromObject = (objectToOmit) => { | ||
// the inner function which will be called recursively | ||
return _.transform(objectToOmit, function (result, value, key) { | ||
if (key in keysToOmitIndex) { // if the key is in the index skip it | ||
return; | ||
} | ||
// if the key is an object run it through the inner function - omitFromObject | ||
result[key] = _.isObject(value) ? omitFromObject(value) : value; | ||
}); | ||
}; | ||
return omitFromObject(obj); // return the inner function result | ||
} | ||
function convertJoiToJSONSchema(joi) { | ||
return deepOmit(JoiToJSONSchema(joi), ["additionalProperties", "patterns"]); | ||
} | ||
class OpenAPIRoute extends namespace_1.Namespace { | ||
@@ -20,3 +38,3 @@ constructor(path, info, routes) { | ||
}; | ||
super(path, {}, { | ||
super(path, { | ||
children: [ | ||
@@ -63,33 +81,50 @@ route_1.Route.OPTIONS("", { desc: "CORS Preflight Endpoint for OpenAPI Documentation API", operationId: "optionOpenAPI" }, {}, async function () { | ||
operationId: endRoute.operationId, | ||
parameters: routes.flatMap((route) => { | ||
parameters: _.flatMap(routes, (route) => { | ||
if (route instanceof namespace_1.Namespace) { | ||
// Namespace only supports path | ||
return Object.entries(route.params) | ||
.map(([name, schema]) => ({ | ||
in: "path", | ||
name, | ||
description: schema.description, | ||
schema, | ||
required: true, | ||
})); | ||
return _.map(route.params, (schema, name) => { | ||
return { | ||
in: "path", | ||
name, | ||
description: schema.describe().description, | ||
schema: { | ||
type: convertJoiToJSONSchema(schema).type, | ||
}, | ||
required: true | ||
}; | ||
}); | ||
} | ||
else { | ||
return Object.entries(route.params) | ||
.filter(([name, param]) => param.in !== "body") | ||
.map(([name, param]) => ({ | ||
in: param.in, | ||
name, | ||
description: param.def.description, | ||
schema: param.def, | ||
required: param.in === "path" || param.def.modifier !== typebox_1.OptionalModifier, | ||
})); | ||
return _.chain(route.params) | ||
.toPairs() | ||
.filter(r => r[1].in !== "body") | ||
.map(([name, def]) => { | ||
const { description, flags } = def.def.describe(); | ||
return { | ||
in: def.in, | ||
name, | ||
description, | ||
schema: convertJoiToJSONSchema(def.def), | ||
required: def.in === "path" | ||
|| (flags || {}).presence !== "optional", | ||
}; | ||
}) | ||
.value(); | ||
} | ||
}), | ||
requestBody: (() => { | ||
const bodyParams = routes | ||
.flatMap((route) => route instanceof route_1.Route | ||
? Object.entries(route.params) | ||
.filter(([name, param]) => param.in === "body") | ||
: []) | ||
.map(([name, param]) => [name, param.def]); | ||
const bodyParams = _.chain(routes) | ||
.flatMap((route) => { | ||
if (route instanceof namespace_1.Namespace) { | ||
return []; | ||
} | ||
else { | ||
return _.chain(route.params) | ||
.toPairs() | ||
.filter(r => r[1].in === "body") | ||
.value(); | ||
} | ||
}) | ||
.map(([name, paramDef]) => ([name, convertJoiToJSONSchema(paramDef.def)])) | ||
.value(); | ||
if (bodyParams.length > 0) { | ||
@@ -103,7 +138,7 @@ return { | ||
type: "object", | ||
properties: Object.fromEntries(bodyParams), | ||
required: bodyParams.map(([name]) => name), | ||
}, | ||
}, | ||
}, | ||
properties: _.fromPairs(bodyParams), | ||
required: bodyParams.map(pair => pair[0]), | ||
} | ||
} | ||
} | ||
}; | ||
@@ -160,3 +195,3 @@ } | ||
toOpenAPIPath(path) { | ||
return path.replace(/:(\w+)/g, "{$1}"); | ||
return path.replace(/\:(\w+)/g, "{$1}"); | ||
} | ||
@@ -163,0 +198,0 @@ } |
@@ -1,11 +0,14 @@ | ||
import { TStatic } from "@catchfashion/typebox"; | ||
export declare type ParameterInputType = "query" | "header" | "path" | "body"; | ||
export interface ParameterDefinition<T extends TStatic> { | ||
import * as Joi from "joi"; | ||
export declare type ParameterInputType = "query" | "header" | "path" | "formData" | "body"; | ||
export interface ParameterDefinition { | ||
in: ParameterInputType; | ||
def: T; | ||
def: Joi.Schema; | ||
} | ||
export interface ParameterDefinitionMap { | ||
[key: string]: ParameterDefinition; | ||
} | ||
export declare class Parameter { | ||
static Query<T extends TStatic>(schema: T): ParameterDefinition<T>; | ||
static Path<T extends TStatic>(schema: T): ParameterDefinition<T>; | ||
static Body<T extends TStatic>(schema: T): ParameterDefinition<T>; | ||
static Query(schema: Joi.Schema): ParameterDefinition; | ||
static Path(schema: Joi.Schema): ParameterDefinition; | ||
static Body(schema: Joi.Schema): ParameterDefinition; | ||
} |
import { ErrorResponseFormatter } from "./error_response"; | ||
import { Namespace, Routes } from "./namespace"; | ||
export declare class RootNamespace extends Namespace<{}, {}> { | ||
export declare class RootNamespace extends Namespace { | ||
readonly errorFormatter: ErrorResponseFormatter; | ||
constructor(children: Routes); | ||
} |
@@ -9,10 +9,7 @@ "use strict"; | ||
const errorFormatter = new error_response_1.ErrorResponseFormatter(process.env.CORGI_ERROR_PASSSWORD); | ||
super("", {}, { | ||
super("", { | ||
async exceptionHandler(error) { | ||
if (error instanceof error_response_1.StandardError) { | ||
return this.json({ | ||
error: { | ||
id: this.requestId, | ||
...errorFormatter.format(error), | ||
} | ||
error: Object.assign({ id: this.requestId }, errorFormatter.format(error)) | ||
}, error.statusCode); | ||
@@ -23,6 +20,3 @@ } | ||
return this.json({ | ||
error: { | ||
id: this.requestId, | ||
...errorFormatter.format(error), | ||
} | ||
error: Object.assign({ id: this.requestId }, errorFormatter.format(error)) | ||
}, 500); | ||
@@ -29,0 +23,0 @@ } |
@@ -1,52 +0,15 @@ | ||
import { TStatic } from "@catchfashion/typebox"; | ||
import { ParameterDefinition } from "../../parameter"; | ||
import { ParameterDefinitionMap } from "../../parameter"; | ||
import { HttpMethod, Route, RouteSimplifiedOptions } from "../../route"; | ||
import { RoutingContext } from "../../routing-context"; | ||
import { Presenter } from "./presenter"; | ||
export declare type PresenterRouteHandler<Input, T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}> = (this: RoutingContext<T, U>) => Promise<Input>; | ||
export declare type PresenterRouteHandler<Input> = (this: RoutingContext) => Promise<Input>; | ||
export declare class PresenterRouteFactory { | ||
static create<Entity, Output, T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, method: HttpMethod, options: RouteSimplifiedOptions, params: T, presenter: Presenter<Entity, Output>, handler: PresenterRouteHandler<Entity, T, U>): Route<T, U>; | ||
static GET<Input, Output, T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input, T, U>): Route<T, U>; | ||
static POST<Input, Output, T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input, T, U>): Route<T, U>; | ||
static PUT<Input, Output, T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input, T, U>): Route<T, U>; | ||
static PATCH<Input, Output, T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input, T, U>): Route<T, U>; | ||
static DELETE<Input, Output, T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input, T, U>): Route<T, U>; | ||
static OPTIONS<Input, Output, T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input, T, U>): Route<T, U>; | ||
static HEAD<Input, Output, T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input, T, U>): Route<T, U>; | ||
static create<Entity, Output>(path: string, method: HttpMethod, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, presenter: Presenter<Entity, Output>, handler: PresenterRouteHandler<Entity>): Route; | ||
static GET<Input, Output>(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input>): Route; | ||
static POST<Input, Output>(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input>): Route; | ||
static PUT<Input, Output>(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input>): Route; | ||
static PATCH<Input, Output>(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input>): Route; | ||
static DELETE<Input, Output>(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input>): Route; | ||
static OPTIONS<Input, Output>(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input>): Route; | ||
static HEAD<Input, Output>(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, presenter: Presenter<Input, Output>, handler: PresenterRouteHandler<Input>): Route; | ||
} |
@@ -1,53 +0,16 @@ | ||
import { TStatic } from "@catchfashion/typebox"; | ||
import * as LambdaProxy from "./lambda-proxy"; | ||
import { ParameterDefinition } from "./parameter"; | ||
import { ParameterDefinitionMap } from "./parameter"; | ||
import { RoutingContext } from "./routing-context"; | ||
import { Middleware, MiddlewareConstructor } from "./middleware"; | ||
export declare type HttpMethod = "GET" | "PUT" | "POST" | "PATCH" | "DELETE" | "OPTIONS" | "HEAD"; | ||
export declare type RouteHandler<T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}> = (this: RoutingContext<T, U>) => Promise<LambdaProxy.Response>; | ||
export declare type RouteHandler = (this: RoutingContext) => Promise<LambdaProxy.Response>; | ||
export declare type RouteMetadata = Map<Function, any>; | ||
export declare class Route<T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}> { | ||
static GET<T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, handler: RouteHandler<T, U>): Route<T, U>; | ||
static PUT<T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, handler: RouteHandler<T, U>): Route<T, U>; | ||
static POST<T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, handler: RouteHandler<T, U>): Route<T, U>; | ||
static PATCH<T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, handler: RouteHandler<T, U>): Route<T, U>; | ||
static DELETE<T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, handler: RouteHandler<T, U>): Route<T, U>; | ||
static OPTIONS<T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, handler: RouteHandler<T, U>): Route<T, U>; | ||
static HEAD<T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}>(path: string, options: RouteSimplifiedOptions, params: T, handler: RouteHandler<T, U>): Route<T, U>; | ||
export declare class Route { | ||
static GET(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, handler: RouteHandler): Route; | ||
static PUT(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, handler: RouteHandler): Route; | ||
static POST(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, handler: RouteHandler): Route; | ||
static PATCH(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, handler: RouteHandler): Route; | ||
static DELETE(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, handler: RouteHandler): Route; | ||
static OPTIONS(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, handler: RouteHandler): Route; | ||
static HEAD(path: string, options: RouteSimplifiedOptions, params: ParameterDefinitionMap, handler: RouteHandler): Route; | ||
private static _factory; | ||
@@ -57,8 +20,8 @@ readonly path: string; | ||
readonly description: string | undefined; | ||
readonly handler: RouteHandler<T, U>; | ||
readonly params: T; | ||
readonly handler: RouteHandler; | ||
readonly params: ParameterDefinitionMap | undefined; | ||
readonly operationId: string; | ||
readonly responses: Map<number, ResponseSchema> | undefined; | ||
readonly metadata: RouteMetadata; | ||
constructor(options: RouteOptions<T, U>); | ||
constructor(options: RouteOptions); | ||
getMetadata<Metadata>(klass: MiddlewareConstructor<Middleware<Metadata>>): Metadata | undefined; | ||
@@ -74,7 +37,3 @@ } | ||
} | ||
export interface RouteOptions<T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
}> { | ||
export interface RouteOptions { | ||
path: string; | ||
@@ -88,4 +47,4 @@ method: HttpMethod; | ||
metadata?: RouteMetadata; | ||
params?: T; | ||
handler: RouteHandler<T, U>; | ||
params?: ParameterDefinitionMap; | ||
handler: RouteHandler; | ||
} | ||
@@ -92,0 +51,0 @@ export interface ResponseSchema { |
@@ -12,3 +12,3 @@ "use strict"; | ||
this.handler = options.handler; | ||
this.params = options.params || {}; | ||
this.params = options.params; | ||
this.operationId = options.operationId; | ||
@@ -20,2 +20,3 @@ this.responses = options.responses ? new Map(_.toPairs(options.responses || {}) | ||
// Simplified Constructors | ||
// tslint:disable:max-line-length | ||
static GET(path, options, params, handler) { | ||
@@ -22,0 +23,0 @@ return this._factory(path, "GET", options, params, handler); |
@@ -5,4 +5,4 @@ import * as LambdaProxy from "./lambda-proxy"; | ||
import { Route } from "./route"; | ||
export declare function flattenRoutes(routes: Routes): Routes<any>[]; | ||
export declare function flattenRoute(parents: Routes, route: Route<any, any> | Namespace<any, any>): Routes[]; | ||
export declare function flattenRoutes(routes: Routes): Routes[]; | ||
export declare function flattenRoute(parents: Array<Route | Namespace>, route: Route | Namespace): Routes[]; | ||
export declare class Router { | ||
@@ -19,3 +19,3 @@ private flattenRoutes; | ||
findMiddleware<T extends Middleware>(middlewareClass: MiddlewareConstructor<T>): T | undefined; | ||
findRoute(operationId: string): Route<any, any> | undefined; | ||
findRoute(operationId: string): Route | undefined; | ||
handler(): (event: LambdaProxy.Event, context: LambdaProxy.Context) => Promise<LambdaProxy.Response | undefined>; | ||
@@ -22,0 +22,0 @@ private readonly routeToPathRegexpCache; |
@@ -13,3 +13,7 @@ "use strict"; | ||
function flattenRoutes(routes) { | ||
return routes.flatMap((route) => flattenRoute([], route)); | ||
let flattenedRoutes = []; | ||
routes.forEach(route => { | ||
flattenedRoutes = [...flattenedRoutes, ...flattenRoute([], route)]; | ||
}); | ||
return flattenedRoutes; | ||
} | ||
@@ -27,5 +31,11 @@ exports.flattenRoutes = flattenRoutes; | ||
else { | ||
return route | ||
.children | ||
.flatMap((childRoute) => flattenRoute([...parents, route], childRoute)); | ||
let routes = []; | ||
route.children.forEach((childRoute) => { | ||
const childRoutes = flattenRoute([...parents, route], childRoute); | ||
routes = [ | ||
...routes, | ||
...childRoutes, | ||
]; | ||
}); | ||
return routes; | ||
} | ||
@@ -32,0 +42,0 @@ } |
@@ -1,10 +0,5 @@ | ||
import { Static, TStatic } from "@catchfashion/typebox"; | ||
import * as LambdaProxy from "./lambda-proxy"; | ||
import { ParameterDefinition } from "./parameter"; | ||
import { ParameterDefinitionMap } from "./parameter"; | ||
import { Router } from "./router"; | ||
export declare class RoutingContext<T extends { | ||
[P in keyof T]: ParameterDefinition<any>; | ||
}, U extends { | ||
[P in keyof U]: TStatic; | ||
} = {}> { | ||
export declare class RoutingContext { | ||
readonly router: Router; | ||
@@ -15,7 +10,7 @@ readonly request: LambdaProxy.Event; | ||
get headers(): LambdaProxy.Event["headers"]; | ||
get params(): (string extends keyof U ? {} : { [P in keyof U]: Static<U[P]>; }) & (string extends keyof T ? {} : { [P_1 in keyof T]: Static<T[P_1]["def"]>; }) & { | ||
[key: string]: unknown; | ||
get params(): { | ||
[key: string]: any; | ||
}; | ||
get bodyJSON(): object | string | undefined; | ||
private readonly validatedParams; | ||
private validatedParams; | ||
private normalizedHeaders; | ||
@@ -25,5 +20,3 @@ constructor(router: Router, request: LambdaProxy.Event, requestId: string | undefined, pathParams: { | ||
}); | ||
validateAndUpdateParams(parameterDefinitionMap: { | ||
[key: string]: ParameterDefinition<any>; | ||
}): void; | ||
validateAndUpdateParams(parameterDefinitionMap: ParameterDefinitionMap): void; | ||
json(json: any, statusCode?: number, headers?: NonNullable<LambdaProxy.Response["headers"]>): LambdaProxy.Response; | ||
@@ -30,0 +23,0 @@ private decodeURI; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.RoutingContext = void 0; | ||
const typebox_1 = require("@catchfashion/typebox"); | ||
const Ajv = require("ajv"); | ||
const Joi = require("joi"); | ||
const _ = require("lodash"); | ||
const qs = require("qs"); | ||
const errors_1 = require("./errors"); | ||
const ajv = new Ajv({ | ||
allErrors: true, | ||
async: false, | ||
coerceTypes: true, | ||
removeAdditional: "all", | ||
}); | ||
// | ||
const DefaultJoiValidateOptions = { | ||
stripUnknown: true, | ||
presence: "required", | ||
abortEarly: false, | ||
}; | ||
// ---- RoutingContext | ||
@@ -58,16 +56,17 @@ class RoutingContext { | ||
validateAndUpdateParams(parameterDefinitionMap) { | ||
const groupByIn = Object.entries(parameterDefinitionMap).reduce((hash, [name, schema]) => { | ||
var _a; | ||
hash[_a = schema.in] || (hash[_a] = {}); | ||
hash[schema.in][name] = schema.def; | ||
return hash; | ||
}, {}); | ||
const groupByIn = {}; | ||
_.forEach(parameterDefinitionMap, (schema, name) => { | ||
if (!groupByIn[schema.in]) { | ||
groupByIn[schema.in] = {}; | ||
} | ||
groupByIn[schema.in][name] = schema.def; | ||
}); | ||
const validate = (rawParams, schemaMap) => { | ||
const params = _.cloneDeep(rawParams !== null && rawParams !== void 0 ? rawParams : {}); | ||
const valid = ajv.validate(typebox_1.Type.Object(schemaMap), params); | ||
if (!valid) { | ||
const errors = ajv.errors; | ||
throw new errors_1.ValidationError(ajv.errorsText(errors), errors); | ||
const res = Joi.validate(rawParams || {}, Joi.object(schemaMap), DefaultJoiValidateOptions); | ||
if (res.error) { | ||
throw res.error; | ||
} | ||
Object.assign(this.validatedParams, params); | ||
else { | ||
Object.assign(this.validatedParams, res.value); | ||
} | ||
}; | ||
@@ -91,6 +90,3 @@ if (groupByIn.path) { | ||
statusCode, | ||
headers: { | ||
"Content-Type": "application/json; charset=utf-8", | ||
...headers, | ||
}, | ||
headers: Object.assign({ "Content-Type": "application/json; charset=utf-8" }, headers), | ||
body: JSON.stringify(json), | ||
@@ -97,0 +93,0 @@ }; |
{ | ||
"name": "@serverless-seoul/corgi", | ||
"version": "3.2.0", | ||
"version": "3.2.1", | ||
"description": "Restful HTTP Framework for AWS Lambda - AWS API Gateway Proxy Integration", | ||
@@ -51,14 +51,15 @@ "main": "./dst/index.js", | ||
"dependencies": { | ||
"@catchfashion/typebox": "^1.0.1", | ||
"@types/aws-lambda": "^8.10.62", | ||
"@types/joi": "^13.0.2", | ||
"@types/lodash": "^4.14.161", | ||
"@types/node": "^12.12.62", | ||
"@types/qs": "^6.9.5", | ||
"ajv": "^6.12.5", | ||
"aws-xray-sdk-core": ">=1.1.6", | ||
"joi": "^13.0.2", | ||
"lodash": "^4.17.20", | ||
"openapi3-ts": "^2.0.0", | ||
"path-to-regexp": "^6.1.0", | ||
"qs": "^6.9.4" | ||
"qs": "^6.9.4", | ||
"vingle-corgi-joi-to-json-schema": "^3.2.0" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
58
85394
12
1232
1
+ Added@types/joi@^13.0.2
+ Addedjoi@^13.0.2
+ Added@types/joi@13.6.3(transitive)
+ Addedhoek@5.0.46.1.3(transitive)
+ Addedisemail@3.2.0(transitive)
+ Addedjoi@13.7.0(transitive)
+ Addedtopo@3.0.3(transitive)
+ Addedvingle-corgi-joi-to-json-schema@3.2.0(transitive)
- Removed@catchfashion/typebox@^1.0.1
- Removedajv@^6.12.5
- Removed@catchfashion/typebox@1.0.1(transitive)
- Removedajv@6.12.6(transitive)
- Removedfast-deep-equal@3.1.3(transitive)
- Removedfast-json-stable-stringify@2.1.0(transitive)
- Removedjson-schema-traverse@0.4.1(transitive)
- Removeduri-js@4.4.1(transitive)