lambder 1.0.39 → 1.0.41

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
@@ -1,6 +1,6 @@
1
1
  import type { APIGatewayProxyEvent, APIGatewayProxyEventHeaders, Context } from "aws-lambda";
2
2
  import Resolver from "./Resolver.js";
3
- import ResolverLight, { ResolverResponse } from "./ResolverLight.js";
3
+ import ResponseBuilder, { ResolverResponse } from "./ResponseBuilder.js";
4
4
  type DDBSession = {
5
5
  userId: string;
6
6
  userIdHash: string;
@@ -29,16 +29,16 @@ type RenderContext = {
29
29
  session: DDBSession;
30
30
  lambdaContext: Context;
31
31
  };
32
- type ConditionFunction = (renderContext: RenderContext) => boolean | Promise<boolean>;
33
- type ActionFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse | Promise<ResolverResponse>;
32
+ type ConditionFunction = (ctx: RenderContext) => boolean | Promise<boolean>;
33
+ type ActionFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse | Promise<ResolverResponse>;
34
34
  type HookCreatedFunction = (lambderInstance: Lambder) => Promise<void>;
35
- type HookBeforeRenderFunction = (renderContext: RenderContext, resolver: Resolver) => RenderContext | Promise<RenderContext>;
36
- type HookAfterRenderFunction = (renderContext: RenderContext, resolver: Resolver, renderResult: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
37
- type HookFallbackFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse | Promise<ResolverResponse>;
35
+ type HookBeforeRenderFunction = (ctx: RenderContext, resolver: Resolver) => RenderContext | Promise<RenderContext>;
36
+ type HookAfterRenderFunction = (ctx: RenderContext, resolver: Resolver, renderResult: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
37
+ type HookFallbackFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse | Promise<ResolverResponse>;
38
38
  type HookCompletedFunction = (renderResult: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
39
- type GlobalErrorHandlerFunction = (err: Error, renderContext: RenderContext | null, resolver: ResolverLight) => ResolverResponse | Promise<ResolverResponse>;
40
- type RouteFallbackHandlerFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse;
41
- type ApiFallbackHandlerFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse;
39
+ type GlobalErrorHandlerFunction = (err: Error, ctx: RenderContext | null, response: ResponseBuilder) => ResolverResponse | Promise<ResolverResponse>;
40
+ type RouteFallbackHandlerFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse;
41
+ type ApiFallbackHandlerFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse;
42
42
  export declare const createContext: (event: APIGatewayProxyEvent, lambdaContext: Context) => RenderContext;
43
43
  export default class Lambder {
44
44
  private apiPath;
@@ -71,6 +71,8 @@ export default class Lambder {
71
71
  addHook(hookEvent: 'afterRender', hookFn: HookAfterRenderFunction, priority?: number): Promise<void>;
72
72
  addHook(hookEvent: 'fallback', hookFn: HookFallbackFunction, priority?: number): Promise<void>;
73
73
  addHook(hookEvent: 'completed', hookFn: HookCompletedFunction, priority?: number): Promise<void>;
74
+ getResponseBuilder(): ResponseBuilder;
75
+ private getResolver;
74
76
  render(event: APIGatewayProxyEvent, lambdaContext: Context): Promise<ResolverResponse>;
75
77
  }
76
78
  export {};
package/dist/Lambder.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import querystring from "querystring";
2
2
  import cookieParser from "cookie";
3
3
  import Resolver from "./Resolver.js";
4
- import ResolverLight from "./ResolverLight.js";
4
+ import ResponseBuilder from "./ResponseBuilder.js";
5
5
  export const createContext = (event, lambdaContext) => {
6
6
  const host = event.headers.Host || event.headers.host || "";
7
7
  const url = event.path;
@@ -71,20 +71,20 @@ export default class Lambder {
71
71
  return false;
72
72
  }
73
73
  ;
74
- async handleNoMatchedAction(renderContext, resolver) {
74
+ async handleNoMatchedAction(ctx, resolver) {
75
75
  for (const hook of this._hookList["fallback"]) {
76
- await hook.hookFn(renderContext, resolver);
76
+ await hook.hookFn(ctx, resolver);
77
77
  }
78
- if (renderContext.url === this.apiPath) {
78
+ if (ctx.url === this.apiPath) {
79
79
  if (this.apiFallbackHandler) {
80
- resolver.resolve(await this.apiFallbackHandler(renderContext, resolver));
80
+ resolver.resolve(await this.apiFallbackHandler(ctx, resolver));
81
81
  }
82
82
  else {
83
83
  resolver.resolve({ statusCode: 204, body: "API handler not set.", });
84
84
  }
85
85
  }
86
86
  else if (this.routeFallbackHandler) {
87
- resolver.resolve(await this.routeFallbackHandler(renderContext, resolver));
87
+ resolver.resolve(await this.routeFallbackHandler(ctx, resolver));
88
88
  }
89
89
  else {
90
90
  resolver.resolve({ statusCode: 204, body: "Handler not set.", });
@@ -95,45 +95,45 @@ export default class Lambder {
95
95
  }
96
96
  addRoute(condition, actionFn) {
97
97
  this._actionList.push({
98
- conditionFn: async (renderContext) => (renderContext.method === "GET" &&
99
- ((typeof condition === "string" && renderContext.url === condition) ||
100
- (typeof condition === "function" && (await condition(renderContext))) ||
101
- (condition?.constructor == RegExp && condition.test(renderContext.url)))),
102
- actionFn: async (renderContext, resolver) => await actionFn(renderContext, resolver)
98
+ conditionFn: async (ctx) => (ctx.method === "GET" &&
99
+ ((typeof condition === "string" && ctx.url === condition) ||
100
+ (typeof condition === "function" && (await condition(ctx))) ||
101
+ (condition?.constructor == RegExp && condition.test(ctx.url)))),
102
+ actionFn: async (ctx, resolver) => await actionFn(ctx, resolver)
103
103
  });
104
104
  }
105
105
  ;
106
106
  addSessionRoute(condition, actionFn) {
107
107
  this._actionList.push({
108
- conditionFn: async (renderContext) => (renderContext.method === "GET" &&
109
- ((typeof condition === "string" && renderContext.url === condition) ||
110
- (typeof condition === "function" && (await condition(renderContext))) ||
111
- (condition?.constructor == RegExp && condition.test(renderContext.url)))),
112
- actionFn: async (renderContext, resolver) => await actionFn(renderContext, resolver)
108
+ conditionFn: async (ctx) => (ctx.method === "GET" && !!ctx.session &&
109
+ ((typeof condition === "string" && ctx.url === condition) ||
110
+ (typeof condition === "function" && (await condition(ctx))) ||
111
+ (condition?.constructor == RegExp && condition.test(ctx.url)))),
112
+ actionFn: async (ctx, resolver) => await actionFn(ctx, resolver)
113
113
  });
114
114
  }
115
115
  ;
116
116
  addApi(condition, actionFn) {
117
117
  this._actionList.push({
118
- conditionFn: async (renderContext) => (renderContext.method === "POST" && renderContext.url === this.apiPath &&
119
- ((typeof condition === "string" && renderContext.post?.api === condition) ||
120
- (typeof condition === "function" && (await condition(renderContext))) ||
121
- (condition?.constructor == RegExp && condition.test(renderContext.post?.api)))),
122
- actionFn: async (renderContext, resolver) => await actionFn(renderContext, resolver)
118
+ conditionFn: async (ctx) => (ctx.method === "POST" && ctx.url === this.apiPath &&
119
+ ((typeof condition === "string" && ctx.post?.api === condition) ||
120
+ (typeof condition === "function" && (await condition(ctx))) ||
121
+ (condition?.constructor == RegExp && condition.test(ctx.post?.api)))),
122
+ actionFn: async (ctx, resolver) => await actionFn(ctx, resolver)
123
123
  });
124
124
  }
125
125
  ;
126
126
  addSessionApi(condition, actionFn) {
127
127
  this._actionList.push({
128
- conditionFn: async (renderContext) => (renderContext.method === "POST" && renderContext.url === this.apiPath &&
129
- ((typeof condition === "string" && renderContext.post?.api === condition) ||
130
- (typeof condition === "function" && (await condition(renderContext))) ||
131
- (condition?.constructor == RegExp && condition.test(renderContext.post?.api)))),
132
- actionFn: async (renderContext, resolver) => {
133
- const isSessionValid = this.validateSession(renderContext.session);
128
+ conditionFn: async (ctx) => (ctx.method === "POST" && ctx.url === this.apiPath && !!ctx.session &&
129
+ ((typeof condition === "string" && ctx.post?.api === condition) ||
130
+ (typeof condition === "function" && (await condition(ctx))) ||
131
+ (condition?.constructor == RegExp && condition.test(ctx.post?.api)))),
132
+ actionFn: async (ctx, resolver) => {
133
+ const isSessionValid = this.validateSession(ctx.session);
134
134
  if (!isSessionValid)
135
135
  throw new Error("Session not found");
136
- return await actionFn(renderContext, resolver);
136
+ return await actionFn(ctx, resolver);
137
137
  }
138
138
  });
139
139
  }
@@ -147,38 +147,50 @@ export default class Lambder {
147
147
  this._hookList[hookEvent].sort((a, b) => a.priority - b.priority);
148
148
  }
149
149
  }
150
+ getResponseBuilder() {
151
+ return new ResponseBuilder({
152
+ isCorsEnabled: this.isCorsEnabled,
153
+ publicPath: this.publicPath,
154
+ apiVersion: this.apiVersion,
155
+ });
156
+ }
157
+ ;
158
+ getResolver(resolve, reject) {
159
+ return new Resolver({
160
+ isCorsEnabled: this.isCorsEnabled,
161
+ publicPath: this.publicPath,
162
+ apiVersion: this.apiVersion,
163
+ resolve, reject
164
+ });
165
+ }
166
+ ;
150
167
  async render(event, lambdaContext) {
151
168
  let eventRenderContext = null;
152
169
  try {
153
- let renderContext = createContext(event, lambdaContext);
154
- eventRenderContext = renderContext;
170
+ let ctx = createContext(event, lambdaContext);
171
+ eventRenderContext = ctx;
155
172
  return await new Promise(async (resolve, reject) => {
156
- const resolver = new Resolver({
157
- isCorsEnabled: this.isCorsEnabled,
158
- publicPath: this.publicPath,
159
- apiVersion: this.apiVersion,
160
- resolve, reject
161
- });
162
- if (renderContext.method === "OPTIONS")
173
+ const resolver = this.getResolver(resolve, reject);
174
+ if (ctx.method === "OPTIONS")
163
175
  return resolver.cors();
164
176
  const firstMatchedAction = await (async () => {
165
177
  for (const action of this._actionList) {
166
- if (await action.conditionFn(renderContext))
178
+ if (await action.conditionFn(ctx))
167
179
  return action;
168
180
  }
169
181
  })();
170
182
  if (firstMatchedAction) {
171
183
  for (const hook of this._hookList["beforeRender"]) {
172
- renderContext = await hook.hookFn(renderContext, resolver);
184
+ ctx = await hook.hookFn(ctx, resolver);
173
185
  }
174
- let renderResult = await firstMatchedAction.actionFn(renderContext, resolver);
186
+ let renderResult = await firstMatchedAction.actionFn(ctx, resolver);
175
187
  for (const hook of this._hookList["afterRender"]) {
176
- renderResult = await hook.hookFn(renderContext, resolver, renderResult);
188
+ renderResult = await hook.hookFn(ctx, resolver, renderResult);
177
189
  }
178
190
  resolve(renderResult);
179
191
  }
180
192
  else {
181
- return this.handleNoMatchedAction(renderContext, resolver);
193
+ return this.handleNoMatchedAction(ctx, resolver);
182
194
  }
183
195
  }).then(async (renderResult) => {
184
196
  for (const hook of this._hookList["completed"]) {
@@ -188,14 +200,10 @@ export default class Lambder {
188
200
  });
189
201
  }
190
202
  catch (err) {
191
- const resolverLight = new ResolverLight({
192
- isCorsEnabled: this.isCorsEnabled,
193
- publicPath: this.publicPath,
194
- apiVersion: this.apiVersion,
195
- });
203
+ const responseBuilder = this.getResponseBuilder();
196
204
  const wrappedError = err instanceof Error ? err : new Error("Error: " + String(err));
197
205
  if (this.globalErrorHandler) {
198
- return this.globalErrorHandler(wrappedError, eventRenderContext, resolverLight);
206
+ return this.globalErrorHandler(wrappedError, eventRenderContext, responseBuilder);
199
207
  }
200
208
  return { statusCode: 500, body: "Internal Server Error.", };
201
209
  }
@@ -1,18 +1,18 @@
1
- import ResolverLight, { ResolverResponse } from "./ResolverLight.js";
1
+ import ResponseBuilder, { ResolverResponse } from "./ResponseBuilder.js";
2
2
  type MethodType<T, M extends keyof T> = T[M] extends (...args: any[]) => any ? T[M] : never;
3
3
  interface DieResolverMethods {
4
- raw: MethodType<ResolverLight, 'raw'>;
5
- json: MethodType<ResolverLight, 'json'>;
6
- xml: MethodType<ResolverLight, 'xml'>;
7
- html: MethodType<ResolverLight, 'html'>;
8
- status301: MethodType<ResolverLight, 'status301'>;
9
- status404: MethodType<ResolverLight, 'status404'>;
10
- cors: MethodType<ResolverLight, 'cors'>;
11
- fileBase64: MethodType<ResolverLight, 'fileBase64'>;
12
- file: MethodType<ResolverLight, 'file'>;
13
- api: MethodType<ResolverLight, 'api'>;
4
+ raw: MethodType<ResponseBuilder, 'raw'>;
5
+ json: MethodType<ResponseBuilder, 'json'>;
6
+ xml: MethodType<ResponseBuilder, 'xml'>;
7
+ html: MethodType<ResponseBuilder, 'html'>;
8
+ status301: MethodType<ResponseBuilder, 'status301'>;
9
+ status404: MethodType<ResponseBuilder, 'status404'>;
10
+ cors: MethodType<ResponseBuilder, 'cors'>;
11
+ fileBase64: MethodType<ResponseBuilder, 'fileBase64'>;
12
+ file: MethodType<ResponseBuilder, 'file'>;
13
+ api: MethodType<ResponseBuilder, 'api'>;
14
14
  }
15
- export default class Resolver extends ResolverLight {
15
+ export default class Resolver extends ResponseBuilder {
16
16
  resolve: (renderResult: ResolverResponse) => void;
17
17
  reject: (err: Error) => void;
18
18
  die: DieResolverMethods;
package/dist/Resolver.js CHANGED
@@ -1,5 +1,5 @@
1
- import ResolverLight from "./ResolverLight.js";
2
- export default class Resolver extends ResolverLight {
1
+ import ResponseBuilder from "./ResponseBuilder.js";
2
+ export default class Resolver extends ResponseBuilder {
3
3
  resolve;
4
4
  reject;
5
5
  die;
@@ -7,7 +7,6 @@ export default class Resolver extends ResolverLight {
7
7
  super({ isCorsEnabled, publicPath, apiVersion });
8
8
  this.resolve = resolve;
9
9
  this.reject = reject;
10
- // Bind ResolverLight methods to `this` for `die` and automatically resolve
11
10
  this.die = {
12
11
  raw: this.autoResolve(this.raw),
13
12
  json: this.autoResolve(this.json),
@@ -7,7 +7,7 @@ export type ResolverResponse = {
7
7
  isBase64Encoded?: boolean;
8
8
  [key: string]: any;
9
9
  };
10
- export default class ResolverLight {
10
+ export default class ResponseBuilder {
11
11
  private isCorsEnabled;
12
12
  private publicPath;
13
13
  private apiVersion;
@@ -8,7 +8,7 @@ const CORS_HEADERS = convertToMultiHeader({
8
8
  "Access-Control-Allow-Origin": "*",
9
9
  "Access-Control-Allow-Methods": "OPTIONS,POST",
10
10
  });
11
- export default class ResolverLight {
11
+ export default class ResponseBuilder {
12
12
  isCorsEnabled;
13
13
  publicPath;
14
14
  apiVersion;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import Lambder from './Lambder.js';
2
2
  export default Lambder;
3
3
  export { default as LambderCaller } from "./LambderCaller.js";
4
- export { default as ResolverLight } from "./ResolverLight.js";
4
+ export { default as ResponseBuilder } from "./ResponseBuilder.js";
5
5
  export { default as Resolver } from "./Resolver.js";
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import Lambder from './Lambder.js';
2
2
  export default Lambder;
3
3
  export { default as LambderCaller } from "./LambderCaller.js";
4
- export { default as ResolverLight } from "./ResolverLight.js";
4
+ export { default as ResponseBuilder } from "./ResponseBuilder.js";
5
5
  export { default as Resolver } from "./Resolver.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lambder",
3
- "version": "1.0.39",
3
+ "version": "1.0.41",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/Lambder.ts CHANGED
@@ -3,7 +3,7 @@ import cookieParser from "cookie";
3
3
 
4
4
  import type { APIGatewayProxyEvent, APIGatewayProxyEventHeaders, Context } from "aws-lambda";
5
5
  import Resolver from "./Resolver.js";
6
- import ResolverLight, { ResolverResponse } from "./ResolverLight.js";
6
+ import ResponseBuilder, { ResolverResponse } from "./ResponseBuilder.js";
7
7
 
8
8
  type DDBSession = {
9
9
  userId: string,
@@ -27,19 +27,19 @@ type RenderContext = {
27
27
  lambdaContext: Context;
28
28
  };
29
29
 
30
- type ConditionFunction = (renderContext: RenderContext) => boolean|Promise<boolean>;
31
- type ActionFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse|Promise<ResolverResponse>;
30
+ type ConditionFunction = (ctx: RenderContext) => boolean|Promise<boolean>;
31
+ type ActionFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse|Promise<ResolverResponse>;
32
32
  type ActionType = { conditionFn: ConditionFunction, actionFn: ActionFunction };
33
33
 
34
34
  type HookCreatedFunction = (lambderInstance: Lambder) => Promise<void>;
35
- type HookBeforeRenderFunction = (renderContext: RenderContext, resolver: Resolver) => RenderContext|Promise<RenderContext>;
36
- type HookAfterRenderFunction = (renderContext: RenderContext, resolver: Resolver, renderResult: ResolverResponse) => ResolverResponse|Promise<ResolverResponse>;
37
- type HookFallbackFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse|Promise<ResolverResponse>;
35
+ type HookBeforeRenderFunction = (ctx: RenderContext, resolver: Resolver) => RenderContext|Promise<RenderContext>;
36
+ type HookAfterRenderFunction = (ctx: RenderContext, resolver: Resolver, renderResult: ResolverResponse) => ResolverResponse|Promise<ResolverResponse>;
37
+ type HookFallbackFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse|Promise<ResolverResponse>;
38
38
  type HookCompletedFunction = (renderResult: ResolverResponse) => ResolverResponse|Promise<ResolverResponse>;
39
39
 
40
- type GlobalErrorHandlerFunction = (err: Error, renderContext: RenderContext|null, resolver: ResolverLight) => ResolverResponse|Promise<ResolverResponse>;
41
- type RouteFallbackHandlerFunction = (renderContext:RenderContext, resolver: Resolver) => ResolverResponse;
42
- type ApiFallbackHandlerFunction = (renderContext:RenderContext, resolver: Resolver) => ResolverResponse;
40
+ type GlobalErrorHandlerFunction = (err: Error, ctx: RenderContext|null, response: ResponseBuilder) => ResolverResponse|Promise<ResolverResponse>;
41
+ type RouteFallbackHandlerFunction = (ctx:RenderContext, resolver: Resolver) => ResolverResponse;
42
+ type ApiFallbackHandlerFunction = (ctx:RenderContext, resolver: Resolver) => ResolverResponse;
43
43
 
44
44
  type HookEventType = "created"|"beforeRender"|"afterRender"|"fallback"|"completed";
45
45
  type HookListType = {
@@ -123,18 +123,18 @@ export default class Lambder {
123
123
  return false;
124
124
  };
125
125
 
126
- private async handleNoMatchedAction(renderContext: RenderContext, resolver: Resolver){
126
+ private async handleNoMatchedAction(ctx: RenderContext, resolver: Resolver){
127
127
  for(const hook of this._hookList["fallback"]){
128
- await hook.hookFn(renderContext, resolver);
128
+ await hook.hookFn(ctx, resolver);
129
129
  }
130
- if(renderContext.url === this.apiPath){
130
+ if(ctx.url === this.apiPath){
131
131
  if(this.apiFallbackHandler){
132
- resolver.resolve(await this.apiFallbackHandler(renderContext, resolver));
132
+ resolver.resolve(await this.apiFallbackHandler(ctx, resolver));
133
133
  }else{
134
134
  resolver.resolve({ statusCode: 204, body: "API handler not set.", })
135
135
  }
136
136
  }else if(this.routeFallbackHandler){
137
- resolver.resolve(await this.routeFallbackHandler(renderContext, resolver));
137
+ resolver.resolve(await this.routeFallbackHandler(ctx, resolver));
138
138
  }else{
139
139
  resolver.resolve({ statusCode: 204, body: "Handler not set.", })
140
140
  }
@@ -145,60 +145,60 @@ export default class Lambder {
145
145
  }
146
146
  addRoute(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
147
147
  this._actionList.push({
148
- conditionFn: async (renderContext:RenderContext) => (
149
- renderContext.method === "GET" &&
148
+ conditionFn: async (ctx:RenderContext) => (
149
+ ctx.method === "GET" &&
150
150
  (
151
- (typeof condition === "string" && renderContext.url === condition) ||
152
- (typeof condition === "function" && (await condition(renderContext))) ||
153
- (condition?.constructor == RegExp && condition.test(renderContext.url))
151
+ (typeof condition === "string" && ctx.url === condition) ||
152
+ (typeof condition === "function" && (await condition(ctx))) ||
153
+ (condition?.constructor == RegExp && condition.test(ctx.url))
154
154
  )
155
155
  ),
156
- actionFn: async (renderContext:RenderContext, resolver: Resolver) => await actionFn(renderContext, resolver)
156
+ actionFn: async (ctx:RenderContext, resolver: Resolver) => await actionFn(ctx, resolver)
157
157
  });
158
158
  };
159
159
 
160
160
  addSessionRoute(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
161
161
  this._actionList.push({
162
- conditionFn: async (renderContext:RenderContext) => (
163
- renderContext.method === "GET" &&
162
+ conditionFn: async (ctx:RenderContext) => (
163
+ ctx.method === "GET" && !!ctx.session &&
164
164
  (
165
- (typeof condition === "string" && renderContext.url === condition) ||
166
- (typeof condition === "function" && (await condition(renderContext))) ||
167
- (condition?.constructor == RegExp && condition.test(renderContext.url))
165
+ (typeof condition === "string" && ctx.url === condition) ||
166
+ (typeof condition === "function" && (await condition(ctx))) ||
167
+ (condition?.constructor == RegExp && condition.test(ctx.url))
168
168
  )
169
169
  ),
170
- actionFn: async (renderContext:RenderContext, resolver: Resolver) => await actionFn(renderContext, resolver)
170
+ actionFn: async (ctx:RenderContext, resolver: Resolver) => await actionFn(ctx, resolver)
171
171
  });
172
172
  };
173
173
 
174
174
  addApi(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
175
175
  this._actionList.push({
176
- conditionFn: async (renderContext:RenderContext) => (
177
- renderContext.method === "POST" && renderContext.url === this.apiPath &&
176
+ conditionFn: async (ctx:RenderContext) => (
177
+ ctx.method === "POST" && ctx.url === this.apiPath &&
178
178
  (
179
- (typeof condition === "string" && renderContext.post?.api === condition) ||
180
- (typeof condition === "function" && (await condition(renderContext))) ||
181
- (condition?.constructor == RegExp && condition.test(renderContext.post?.api))
179
+ (typeof condition === "string" && ctx.post?.api === condition) ||
180
+ (typeof condition === "function" && (await condition(ctx))) ||
181
+ (condition?.constructor == RegExp && condition.test(ctx.post?.api))
182
182
  )
183
183
  ),
184
- actionFn: async (renderContext:RenderContext, resolver: Resolver) => await actionFn(renderContext, resolver)
184
+ actionFn: async (ctx:RenderContext, resolver: Resolver) => await actionFn(ctx, resolver)
185
185
  });
186
186
  };
187
187
 
188
188
  addSessionApi(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
189
189
  this._actionList.push({
190
- conditionFn: async (renderContext:RenderContext) => (
191
- renderContext.method === "POST" && renderContext.url === this.apiPath &&
190
+ conditionFn: async (ctx:RenderContext) => (
191
+ ctx.method === "POST" && ctx.url === this.apiPath && !!ctx.session &&
192
192
  (
193
- (typeof condition === "string" && renderContext.post?.api === condition) ||
194
- (typeof condition === "function" && (await condition(renderContext))) ||
195
- (condition?.constructor == RegExp && condition.test(renderContext.post?.api))
193
+ (typeof condition === "string" && ctx.post?.api === condition) ||
194
+ (typeof condition === "function" && (await condition(ctx))) ||
195
+ (condition?.constructor == RegExp && condition.test(ctx.post?.api))
196
196
  )
197
197
  ),
198
- actionFn: async (renderContext:RenderContext, resolver: Resolver) => {
199
- const isSessionValid = this.validateSession(renderContext.session);
198
+ actionFn: async (ctx:RenderContext, resolver: Resolver) => {
199
+ const isSessionValid = this.validateSession(ctx.session);
200
200
  if(!isSessionValid) throw new Error("Session not found");
201
- return await actionFn(renderContext, resolver);
201
+ return await actionFn(ctx, resolver);
202
202
  }
203
203
  });
204
204
  };
@@ -222,45 +222,57 @@ export default class Lambder {
222
222
  }
223
223
  }
224
224
 
225
+ public getResponseBuilder(){
226
+ return new ResponseBuilder({
227
+ isCorsEnabled: this.isCorsEnabled,
228
+ publicPath: this.publicPath,
229
+ apiVersion: this.apiVersion,
230
+ });
231
+ };
232
+
233
+ private getResolver(resolve: (renderResult: ResolverResponse) => void, reject: (err: Error) => void){
234
+ return new Resolver({
235
+ isCorsEnabled: this.isCorsEnabled,
236
+ publicPath: this.publicPath,
237
+ apiVersion: this.apiVersion,
238
+ resolve, reject
239
+ });
240
+ };
225
241
 
226
242
  async render(
227
243
  event: APIGatewayProxyEvent,
228
244
  lambdaContext: Context
229
245
  ): Promise<ResolverResponse>{
230
246
  let eventRenderContext:RenderContext|null = null;
247
+
231
248
  try {
232
- let renderContext = createContext(event, lambdaContext);
233
- eventRenderContext = renderContext;
249
+ let ctx = createContext(event, lambdaContext);
250
+ eventRenderContext = ctx;
234
251
 
235
252
  return await new Promise(async (
236
253
  resolve:(renderResult: ResolverResponse)=>void,
237
254
  reject:(err: Error)=>void
238
255
  )=> {
239
- const resolver = new Resolver({
240
- isCorsEnabled: this.isCorsEnabled,
241
- publicPath: this.publicPath,
242
- apiVersion: this.apiVersion,
243
- resolve, reject
244
- });
245
- if(renderContext.method === "OPTIONS") return resolver.cors();
256
+ const resolver = this.getResolver(resolve, reject);
257
+ if(ctx.method === "OPTIONS") return resolver.cors();
246
258
 
247
259
  const firstMatchedAction = await (async () => {
248
260
  for(const action of this._actionList){
249
- if(await action.conditionFn(renderContext)) return action;
261
+ if(await action.conditionFn(ctx)) return action;
250
262
  }
251
263
  })();
252
264
 
253
265
  if(firstMatchedAction){
254
266
  for(const hook of this._hookList["beforeRender"]){
255
- renderContext = await hook.hookFn(renderContext, resolver);
267
+ ctx = await hook.hookFn(ctx, resolver);
256
268
  }
257
- let renderResult = await firstMatchedAction.actionFn(renderContext, resolver);
269
+ let renderResult = await firstMatchedAction.actionFn(ctx, resolver);
258
270
  for(const hook of this._hookList["afterRender"]){
259
- renderResult = await hook.hookFn(renderContext, resolver, renderResult);
271
+ renderResult = await hook.hookFn(ctx, resolver, renderResult);
260
272
  }
261
273
  resolve(renderResult);
262
274
  }else{
263
- return this.handleNoMatchedAction(renderContext, resolver);
275
+ return this.handleNoMatchedAction(ctx, resolver);
264
276
  }
265
277
  }).then(async (renderResult: ResolverResponse):Promise<ResolverResponse> => {
266
278
  for(const hook of this._hookList["completed"]){
@@ -269,14 +281,10 @@ export default class Lambder {
269
281
  return renderResult;
270
282
  });
271
283
  }catch(err){
272
- const resolverLight = new ResolverLight({
273
- isCorsEnabled: this.isCorsEnabled,
274
- publicPath: this.publicPath,
275
- apiVersion: this.apiVersion,
276
- })
284
+ const responseBuilder = this.getResponseBuilder();
277
285
  const wrappedError = err instanceof Error ? err : new Error("Error: " + String(err));
278
286
  if(this.globalErrorHandler){
279
- return this.globalErrorHandler(wrappedError, eventRenderContext, resolverLight);
287
+ return this.globalErrorHandler(wrappedError, eventRenderContext, responseBuilder);
280
288
  }
281
289
  return { statusCode: 500, body: "Internal Server Error.", }
282
290
 
package/src/Resolver.ts CHANGED
@@ -1,21 +1,21 @@
1
- import ResolverLight, { ResolverResponse } from "./ResolverLight.js";
1
+ import ResponseBuilder, { ResolverResponse } from "./ResponseBuilder.js";
2
2
 
3
3
  type MethodType<T, M extends keyof T> = T[M] extends (...args: any[]) => any ? T[M] : never;
4
4
 
5
5
  interface DieResolverMethods {
6
- raw: MethodType<ResolverLight, 'raw'>;
7
- json: MethodType<ResolverLight, 'json'>;
8
- xml: MethodType<ResolverLight, 'xml'>;
9
- html: MethodType<ResolverLight, 'html'>;
10
- status301: MethodType<ResolverLight, 'status301'>;
11
- status404: MethodType<ResolverLight, 'status404'>;
12
- cors: MethodType<ResolverLight, 'cors'>;
13
- fileBase64: MethodType<ResolverLight, 'fileBase64'>;
14
- file: MethodType<ResolverLight, 'file'>;
15
- api: MethodType<ResolverLight, 'api'>;
6
+ raw: MethodType<ResponseBuilder, 'raw'>;
7
+ json: MethodType<ResponseBuilder, 'json'>;
8
+ xml: MethodType<ResponseBuilder, 'xml'>;
9
+ html: MethodType<ResponseBuilder, 'html'>;
10
+ status301: MethodType<ResponseBuilder, 'status301'>;
11
+ status404: MethodType<ResponseBuilder, 'status404'>;
12
+ cors: MethodType<ResponseBuilder, 'cors'>;
13
+ fileBase64: MethodType<ResponseBuilder, 'fileBase64'>;
14
+ file: MethodType<ResponseBuilder, 'file'>;
15
+ api: MethodType<ResponseBuilder, 'api'>;
16
16
  }
17
17
 
18
- export default class Resolver extends ResolverLight {
18
+ export default class Resolver extends ResponseBuilder {
19
19
  public resolve: (renderResult: ResolverResponse) => void;
20
20
  public reject: (err: Error) => void;
21
21
  public die: DieResolverMethods;
@@ -34,7 +34,6 @@ export default class Resolver extends ResolverLight {
34
34
  this.resolve = resolve;
35
35
  this.reject = reject;
36
36
 
37
- // Bind ResolverLight methods to `this` for `die` and automatically resolve
38
37
  this.die = {
39
38
  raw: this.autoResolve(this.raw),
40
39
  json: this.autoResolve(this.json),
@@ -23,7 +23,7 @@ export type ResolverResponse = {
23
23
  };
24
24
 
25
25
 
26
- export default class ResolverLight {
26
+ export default class ResponseBuilder {
27
27
  private isCorsEnabled: boolean;
28
28
  private publicPath: string;
29
29
  private apiVersion: string|null;
@@ -187,38 +187,4 @@ export default class ResolverLight {
187
187
  }, headers);
188
188
  };
189
189
 
190
- };
191
-
192
-
193
-
194
- interface IResolverMethods {
195
- raw(param: {
196
- statusCode: number,
197
- isBase64Encoded?: boolean,
198
- body: null | string,
199
- multiValueHeaders: { [key: string]: string[] },
200
- }): ResolverResponse;
201
- json(data: { [key: string]: any }, headers?: { [key: string]: string | string[] }): ResolverResponse;
202
- xml(data: string): ResolverResponse;
203
- html(data: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
204
- status301(url: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
205
- status404(data: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
206
- cors(): ResolverResponse;
207
- fileBase64(fileBase64: string, mimeType: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
208
- file(filePath: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
209
- api({
210
- payload,
211
- versionExpired, sessionExpired, notAuthorized,
212
- message, errorMessage,
213
- ...other
214
- }: {
215
- payload?: any;
216
- versionExpired?: boolean;
217
- sessionExpired?: boolean;
218
- notAuthorized?: boolean;
219
- message?: any;
220
- errorMessage?: any;
221
- },
222
- headers?: { [key:string]: string|string[] }
223
- ): ResolverResponse;
224
- }
190
+ };
package/src/index.ts CHANGED
@@ -2,5 +2,5 @@ import Lambder from './Lambder.js';
2
2
 
3
3
  export default Lambder;
4
4
  export { default as LambderCaller } from "./LambderCaller.js";
5
- export { default as ResolverLight } from "./ResolverLight.js";
5
+ export { default as ResponseBuilder } from "./ResponseBuilder.js";
6
6
  export { default as Resolver } from "./Resolver.js";