lambder 1.0.55 → 1.0.57

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/Lambder.d.ts CHANGED
@@ -19,6 +19,7 @@ type RenderContext = {
19
19
  get: Record<string, any>;
20
20
  post: Record<string, any>;
21
21
  cookie: Record<string, any>;
22
+ apiName: string;
22
23
  headers: APIGatewayProxyEventHeaders;
23
24
  session: Session | null;
24
25
  lambdaContext: Context;
@@ -26,14 +27,13 @@ type RenderContext = {
26
27
  type ConditionFunction = (ctx: RenderContext) => boolean;
27
28
  type ActionFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse | Promise<ResolverResponse>;
28
29
  type HookCreatedFunction = (lambderInstance: Lambder) => Promise<void>;
29
- type HookBeforeRenderFunction = (ctx: RenderContext, resolver: Resolver) => RenderContext | Promise<RenderContext>;
30
- type HookAfterRenderFunction = (ctx: RenderContext, resolver: Resolver, response: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
31
- type HookFallbackFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse | Promise<ResolverResponse>;
32
- type HookCompletedFunction = (response: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
30
+ type HookBeforeRenderFunction = (ctx: RenderContext, resolver: Resolver) => RenderContext | Error | Promise<RenderContext | Error>;
31
+ type HookAfterRenderFunction = (ctx: RenderContext, resolver: Resolver, response: ResolverResponse) => ResolverResponse | Error | Promise<ResolverResponse | Error>;
32
+ type HookFallbackFunction = (ctx: RenderContext, resolver: Resolver) => void | Promise<void>;
33
33
  type GlobalErrorHandlerFunction = (err: Error, ctx: RenderContext | null, response: ResponseBuilder) => ResolverResponse | Promise<ResolverResponse>;
34
34
  type RouteFallbackHandlerFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse;
35
35
  type ApiFallbackHandlerFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse;
36
- export declare const createContext: (event: APIGatewayProxyEvent, lambdaContext: Context) => RenderContext;
36
+ export declare const createContext: (event: APIGatewayProxyEvent, lambdaContext: Context, apiPath?: string | null) => RenderContext;
37
37
  export default class Lambder {
38
38
  private apiPath;
39
39
  private apiVersion;
@@ -60,13 +60,12 @@ export default class Lambder {
60
60
  addModule(moduleFn: Function): Promise<void>;
61
61
  addRoute(condition: Path | ConditionFunction | RegExp, actionFn: ActionFunction): void;
62
62
  addSessionRoute(condition: Path | ConditionFunction | RegExp, actionFn: ActionFunction): void;
63
- addApi(condition: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
64
- addSessionApi(condition: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
63
+ addApi(apiName: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
64
+ addSessionApi(apiName: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
65
65
  addHook(hookEvent: 'created', hookFn: HookCreatedFunction, priority?: number): Promise<void>;
66
66
  addHook(hookEvent: 'beforeRender', hookFn: HookBeforeRenderFunction, priority?: number): Promise<void>;
67
67
  addHook(hookEvent: 'afterRender', hookFn: HookAfterRenderFunction, priority?: number): Promise<void>;
68
68
  addHook(hookEvent: 'fallback', hookFn: HookFallbackFunction, priority?: number): Promise<void>;
69
- addHook(hookEvent: 'completed', hookFn: HookCompletedFunction, priority?: number): Promise<void>;
70
69
  getResponseBuilder(): ResponseBuilder;
71
70
  private getResolver;
72
71
  render(event: APIGatewayProxyEvent, lambdaContext: Context): Promise<ResolverResponse>;
package/dist/Lambder.js CHANGED
@@ -3,7 +3,7 @@ import cookieParser from "cookie";
3
3
  import { match } from "path-to-regexp";
4
4
  import Resolver from "./Resolver.js";
5
5
  import ResponseBuilder from "./ResponseBuilder.js";
6
- export const createContext = (event, lambdaContext) => {
6
+ export const createContext = (event, lambdaContext, apiPath = null) => {
7
7
  const host = event.headers.Host || event.headers.host || "";
8
8
  const path = event.path;
9
9
  const pathParams = null;
@@ -13,6 +13,7 @@ export const createContext = (event, lambdaContext) => {
13
13
  const headers = event.headers;
14
14
  let post = {};
15
15
  const session = null;
16
+ const apiName = (method === "POST" && apiPath && path === apiPath && post.apiName) ? post.apiName : null;
16
17
  try {
17
18
  const decodedBody = event.isBase64Encoded ? (event.body ? Buffer.from(event.body, "base64").toString() : "{}") : (event.body || "{}");
18
19
  try {
@@ -26,7 +27,7 @@ export const createContext = (event, lambdaContext) => {
26
27
  if (/^(((\d+\.)+\d+)|(([a-f\d]+:)+[a-f\d]+))$/.test(host)) {
27
28
  throw new Error("[404] Host cannot be an ip address: " + host);
28
29
  }
29
- return { host, path, pathParams, method, get, post, cookie, headers, session, lambdaContext };
30
+ return { host, path, pathParams, method, get, post, cookie, apiName, headers, session, lambdaContext };
30
31
  };
31
32
  export default class Lambder {
32
33
  apiPath;
@@ -48,7 +49,6 @@ export default class Lambder {
48
49
  "beforeRender": [],
49
50
  "afterRender": [],
50
51
  "fallback": [],
51
- "completed": []
52
52
  };
53
53
  }
54
54
  setRouteFallbackHandler(routeFallbackHandler) {
@@ -142,22 +142,20 @@ export default class Lambder {
142
142
  });
143
143
  }
144
144
  ;
145
- addApi(condition, actionFn) {
145
+ addApi(apiName, actionFn) {
146
146
  this.actionList.push({
147
- conditionFn: (ctx) => (ctx.method === "POST" && ctx.path === this.apiPath &&
148
- ((typeof condition === "string" && ctx.post?.api === condition) ||
149
- (typeof condition === "function" && condition(ctx)) ||
150
- (condition?.constructor == RegExp && condition.test(ctx.post?.api)))),
147
+ conditionFn: (ctx) => ((typeof apiName === "string" && ctx.apiName === apiName) ||
148
+ (typeof apiName === "function" && apiName(ctx)) ||
149
+ (apiName?.constructor == RegExp && apiName.test(ctx.apiName))),
151
150
  actionFn: async (ctx, resolver) => await actionFn(ctx, resolver),
152
151
  });
153
152
  }
154
153
  ;
155
- addSessionApi(condition, actionFn) {
154
+ addSessionApi(apiName, actionFn) {
156
155
  this.actionList.push({
157
- conditionFn: (ctx) => (ctx.method === "POST" && ctx.path === this.apiPath &&
158
- ((typeof condition === "string" && ctx.post?.api === condition) ||
159
- (typeof condition === "function" && condition(ctx)) ||
160
- (condition?.constructor == RegExp && condition.test(ctx.post?.api)))),
156
+ conditionFn: (ctx) => ((typeof apiName === "string" && ctx.apiName === apiName) ||
157
+ (typeof apiName === "function" && apiName(ctx)) ||
158
+ (apiName?.constructor == RegExp && apiName.test(ctx.apiName))),
161
159
  actionFn: async (ctx, resolver) => {
162
160
  const isSessionValid = this.validateSession(ctx.session);
163
161
  if (!isSessionValid)
@@ -206,11 +204,19 @@ export default class Lambder {
206
204
  const firstMatchedAction = this.actionList.find(action => action.conditionFn(ctx));
207
205
  if (firstMatchedAction) {
208
206
  for (const hook of this.hookList["beforeRender"]) {
209
- ctx = await hook.hookFn(ctx, resolver);
207
+ const hookCtx = await hook.hookFn(ctx, resolver);
208
+ if (hookCtx instanceof Error) {
209
+ throw hookCtx;
210
+ }
211
+ ctx = hookCtx;
210
212
  }
211
213
  let response = await firstMatchedAction.actionFn(ctx, resolver);
212
214
  for (const hook of this.hookList["afterRender"]) {
213
- response = await hook.hookFn(ctx, resolver, response);
215
+ const hookResponse = await hook.hookFn(ctx, resolver, response);
216
+ if (hookResponse instanceof Error) {
217
+ throw hookResponse;
218
+ }
219
+ response = hookResponse;
214
220
  }
215
221
  resolve(response);
216
222
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lambder",
3
- "version": "1.0.55",
3
+ "version": "1.0.57",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/Lambder.ts CHANGED
@@ -26,6 +26,7 @@ type RenderContext = {
26
26
  get: Record<string, any>;
27
27
  post: Record<string, any>;
28
28
  cookie: Record<string, any>;
29
+ apiName: string;
29
30
  headers: APIGatewayProxyEventHeaders;
30
31
  session: Session|null;
31
32
  lambdaContext: Context;
@@ -36,24 +37,24 @@ type ActionFunction = (ctx: RenderContext, resolver: Resolver) => ResolverRespon
36
37
  type ActionObject = { conditionFn: ConditionFunction, actionFn: ActionFunction };
37
38
 
38
39
  type HookCreatedFunction = (lambderInstance: Lambder) => Promise<void>;
39
- type HookBeforeRenderFunction = (ctx: RenderContext, resolver: Resolver) => RenderContext|Promise<RenderContext>;
40
- type HookAfterRenderFunction = (ctx: RenderContext, resolver: Resolver, response: ResolverResponse) => ResolverResponse|Promise<ResolverResponse>;
41
- type HookFallbackFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse|Promise<ResolverResponse>;
42
- type HookCompletedFunction = (response: ResolverResponse) => ResolverResponse|Promise<ResolverResponse>;
40
+ type HookBeforeRenderFunction = (ctx: RenderContext, resolver: Resolver) => RenderContext|Error|Promise<RenderContext|Error>;
41
+ type HookAfterRenderFunction = (ctx: RenderContext, resolver: Resolver, response: ResolverResponse) => ResolverResponse|Error|Promise<ResolverResponse|Error>;
42
+ type HookFallbackFunction = (ctx: RenderContext, resolver: Resolver) => void|Promise<void>;
43
43
 
44
44
  type GlobalErrorHandlerFunction = (err: Error, ctx: RenderContext|null, response: ResponseBuilder) => ResolverResponse|Promise<ResolverResponse>;
45
45
  type RouteFallbackHandlerFunction = (ctx:RenderContext, resolver: Resolver) => ResolverResponse;
46
46
  type ApiFallbackHandlerFunction = (ctx:RenderContext, resolver: Resolver) => ResolverResponse;
47
47
 
48
- type HookEventType = "created"|"beforeRender"|"afterRender"|"fallback"|"completed";
48
+ type HookEventType = "created"|"beforeRender"|"afterRender"|"fallback";
49
49
  type HookListType = {
50
50
  priority: number,
51
- hookFn: HookCreatedFunction|HookBeforeRenderFunction|HookAfterRenderFunction|HookFallbackFunction|HookCompletedFunction,
51
+ hookFn: HookCreatedFunction|HookBeforeRenderFunction|HookAfterRenderFunction|HookFallbackFunction,
52
52
  }[];
53
53
 
54
54
  export const createContext = (
55
55
  event: APIGatewayProxyEvent,
56
56
  lambdaContext: Context,
57
+ apiPath: string|null = null
57
58
  ):RenderContext => {
58
59
  const host = event.headers.Host || event.headers.host || "";
59
60
  const path = event.path;
@@ -64,13 +65,14 @@ export const createContext = (
64
65
  const headers = event.headers;
65
66
  let post: Record<string, any> = {};
66
67
  const session = null;
68
+ const apiName = (method === "POST" && apiPath && path === apiPath && post.apiName) ? post.apiName : null;
67
69
  try {
68
70
  const decodedBody = event.isBase64Encoded ? ( event.body ? Buffer.from(event.body,"base64").toString() : "{}" ) : ( event.body || "{}" );
69
71
  try { post = JSON.parse(decodedBody) || {}; }
70
72
  catch(e){ post = querystring.parse(decodedBody) || {}; }
71
73
  }catch(e){}
72
74
  if(/^(((\d+\.)+\d+)|(([a-f\d]+:)+[a-f\d]+))$/.test(host)){ throw new Error("[404] Host cannot be an ip address: " + host); }
73
- return { host, path, pathParams, method, get, post, cookie, headers, session, lambdaContext };
75
+ return { host, path, pathParams, method, get, post, cookie, apiName, headers, session, lambdaContext };
74
76
  }
75
77
 
76
78
 
@@ -85,7 +87,6 @@ export default class Lambder {
85
87
  "beforeRender": { priority: number, hookFn: HookBeforeRenderFunction }[],
86
88
  "afterRender": { priority: number, hookFn: HookAfterRenderFunction }[],
87
89
  "fallback": { priority: number, hookFn: HookFallbackFunction }[],
88
- "completed": { priority: number, hookFn: HookCompletedFunction }[]
89
90
  };
90
91
  private globalErrorHandler: GlobalErrorHandlerFunction|null = null;
91
92
  private routeFallbackHandler: RouteFallbackHandlerFunction|null = null;
@@ -105,7 +106,6 @@ export default class Lambder {
105
106
  "beforeRender": [],
106
107
  "afterRender": [],
107
108
  "fallback": [],
108
- "completed": []
109
109
  };
110
110
  }
111
111
 
@@ -137,7 +137,7 @@ export default class Lambder {
137
137
  };
138
138
 
139
139
  private async handleNoMatchedAction(ctx: RenderContext, resolver: Resolver){
140
- for(const hook of this.hookList["fallback"]){ await hook.hookFn(ctx, resolver); }
140
+ for(const hook of this.hookList["fallback"]){ await hook.hookFn(ctx, resolver); }
141
141
 
142
142
  const isAPI = ctx.path === this.apiPath;
143
143
  if(isAPI && this.apiFallbackHandler){
@@ -170,6 +170,7 @@ export default class Lambder {
170
170
  }else if(condition?.constructor == RegExp){
171
171
  ctx.pathParams = ctx.path.match(condition);
172
172
  }
173
+
173
174
  return await actionFn(ctx, resolver);
174
175
  }
175
176
  });
@@ -198,29 +199,23 @@ export default class Lambder {
198
199
  });
199
200
  };
200
201
 
201
- addApi(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
202
+ addApi(apiName: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
202
203
  this.actionList.push({
203
204
  conditionFn: (ctx:RenderContext) => (
204
- ctx.method === "POST" && ctx.path === this.apiPath &&
205
- (
206
- (typeof condition === "string" && ctx.post?.api === condition) ||
207
- (typeof condition === "function" && condition(ctx)) ||
208
- (condition?.constructor == RegExp && condition.test(ctx.post?.api))
209
- )
205
+ (typeof apiName === "string" && ctx.apiName === apiName) ||
206
+ (typeof apiName === "function" && apiName(ctx)) ||
207
+ (apiName?.constructor == RegExp && apiName.test(ctx.apiName))
210
208
  ),
211
209
  actionFn: async (ctx:RenderContext, resolver: Resolver) => await actionFn(ctx, resolver),
212
210
  });
213
211
  };
214
212
 
215
- addSessionApi(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
213
+ addSessionApi(apiName: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
216
214
  this.actionList.push({
217
215
  conditionFn: (ctx:RenderContext) => (
218
- ctx.method === "POST" && ctx.path === this.apiPath &&
219
- (
220
- (typeof condition === "string" && ctx.post?.api === condition) ||
221
- (typeof condition === "function" && condition(ctx)) ||
222
- (condition?.constructor == RegExp && condition.test(ctx.post?.api))
223
- )
216
+ (typeof apiName === "string" && ctx.apiName === apiName) ||
217
+ (typeof apiName === "function" && apiName(ctx)) ||
218
+ (apiName?.constructor == RegExp && apiName.test(ctx.apiName))
224
219
  ),
225
220
  actionFn: async (ctx:RenderContext, resolver: Resolver) => {
226
221
  const isSessionValid = this.validateSession(ctx.session);
@@ -230,15 +225,13 @@ export default class Lambder {
230
225
  });
231
226
  };
232
227
 
233
-
234
228
  async addHook(hookEvent: 'created', hookFn: HookCreatedFunction, priority?: number): Promise<void>;
235
229
  async addHook(hookEvent: 'beforeRender', hookFn: HookBeforeRenderFunction, priority?: number): Promise<void>;
236
230
  async addHook(hookEvent: 'afterRender', hookFn: HookAfterRenderFunction, priority?: number): Promise<void>;
237
231
  async addHook(hookEvent: 'fallback', hookFn: HookFallbackFunction, priority?: number): Promise<void>;
238
- async addHook(hookEvent: 'completed', hookFn: HookCompletedFunction, priority?: number): Promise<void>;
239
232
  async addHook(
240
233
  hookEvent:HookEventType,
241
- hookFn: HookCreatedFunction & HookBeforeRenderFunction & HookAfterRenderFunction & HookFallbackFunction & HookCompletedFunction,
234
+ hookFn: HookCreatedFunction & HookBeforeRenderFunction & HookAfterRenderFunction & HookFallbackFunction,
242
235
  priority = 0
243
236
  ): Promise<void> {
244
237
  if(hookEvent === "created"){
@@ -286,9 +279,17 @@ export default class Lambder {
286
279
 
287
280
  const firstMatchedAction = this.actionList.find(action => action.conditionFn(ctx));
288
281
  if(firstMatchedAction){
289
- for(const hook of this.hookList["beforeRender"]){ ctx = await hook.hookFn(ctx, resolver); }
282
+ for(const hook of this.hookList["beforeRender"]){
283
+ const hookCtx = await hook.hookFn(ctx, resolver);
284
+ if(hookCtx instanceof Error){ throw hookCtx; }
285
+ ctx = hookCtx;
286
+ }
290
287
  let response = await firstMatchedAction.actionFn(ctx, resolver);
291
- for(const hook of this.hookList["afterRender"]){ response = await hook.hookFn(ctx, resolver, response); }
288
+ for(const hook of this.hookList["afterRender"]){
289
+ const hookResponse = await hook.hookFn(ctx, resolver, response);
290
+ if(hookResponse instanceof Error){ throw hookResponse; }
291
+ response = hookResponse;
292
+ }
292
293
  resolve(response);
293
294
  }else{
294
295
  return this.handleNoMatchedAction(ctx, resolver);