lambder 1.0.14 → 1.0.16

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "editor.codeActionsOnSave": {
3
- "source.fixAll.eslint": true
3
+ "source.fixAll.eslint": "explicit"
4
4
  },
5
5
  "eslint.validate": [
6
6
  "javascript",
@@ -16,6 +16,9 @@
16
16
  "**/dist/": true,
17
17
  "**/package-lock.json": true,
18
18
  "**/.git/": true,
19
- },
19
+ },
20
+ "cSpell.words": [
21
+ "lambder"
22
+ ],
20
23
  }
21
24
 
@@ -52,7 +52,7 @@ export default class Resolver {
52
52
  private apiVersion;
53
53
  resolve: Function;
54
54
  reject: Function;
55
- die: Partial<IResolverMethods>;
55
+ die: IResolverMethods;
56
56
  constructor({ isCorsEnabled, publicPath, apiVersion, resolve, reject }: {
57
57
  isCorsEnabled: boolean;
58
58
  publicPath: string;
package/dist/Resolver.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import fs from "fs";
2
- import * as pathLibrary from "path";
2
+ import * as path from "path";
3
3
  import mimeTypeResolver from "mime-types";
4
4
  const convertToMultiHeader = (headers) => Object.fromEntries(Object.entries(headers || {}).map(([k, v]) => [k, Array.isArray(v) ? v : [v]]));
5
5
  const CORS_HEADERS = convertToMultiHeader({
@@ -21,22 +21,23 @@ export default class Resolver {
21
21
  this.apiVersion = apiVersion ?? null;
22
22
  this.resolve = resolve;
23
23
  this.reject = reject;
24
- this.die = new Proxy(this, {
25
- get: (target, prop) => {
26
- const origProp = target[prop];
27
- if (typeof origProp === 'function') {
28
- return (...args) => {
29
- this.resolve(origProp.apply(this, args));
30
- };
31
- }
32
- return origProp;
33
- }
34
- });
24
+ this.die = {
25
+ raw: this.raw,
26
+ json: this.json,
27
+ xml: this.xml,
28
+ html: this.html,
29
+ status301: this.status301,
30
+ status404: this.status404,
31
+ cors: this.cors,
32
+ fileBase64: this.fileBase64,
33
+ file: this.file,
34
+ api: this.api,
35
+ };
35
36
  }
36
37
  ;
37
38
  readFileSync(filePath) {
38
- const publicPath = pathLibrary.resolve(this.publicPath);
39
- const absolutePath = pathLibrary.join(publicPath, filePath);
39
+ const publicPath = path.resolve(this.publicPath);
40
+ const absolutePath = path.join(publicPath, filePath);
40
41
  console.log("readFileSync", { filePath, publicPath, absolutePath });
41
42
  if (!absolutePath.includes(publicPath)) {
42
43
  return "forbiddenpath";
@@ -45,8 +46,8 @@ export default class Resolver {
45
46
  }
46
47
  ;
47
48
  checkFileExist(filePath) {
48
- const publicPath = pathLibrary.resolve(this.publicPath);
49
- const absolutePath = pathLibrary.join(this.publicPath, filePath);
49
+ const publicPath = path.resolve(this.publicPath);
50
+ const absolutePath = path.join(this.publicPath, filePath);
50
51
  console.log("checkFileExist", { filePath, publicPath, absolutePath });
51
52
  if (!absolutePath.includes(publicPath)) {
52
53
  return false;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,16 @@
1
1
  import type { APIGatewayProxyEvent, APIGatewayProxyEventHeaders, Context } from "aws-lambda";
2
2
  import Resolver, { ResolverResponse } from "./Resolver.js";
3
+ type DDBSession = {
4
+ userId: string;
5
+ userIdHash: string;
6
+ sessionHash: string;
7
+ csrfToken: string;
8
+ createdTimeStamp: number;
9
+ expiresTimeStamp: number;
10
+ data: {
11
+ [key: string]: any;
12
+ };
13
+ } | null;
3
14
  type RenderContext = {
4
15
  host: string;
5
16
  url: string;
@@ -14,6 +25,7 @@ type RenderContext = {
14
25
  [key: string]: any;
15
26
  };
16
27
  headers: APIGatewayProxyEventHeaders;
28
+ session: DDBSession;
17
29
  lambdaContext: Context;
18
30
  };
19
31
  type ConditionFunction = (renderContext: RenderContext) => boolean | Promise<boolean>;
@@ -39,18 +51,18 @@ export default class Lambder {
39
51
  apiVersion?: string;
40
52
  isCorsEnabled?: boolean;
41
53
  });
42
- private apiHandler;
43
- private pathHandler;
44
54
  setFallbackHandler(fallbackHandler: (renderContext: RenderContext, resolver: Resolver) => ResolverResponse): void;
45
55
  setGlobalErrorHandler(globalErrorHandler: (err: Error) => ResolverResponse): void;
46
- addApi(condition: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
56
+ addModule(moduleFn: Function): Promise<void>;
57
+ private validateSession;
47
58
  addPath(condition: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
59
+ addPublicApi(condition: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
60
+ addSessionApi(condition: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
48
61
  addHook(hookEvent: 'created', hookFn: HookCreatedFunction, priority?: number): Promise<void>;
49
62
  addHook(hookEvent: 'beforeRender', hookFn: HookBeforeRenderFunction, priority?: number): Promise<void>;
50
63
  addHook(hookEvent: 'afterRender', hookFn: HookAfterRenderFunction, priority?: number): Promise<void>;
51
64
  addHook(hookEvent: 'fallback', hookFn: HookFallbackFunction, priority?: number): Promise<void>;
52
65
  addHook(hookEvent: 'completed', hookFn: HookCompletedFunction, priority?: number): Promise<void>;
53
- addModule(moduleFn: Function): Promise<void>;
54
66
  render(event: APIGatewayProxyEvent, lambdaContext: Context): Promise<ResolverResponse>;
55
67
  }
56
68
  export {};
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ export const createContext = (event, lambdaContext, resolve, reject) => {
9
9
  const cookie = cookieParser.parse(event.headers.Cookie || event.headers.cookie || "");
10
10
  const headers = event.headers;
11
11
  let post = {};
12
+ const session = null;
12
13
  try {
13
14
  const decodedBody = event.isBase64Encoded ? (event.body ? Buffer.from(event.body, "base64").toString() : "{}") : (event.body || "{}");
14
15
  try {
@@ -22,7 +23,7 @@ export const createContext = (event, lambdaContext, resolve, reject) => {
22
23
  if (/^(((\d+\.)+\d+)|(([a-f\d]+:)+[a-f\d]+))$/.test(host)) {
23
24
  reject(new Error("[404] Host cannot be an ip address: " + host));
24
25
  }
25
- return { host, url, method, get, post, cookie, headers, lambdaContext };
26
+ return { host, url, method, get, post, cookie, headers, session, lambdaContext };
26
27
  };
27
28
  export default class Lambder {
28
29
  apiPath;
@@ -46,56 +47,57 @@ export default class Lambder {
46
47
  "completed": []
47
48
  };
48
49
  }
49
- async apiHandler(renderContext, resolver, actionFn) {
50
- // Do context stuff;
51
- return await actionFn(renderContext, resolver);
52
- }
53
- async pathHandler(renderContext, resolver, actionFn) {
54
- // Do context stuff;
55
- return await actionFn(renderContext, resolver);
56
- }
57
50
  setFallbackHandler(fallbackHandler) {
58
51
  this.fallbackHandler = fallbackHandler;
59
52
  }
60
53
  setGlobalErrorHandler(globalErrorHandler) {
61
54
  this.globalErrorHandler = globalErrorHandler;
62
55
  }
63
- addApi(condition, actionFn) {
64
- let conditionFn = (renderContext) => false;
65
- if (typeof condition === "string") {
66
- conditionFn = (renderContext) => renderContext.method === "POST" && renderContext.url === this.apiPath && (renderContext.post?.api) === condition;
67
- }
68
- else if (typeof condition === "function") {
69
- conditionFn = async (renderContext) => renderContext.method === "POST" && renderContext.url === this.apiPath && (await condition(renderContext));
70
- }
71
- else if (condition?.constructor == RegExp) {
72
- conditionFn = (renderContext) => renderContext.method === "POST" && renderContext.url === this.apiPath && condition.test(renderContext.post?.api);
73
- }
74
- else {
75
- throw "Unsupported API Condition";
76
- }
56
+ async addModule(moduleFn) {
57
+ await moduleFn(this);
58
+ }
59
+ async validateSession(session) {
60
+ if (!session)
61
+ return false;
62
+ if (!session.userId || !session.userIdHash || !session.sessionHash || !session.csrfToken)
63
+ return false;
64
+ if (!session.createdTimeStamp || !session.expiresTimeStamp)
65
+ return false;
66
+ if (session.expiresTimeStamp > Date.now())
67
+ return false;
68
+ // Check DDB;
69
+ return false;
70
+ }
71
+ addPath(condition, actionFn) {
77
72
  this._actionList.push({
78
- conditionFn,
79
- actionFn: async (renderContext, resolver) => await this.apiHandler(renderContext, resolver, actionFn)
73
+ conditionFn: async (renderContext) => (renderContext.method === "GET" &&
74
+ ((typeof condition === "string" && renderContext.url === condition) ||
75
+ (typeof condition === "function" && (await condition(renderContext))) ||
76
+ (condition?.constructor == RegExp && condition.test(renderContext.url)))),
77
+ actionFn: async (renderContext, resolver) => await actionFn(renderContext, resolver)
80
78
  });
81
79
  }
82
- addPath(condition, actionFn) {
83
- let conditionFn = (renderContext) => false;
84
- if (typeof condition === "string") {
85
- conditionFn = (renderContext) => renderContext.method === "GET" && renderContext.url === condition;
86
- }
87
- else if (typeof condition === "function") {
88
- conditionFn = async (renderContext) => renderContext.method === "GET" && (await condition(renderContext));
89
- }
90
- else if (condition?.constructor == RegExp) {
91
- conditionFn = (renderContext) => renderContext.method === "GET" && condition.test(renderContext.url);
92
- }
93
- else {
94
- throw "Unsupported Path Condition";
95
- }
80
+ addPublicApi(condition, actionFn) {
96
81
  this._actionList.push({
97
- conditionFn,
98
- actionFn: async (renderContext, resolver) => await this.pathHandler(renderContext, resolver, actionFn)
82
+ conditionFn: async (renderContext) => (renderContext.method === "POST" && renderContext.url === this.apiPath &&
83
+ ((typeof condition === "string" && renderContext.post?.api === condition) ||
84
+ (typeof condition === "function" && (await condition(renderContext))) ||
85
+ (condition?.constructor == RegExp && condition.test(renderContext.post?.api)))),
86
+ actionFn: async (renderContext, resolver) => await actionFn(renderContext, resolver)
87
+ });
88
+ }
89
+ addSessionApi(condition, actionFn) {
90
+ this._actionList.push({
91
+ conditionFn: async (renderContext) => (renderContext.method === "POST" && renderContext.url === this.apiPath &&
92
+ ((typeof condition === "string" && renderContext.post?.api === condition) ||
93
+ (typeof condition === "function" && (await condition(renderContext))) ||
94
+ (condition?.constructor == RegExp && condition.test(renderContext.post?.api)))),
95
+ actionFn: async (renderContext, resolver) => {
96
+ const isSessionValid = this.validateSession(renderContext.session);
97
+ if (!isSessionValid)
98
+ throw new Error("Session not found");
99
+ return await actionFn(renderContext, resolver);
100
+ }
99
101
  });
100
102
  }
101
103
  async addHook(hookEvent, hookFn, priority = 0) {
@@ -107,9 +109,6 @@ export default class Lambder {
107
109
  this._hookList[hookEvent].sort((a, b) => a.priority - b.priority);
108
110
  }
109
111
  }
110
- async addModule(moduleFn) {
111
- await moduleFn(this);
112
- }
113
112
  async render(event, lambdaContext) {
114
113
  return await new Promise(async (resolve, reject) => {
115
114
  const resolver = new Resolver({
@@ -121,14 +120,12 @@ export default class Lambder {
121
120
  let renderContext = createContext(event, lambdaContext, resolve, reject);
122
121
  if (renderContext.method === "OPTIONS")
123
122
  return resolver.cors();
124
- let firstMatchedAction = null;
125
- for (const action of this._actionList) {
126
- const isConditionMet = await action.conditionFn(renderContext);
127
- if (isConditionMet) {
128
- firstMatchedAction = action;
129
- break;
123
+ const firstMatchedAction = await (async () => {
124
+ for (const action of this._actionList) {
125
+ if (await action.conditionFn(renderContext))
126
+ return action;
130
127
  }
131
- }
128
+ })();
132
129
  if (firstMatchedAction) {
133
130
  for (const hook of this._hookList["beforeRender"]) {
134
131
  renderContext = await hook.hookFn(renderContext, resolver);
@@ -140,8 +137,9 @@ export default class Lambder {
140
137
  resolve(renderResult);
141
138
  }
142
139
  else {
143
- for (const hook of this._hookList["fallback"])
140
+ for (const hook of this._hookList["fallback"]) {
144
141
  await hook.hookFn(renderContext, resolver);
142
+ }
145
143
  if (this.fallbackHandler) {
146
144
  const renderResult = await this.fallbackHandler(renderContext, resolver);
147
145
  resolve(renderResult);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lambder",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/Resolver.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import fs from "fs";
2
- import * as pathLibrary from "path";
2
+ import * as path from "path";
3
3
  import mimeTypeResolver from "mime-types";
4
4
 
5
5
  const convertToMultiHeader = (
@@ -49,7 +49,7 @@ export default class Resolver {
49
49
  private apiVersion: string|null;
50
50
  resolve: Function;
51
51
  reject: Function;
52
- die: Partial<IResolverMethods>;
52
+ die: IResolverMethods;
53
53
 
54
54
  constructor(
55
55
  { isCorsEnabled, publicPath, apiVersion, resolve, reject }:
@@ -66,30 +66,31 @@ export default class Resolver {
66
66
  this.apiVersion = apiVersion ?? null;
67
67
  this.resolve = resolve;
68
68
  this.reject = reject;
69
- this.die = new Proxy(this, {
70
- get: (target, prop: keyof IResolverMethods) => {
71
- const origProp = target[prop];
72
- if (typeof origProp === 'function') {
73
- return (...args: any[]) => {
74
- this.resolve((origProp as Function).apply(this, args));
75
- };
76
- }
77
- return origProp;
78
- }
79
- });
69
+ this.die = {
70
+ raw: this.raw,
71
+ json: this.json,
72
+ xml: this.xml,
73
+ html: this.html,
74
+ status301: this.status301,
75
+ status404: this.status404,
76
+ cors: this.cors,
77
+ fileBase64: this.fileBase64,
78
+ file: this.file,
79
+ api: this.api,
80
+ }
80
81
  };
81
82
 
82
83
  private readFileSync(filePath: string){
83
- const publicPath = pathLibrary.resolve(this.publicPath);
84
- const absolutePath = pathLibrary.join(publicPath, filePath);
84
+ const publicPath = path.resolve(this.publicPath);
85
+ const absolutePath = path.join(publicPath, filePath);
85
86
  console.log("readFileSync", { filePath, publicPath, absolutePath });
86
87
  if(!absolutePath.includes(publicPath)){ return "forbiddenpath"; }
87
88
  return fs.readFileSync(absolutePath);
88
89
  };
89
90
 
90
91
  private checkFileExist(filePath: string){
91
- const publicPath = pathLibrary.resolve(this.publicPath);
92
- const absolutePath = pathLibrary.join(this.publicPath, filePath);
92
+ const publicPath = path.resolve(this.publicPath);
93
+ const absolutePath = path.join(this.publicPath, filePath);
93
94
  console.log("checkFileExist", { filePath, publicPath, absolutePath });
94
95
  if(!absolutePath.includes(publicPath)){ return false; }
95
96
  return fs.existsSync(absolutePath) && fs.statSync(absolutePath).isFile();
package/src/index.ts CHANGED
@@ -4,6 +4,16 @@ import cookieParser from "cookie";
4
4
  import type { APIGatewayProxyEvent, APIGatewayProxyEventHeaders, Context } from "aws-lambda";
5
5
  import Resolver, { ResolverResponse } from "./Resolver.js";
6
6
 
7
+ type DDBSession = {
8
+ userId: string,
9
+ userIdHash: string;
10
+ sessionHash: string;
11
+ csrfToken: string;
12
+ createdTimeStamp: number;
13
+ expiresTimeStamp: number;
14
+ data: { [key:string]: any };
15
+ } | null;
16
+
7
17
  type RenderContext = {
8
18
  host: string;
9
19
  url: string;
@@ -12,6 +22,7 @@ type RenderContext = {
12
22
  post: { [key: string]: any };
13
23
  cookie: { [key: string]: any };
14
24
  headers: APIGatewayProxyEventHeaders;
25
+ session: DDBSession;
15
26
  lambdaContext: Context;
16
27
  };
17
28
 
@@ -44,13 +55,14 @@ export const createContext = (
44
55
  const cookie = cookieParser.parse(event.headers.Cookie || event.headers.cookie || "");
45
56
  const headers = event.headers;
46
57
  let post:{ [key:string]: any } = {};
58
+ const session = null;
47
59
  try {
48
60
  const decodedBody = event.isBase64Encoded ? ( event.body ? Buffer.from(event.body,"base64").toString() : "{}" ) : ( event.body || "{}" );
49
61
  try { post = JSON.parse(decodedBody) || {}; }
50
62
  catch(e){ post = querystring.parse(decodedBody) || {}; }
51
63
  }catch(e){}
52
64
  if(/^(((\d+\.)+\d+)|(([a-f\d]+:)+[a-f\d]+))$/.test(host)){ reject(new Error("[404] Host cannot be an ip address: " + host)); }
53
- return { host, url, method, get, post, cookie, headers, lambdaContext };
65
+ return { host, url, method, get, post, cookie, headers, session, lambdaContext };
54
66
  }
55
67
 
56
68
 
@@ -88,14 +100,6 @@ export default class Lambder {
88
100
  };
89
101
  }
90
102
 
91
- private async apiHandler (renderContext:RenderContext, resolver: Resolver, actionFn: ActionFunction){
92
- // Do context stuff;
93
- return await actionFn(renderContext, resolver);
94
- }
95
- private async pathHandler (renderContext:RenderContext, resolver: Resolver, actionFn: ActionFunction){
96
- // Do context stuff;
97
- return await actionFn(renderContext, resolver);
98
- }
99
103
  setFallbackHandler(fallbackHandler: (renderContext:RenderContext, resolver: Resolver)=>ResolverResponse){
100
104
  this.fallbackHandler = fallbackHandler;
101
105
  }
@@ -103,42 +107,64 @@ export default class Lambder {
103
107
  this.globalErrorHandler = globalErrorHandler;
104
108
  }
105
109
 
106
- addApi(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
107
- let conditionFn: ConditionFunction = (renderContext:RenderContext) => false;
108
- if(typeof condition === "string"){
109
- conditionFn = (renderContext:RenderContext) =>
110
- renderContext.method === "POST" && renderContext.url === this.apiPath && (renderContext.post?.api) === condition;
111
- }else if(typeof condition === "function"){
112
- conditionFn = async (renderContext:RenderContext) =>
113
- renderContext.method === "POST" && renderContext.url === this.apiPath && (await condition(renderContext));
114
- }else if(condition?.constructor == RegExp){
115
- conditionFn = (renderContext:RenderContext) =>
116
- renderContext.method === "POST" && renderContext.url === this.apiPath && condition.test(renderContext.post?.api);
117
- }else { throw "Unsupported API Condition"; }
118
- this._actionList.push({
119
- conditionFn,
120
- actionFn: async (renderContext:RenderContext, resolver: Resolver) => await this.apiHandler(renderContext, resolver, actionFn)
121
- });
110
+ async addModule(moduleFn: Function): Promise<void>{
111
+ await moduleFn(this);
112
+ }
113
+
114
+ private async validateSession (session: DDBSession): Promise<boolean>{
115
+ if(!session) return false;
116
+ if(!session.userId || !session.userIdHash || !session.sessionHash || !session.csrfToken) return false;
117
+ if(!session.createdTimeStamp || !session.expiresTimeStamp) return false;
118
+ if(session.expiresTimeStamp > Date.now()) return false;
119
+ // Check DDB;
120
+ return false;
122
121
  }
123
122
 
124
123
  addPath(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
125
- let conditionFn: ConditionFunction = (renderContext:RenderContext) => false;
126
- if(typeof condition === "string"){
127
- conditionFn = (renderContext:RenderContext) =>
128
- renderContext.method === "GET" && renderContext.url === condition;
129
- }else if(typeof condition === "function"){
130
- conditionFn = async (renderContext:RenderContext) =>
131
- renderContext.method === "GET" && (await condition(renderContext));
132
- }else if(condition?.constructor == RegExp){
133
- conditionFn = (renderContext:RenderContext) =>
134
- renderContext.method === "GET" && condition.test(renderContext.url);
135
- }else { throw "Unsupported Path Condition"; }
136
124
  this._actionList.push({
137
- conditionFn,
138
- actionFn: async (renderContext:RenderContext, resolver: Resolver) => await this.pathHandler(renderContext, resolver, actionFn)
125
+ conditionFn: async (renderContext:RenderContext) => (
126
+ renderContext.method === "GET" &&
127
+ (
128
+ (typeof condition === "string" && renderContext.url === condition) ||
129
+ (typeof condition === "function" && (await condition(renderContext))) ||
130
+ (condition?.constructor == RegExp && condition.test(renderContext.url))
131
+ )
132
+ ),
133
+ actionFn: async (renderContext:RenderContext, resolver: Resolver) => await actionFn(renderContext, resolver)
134
+ });
135
+ }
136
+
137
+ addPublicApi(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
138
+ this._actionList.push({
139
+ conditionFn: async (renderContext:RenderContext) => (
140
+ renderContext.method === "POST" && renderContext.url === this.apiPath &&
141
+ (
142
+ (typeof condition === "string" && renderContext.post?.api === condition) ||
143
+ (typeof condition === "function" && (await condition(renderContext))) ||
144
+ (condition?.constructor == RegExp && condition.test(renderContext.post?.api))
145
+ )
146
+ ),
147
+ actionFn: async (renderContext:RenderContext, resolver: Resolver) => await actionFn(renderContext, resolver)
139
148
  });
140
149
  }
141
150
 
151
+ addSessionApi(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
152
+ this._actionList.push({
153
+ conditionFn: async (renderContext:RenderContext) => (
154
+ renderContext.method === "POST" && renderContext.url === this.apiPath &&
155
+ (
156
+ (typeof condition === "string" && renderContext.post?.api === condition) ||
157
+ (typeof condition === "function" && (await condition(renderContext))) ||
158
+ (condition?.constructor == RegExp && condition.test(renderContext.post?.api))
159
+ )
160
+ ),
161
+ actionFn: async (renderContext:RenderContext, resolver: Resolver) => {
162
+ const isSessionValid = this.validateSession(renderContext.session);
163
+ if(!isSessionValid) throw new Error("Session not found");
164
+ return await actionFn(renderContext, resolver);
165
+ }
166
+ });
167
+ }
142
168
 
143
169
 
144
170
  async addHook(hookEvent: 'created', hookFn: HookCreatedFunction, priority?: number): Promise<void>;
@@ -159,10 +185,6 @@ export default class Lambder {
159
185
  }
160
186
  }
161
187
 
162
- async addModule(moduleFn: Function): Promise<void>{
163
- await moduleFn(this);
164
- }
165
-
166
188
  async render(
167
189
  event: APIGatewayProxyEvent,
168
190
  lambdaContext: Context
@@ -171,7 +193,6 @@ export default class Lambder {
171
193
  resolve:(renderResult: ResolverResponse)=>void,
172
194
  reject:(err: Error)=>void
173
195
  )=> {
174
-
175
196
  const resolver = new Resolver({
176
197
  isCorsEnabled: this.isCorsEnabled,
177
198
  publicPath: this.publicPath,
@@ -179,17 +200,13 @@ export default class Lambder {
179
200
  resolve, reject,
180
201
  });
181
202
  let renderContext:RenderContext = createContext(event, lambdaContext, resolve, reject)
182
-
183
203
  if(renderContext.method === "OPTIONS") return resolver.cors();
184
204
 
185
- let firstMatchedAction: null|ActionType = null;
186
- for(const action of this._actionList){
187
- const isConditionMet = await action.conditionFn(renderContext);
188
- if(isConditionMet){
189
- firstMatchedAction = action;
190
- break;
205
+ const firstMatchedAction = await (async () => {
206
+ for (const action of this._actionList) {
207
+ if (await action.conditionFn(renderContext)) return action;
191
208
  }
192
- }
209
+ })();
193
210
 
194
211
  if(firstMatchedAction){
195
212
  for(const hook of this._hookList["beforeRender"]){
@@ -201,7 +218,9 @@ export default class Lambder {
201
218
  }
202
219
  resolve(renderResult);
203
220
  }else{
204
- for(const hook of this._hookList["fallback"]) await hook.hookFn(renderContext, resolver);
221
+ for(const hook of this._hookList["fallback"]){
222
+ await hook.hookFn(renderContext, resolver);
223
+ }
205
224
  if(this.fallbackHandler){
206
225
  const renderResult = await this.fallbackHandler(renderContext, resolver);
207
226
  resolve(renderResult);