lambder 1.0.41 → 1.0.42
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 +8 -8
- package/dist/Lambder.js +44 -45
- package/dist/Resolver.d.ts +2 -2
- package/package.json +1 -1
- package/src/Lambder.ts +53 -62
- package/src/Resolver.ts +2 -2
package/dist/Lambder.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { APIGatewayProxyEvent, APIGatewayProxyEventHeaders, Context } from "aws-lambda";
|
|
2
2
|
import Resolver from "./Resolver.js";
|
|
3
3
|
import ResponseBuilder, { ResolverResponse } from "./ResponseBuilder.js";
|
|
4
|
-
type
|
|
4
|
+
type Session = {
|
|
5
5
|
userId: string;
|
|
6
6
|
userIdHash: string;
|
|
7
7
|
sessionHash: string;
|
|
@@ -11,7 +11,7 @@ type DDBSession = {
|
|
|
11
11
|
data: {
|
|
12
12
|
[key: string]: any;
|
|
13
13
|
};
|
|
14
|
-
}
|
|
14
|
+
};
|
|
15
15
|
type RenderContext = {
|
|
16
16
|
host: string;
|
|
17
17
|
url: string;
|
|
@@ -26,16 +26,16 @@ type RenderContext = {
|
|
|
26
26
|
[key: string]: any;
|
|
27
27
|
};
|
|
28
28
|
headers: APIGatewayProxyEventHeaders;
|
|
29
|
-
session:
|
|
29
|
+
session: Session | null;
|
|
30
30
|
lambdaContext: Context;
|
|
31
31
|
};
|
|
32
|
-
type ConditionFunction = (ctx: RenderContext) => boolean
|
|
32
|
+
type ConditionFunction = (ctx: RenderContext) => boolean;
|
|
33
33
|
type ActionFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse | Promise<ResolverResponse>;
|
|
34
34
|
type HookCreatedFunction = (lambderInstance: Lambder) => Promise<void>;
|
|
35
35
|
type HookBeforeRenderFunction = (ctx: RenderContext, resolver: Resolver) => RenderContext | Promise<RenderContext>;
|
|
36
|
-
type HookAfterRenderFunction = (ctx: RenderContext, resolver: Resolver,
|
|
36
|
+
type HookAfterRenderFunction = (ctx: RenderContext, resolver: Resolver, response: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
|
|
37
37
|
type HookFallbackFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse | Promise<ResolverResponse>;
|
|
38
|
-
type HookCompletedFunction = (
|
|
38
|
+
type HookCompletedFunction = (response: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
|
|
39
39
|
type GlobalErrorHandlerFunction = (err: Error, ctx: RenderContext | null, response: ResponseBuilder) => ResolverResponse | Promise<ResolverResponse>;
|
|
40
40
|
type RouteFallbackHandlerFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse;
|
|
41
41
|
type ApiFallbackHandlerFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse;
|
|
@@ -45,8 +45,8 @@ export default class Lambder {
|
|
|
45
45
|
private apiVersion;
|
|
46
46
|
private isCorsEnabled;
|
|
47
47
|
private publicPath;
|
|
48
|
-
private
|
|
49
|
-
private
|
|
48
|
+
private actionList;
|
|
49
|
+
private hookList;
|
|
50
50
|
private globalErrorHandler;
|
|
51
51
|
private routeFallbackHandler;
|
|
52
52
|
private apiFallbackHandler;
|
package/dist/Lambder.js
CHANGED
|
@@ -31,8 +31,8 @@ export default class Lambder {
|
|
|
31
31
|
apiVersion;
|
|
32
32
|
isCorsEnabled;
|
|
33
33
|
publicPath;
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
actionList;
|
|
35
|
+
hookList;
|
|
36
36
|
globalErrorHandler = null;
|
|
37
37
|
routeFallbackHandler = null;
|
|
38
38
|
apiFallbackHandler = null;
|
|
@@ -41,8 +41,8 @@ export default class Lambder {
|
|
|
41
41
|
this.apiPath = apiPath ?? "/api";
|
|
42
42
|
this.apiVersion = apiVersion ?? null;
|
|
43
43
|
this.isCorsEnabled = isCorsEnabled ?? false;
|
|
44
|
-
this.
|
|
45
|
-
this.
|
|
44
|
+
this.actionList = [];
|
|
45
|
+
this.hookList = {
|
|
46
46
|
"beforeRender": [],
|
|
47
47
|
"afterRender": [],
|
|
48
48
|
"fallback": [],
|
|
@@ -72,16 +72,15 @@ export default class Lambder {
|
|
|
72
72
|
}
|
|
73
73
|
;
|
|
74
74
|
async handleNoMatchedAction(ctx, resolver) {
|
|
75
|
-
for (const hook of this.
|
|
75
|
+
for (const hook of this.hookList["fallback"]) {
|
|
76
76
|
await hook.hookFn(ctx, resolver);
|
|
77
77
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
78
|
+
const isAPI = ctx.url === this.apiPath;
|
|
79
|
+
if (isAPI && this.apiFallbackHandler) {
|
|
80
|
+
resolver.resolve(await this.apiFallbackHandler(ctx, resolver));
|
|
81
|
+
}
|
|
82
|
+
else if (isAPI) {
|
|
83
|
+
resolver.resolve({ statusCode: 204, body: "API handler not set.", });
|
|
85
84
|
}
|
|
86
85
|
else if (this.routeFallbackHandler) {
|
|
87
86
|
resolver.resolve(await this.routeFallbackHandler(ctx, resolver));
|
|
@@ -94,40 +93,45 @@ export default class Lambder {
|
|
|
94
93
|
await moduleFn(this);
|
|
95
94
|
}
|
|
96
95
|
addRoute(condition, actionFn) {
|
|
97
|
-
this.
|
|
98
|
-
conditionFn:
|
|
96
|
+
this.actionList.push({
|
|
97
|
+
conditionFn: (ctx) => (ctx.method === "GET" &&
|
|
99
98
|
((typeof condition === "string" && ctx.url === condition) ||
|
|
100
|
-
(typeof condition === "function" &&
|
|
99
|
+
(typeof condition === "function" && condition(ctx)) ||
|
|
101
100
|
(condition?.constructor == RegExp && condition.test(ctx.url)))),
|
|
102
101
|
actionFn: async (ctx, resolver) => await actionFn(ctx, resolver)
|
|
103
102
|
});
|
|
104
103
|
}
|
|
105
104
|
;
|
|
106
105
|
addSessionRoute(condition, actionFn) {
|
|
107
|
-
this.
|
|
108
|
-
conditionFn:
|
|
106
|
+
this.actionList.push({
|
|
107
|
+
conditionFn: (ctx) => (ctx.method === "GET" &&
|
|
109
108
|
((typeof condition === "string" && ctx.url === condition) ||
|
|
110
|
-
(typeof condition === "function" &&
|
|
109
|
+
(typeof condition === "function" && condition(ctx)) ||
|
|
111
110
|
(condition?.constructor == RegExp && condition.test(ctx.url)))),
|
|
112
|
-
actionFn: async (ctx, resolver) =>
|
|
111
|
+
actionFn: async (ctx, resolver) => {
|
|
112
|
+
const isSessionValid = this.validateSession(ctx.session);
|
|
113
|
+
if (!isSessionValid)
|
|
114
|
+
throw new Error("Session not found");
|
|
115
|
+
return await actionFn(ctx, resolver);
|
|
116
|
+
}
|
|
113
117
|
});
|
|
114
118
|
}
|
|
115
119
|
;
|
|
116
120
|
addApi(condition, actionFn) {
|
|
117
|
-
this.
|
|
118
|
-
conditionFn:
|
|
121
|
+
this.actionList.push({
|
|
122
|
+
conditionFn: (ctx) => (ctx.method === "POST" && ctx.url === this.apiPath &&
|
|
119
123
|
((typeof condition === "string" && ctx.post?.api === condition) ||
|
|
120
|
-
(typeof condition === "function" &&
|
|
124
|
+
(typeof condition === "function" && condition(ctx)) ||
|
|
121
125
|
(condition?.constructor == RegExp && condition.test(ctx.post?.api)))),
|
|
122
|
-
actionFn: async (ctx, resolver) => await actionFn(ctx, resolver)
|
|
126
|
+
actionFn: async (ctx, resolver) => await actionFn(ctx, resolver),
|
|
123
127
|
});
|
|
124
128
|
}
|
|
125
129
|
;
|
|
126
130
|
addSessionApi(condition, actionFn) {
|
|
127
|
-
this.
|
|
128
|
-
conditionFn:
|
|
131
|
+
this.actionList.push({
|
|
132
|
+
conditionFn: (ctx) => (ctx.method === "POST" && ctx.url === this.apiPath &&
|
|
129
133
|
((typeof condition === "string" && ctx.post?.api === condition) ||
|
|
130
|
-
(typeof condition === "function" &&
|
|
134
|
+
(typeof condition === "function" && condition(ctx)) ||
|
|
131
135
|
(condition?.constructor == RegExp && condition.test(ctx.post?.api)))),
|
|
132
136
|
actionFn: async (ctx, resolver) => {
|
|
133
137
|
const isSessionValid = this.validateSession(ctx.session);
|
|
@@ -143,8 +147,8 @@ export default class Lambder {
|
|
|
143
147
|
await hookFn(this);
|
|
144
148
|
}
|
|
145
149
|
else {
|
|
146
|
-
this.
|
|
147
|
-
this.
|
|
150
|
+
this.hookList[hookEvent].push({ priority, hookFn });
|
|
151
|
+
this.hookList[hookEvent].sort((a, b) => a.priority - b.priority);
|
|
148
152
|
}
|
|
149
153
|
}
|
|
150
154
|
getResponseBuilder() {
|
|
@@ -173,36 +177,31 @@ export default class Lambder {
|
|
|
173
177
|
const resolver = this.getResolver(resolve, reject);
|
|
174
178
|
if (ctx.method === "OPTIONS")
|
|
175
179
|
return resolver.cors();
|
|
176
|
-
const firstMatchedAction =
|
|
177
|
-
for (const action of this._actionList) {
|
|
178
|
-
if (await action.conditionFn(ctx))
|
|
179
|
-
return action;
|
|
180
|
-
}
|
|
181
|
-
})();
|
|
180
|
+
const firstMatchedAction = this.actionList.find(action => action.conditionFn(ctx));
|
|
182
181
|
if (firstMatchedAction) {
|
|
183
|
-
for (const hook of this.
|
|
182
|
+
for (const hook of this.hookList["beforeRender"]) {
|
|
184
183
|
ctx = await hook.hookFn(ctx, resolver);
|
|
185
184
|
}
|
|
186
|
-
let
|
|
187
|
-
for (const hook of this.
|
|
188
|
-
|
|
185
|
+
let response = await firstMatchedAction.actionFn(ctx, resolver);
|
|
186
|
+
for (const hook of this.hookList["afterRender"]) {
|
|
187
|
+
response = await hook.hookFn(ctx, resolver, response);
|
|
189
188
|
}
|
|
190
|
-
resolve(
|
|
189
|
+
resolve(response);
|
|
191
190
|
}
|
|
192
191
|
else {
|
|
193
192
|
return this.handleNoMatchedAction(ctx, resolver);
|
|
194
193
|
}
|
|
195
|
-
}).then(async (
|
|
196
|
-
for (const hook of this.
|
|
197
|
-
|
|
194
|
+
}).then(async (response) => {
|
|
195
|
+
for (const hook of this.hookList["completed"]) {
|
|
196
|
+
response = await hook.hookFn(response);
|
|
198
197
|
}
|
|
199
|
-
return
|
|
198
|
+
return response;
|
|
200
199
|
});
|
|
201
200
|
}
|
|
202
201
|
catch (err) {
|
|
203
|
-
const responseBuilder = this.getResponseBuilder();
|
|
204
|
-
const wrappedError = err instanceof Error ? err : new Error("Error: " + String(err));
|
|
205
202
|
if (this.globalErrorHandler) {
|
|
203
|
+
const wrappedError = err instanceof Error ? err : new Error("Error: " + String(err));
|
|
204
|
+
const responseBuilder = this.getResponseBuilder();
|
|
206
205
|
return this.globalErrorHandler(wrappedError, eventRenderContext, responseBuilder);
|
|
207
206
|
}
|
|
208
207
|
return { statusCode: 500, body: "Internal Server Error.", };
|
package/dist/Resolver.d.ts
CHANGED
|
@@ -13,14 +13,14 @@ interface DieResolverMethods {
|
|
|
13
13
|
api: MethodType<ResponseBuilder, 'api'>;
|
|
14
14
|
}
|
|
15
15
|
export default class Resolver extends ResponseBuilder {
|
|
16
|
-
resolve: (
|
|
16
|
+
resolve: (response: ResolverResponse) => void;
|
|
17
17
|
reject: (err: Error) => void;
|
|
18
18
|
die: DieResolverMethods;
|
|
19
19
|
constructor({ isCorsEnabled, publicPath, apiVersion, resolve, reject }: {
|
|
20
20
|
isCorsEnabled: boolean;
|
|
21
21
|
publicPath: string;
|
|
22
22
|
apiVersion?: string | null;
|
|
23
|
-
resolve: (
|
|
23
|
+
resolve: (response: ResolverResponse) => void;
|
|
24
24
|
reject: (err: Error) => void;
|
|
25
25
|
});
|
|
26
26
|
private autoResolve;
|
package/package.json
CHANGED
package/src/Lambder.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { APIGatewayProxyEvent, APIGatewayProxyEventHeaders, Context } from
|
|
|
5
5
|
import Resolver from "./Resolver.js";
|
|
6
6
|
import ResponseBuilder, { ResolverResponse } from "./ResponseBuilder.js";
|
|
7
7
|
|
|
8
|
-
type
|
|
8
|
+
type Session = {
|
|
9
9
|
userId: string,
|
|
10
10
|
userIdHash: string;
|
|
11
11
|
sessionHash: string;
|
|
@@ -13,7 +13,7 @@ type DDBSession = {
|
|
|
13
13
|
createdTimeStamp: number;
|
|
14
14
|
expiresTimeStamp: number;
|
|
15
15
|
data: { [key:string]: any };
|
|
16
|
-
}
|
|
16
|
+
};
|
|
17
17
|
|
|
18
18
|
type RenderContext = {
|
|
19
19
|
host: string;
|
|
@@ -23,19 +23,19 @@ type RenderContext = {
|
|
|
23
23
|
post: { [key: string]: any };
|
|
24
24
|
cookie: { [key: string]: any };
|
|
25
25
|
headers: APIGatewayProxyEventHeaders;
|
|
26
|
-
session:
|
|
26
|
+
session: Session|null;
|
|
27
27
|
lambdaContext: Context;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
type ConditionFunction = (ctx: RenderContext) => boolean
|
|
30
|
+
type ConditionFunction = (ctx: RenderContext) => boolean;
|
|
31
31
|
type ActionFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse|Promise<ResolverResponse>;
|
|
32
|
-
type
|
|
32
|
+
type ActionObject = { conditionFn: ConditionFunction, actionFn: ActionFunction };
|
|
33
33
|
|
|
34
34
|
type HookCreatedFunction = (lambderInstance: Lambder) => Promise<void>;
|
|
35
35
|
type HookBeforeRenderFunction = (ctx: RenderContext, resolver: Resolver) => RenderContext|Promise<RenderContext>;
|
|
36
|
-
type HookAfterRenderFunction = (ctx: RenderContext, resolver: Resolver,
|
|
36
|
+
type HookAfterRenderFunction = (ctx: RenderContext, resolver: Resolver, response: ResolverResponse) => ResolverResponse|Promise<ResolverResponse>;
|
|
37
37
|
type HookFallbackFunction = (ctx: RenderContext, resolver: Resolver) => ResolverResponse|Promise<ResolverResponse>;
|
|
38
|
-
type HookCompletedFunction = (
|
|
38
|
+
type HookCompletedFunction = (response: ResolverResponse) => ResolverResponse|Promise<ResolverResponse>;
|
|
39
39
|
|
|
40
40
|
type GlobalErrorHandlerFunction = (err: Error, ctx: RenderContext|null, response: ResponseBuilder) => ResolverResponse|Promise<ResolverResponse>;
|
|
41
41
|
type RouteFallbackHandlerFunction = (ctx:RenderContext, resolver: Resolver) => ResolverResponse;
|
|
@@ -75,8 +75,8 @@ export default class Lambder {
|
|
|
75
75
|
private isCorsEnabled: boolean;
|
|
76
76
|
private publicPath: string;
|
|
77
77
|
|
|
78
|
-
private
|
|
79
|
-
private
|
|
78
|
+
private actionList: ActionObject[];
|
|
79
|
+
private hookList: {
|
|
80
80
|
"beforeRender": { priority: number, hookFn: HookBeforeRenderFunction }[],
|
|
81
81
|
"afterRender": { priority: number, hookFn: HookAfterRenderFunction }[],
|
|
82
82
|
"fallback": { priority: number, hookFn: HookFallbackFunction }[],
|
|
@@ -95,8 +95,8 @@ export default class Lambder {
|
|
|
95
95
|
this.apiVersion = apiVersion ?? null;
|
|
96
96
|
this.isCorsEnabled = isCorsEnabled ?? false;
|
|
97
97
|
|
|
98
|
-
this.
|
|
99
|
-
this.
|
|
98
|
+
this.actionList = [];
|
|
99
|
+
this.hookList = {
|
|
100
100
|
"beforeRender": [],
|
|
101
101
|
"afterRender": [],
|
|
102
102
|
"fallback": [],
|
|
@@ -114,7 +114,7 @@ export default class Lambder {
|
|
|
114
114
|
this.globalErrorHandler = globalErrorHandler;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
private async validateSession (session:
|
|
117
|
+
private async validateSession (session: Session|null): Promise<boolean>{
|
|
118
118
|
if(!session) return false;
|
|
119
119
|
if(!session.userId || !session.userIdHash || !session.sessionHash || !session.csrfToken) return false;
|
|
120
120
|
if(!session.createdTimeStamp || !session.expiresTimeStamp) return false;
|
|
@@ -124,15 +124,13 @@ export default class Lambder {
|
|
|
124
124
|
};
|
|
125
125
|
|
|
126
126
|
private async handleNoMatchedAction(ctx: RenderContext, resolver: Resolver){
|
|
127
|
-
for(const hook of this.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if(
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
resolver.resolve({ statusCode: 204, body: "API handler not set.", })
|
|
135
|
-
}
|
|
127
|
+
for(const hook of this.hookList["fallback"]){ await hook.hookFn(ctx, resolver); }
|
|
128
|
+
|
|
129
|
+
const isAPI = ctx.url === this.apiPath;
|
|
130
|
+
if(isAPI && this.apiFallbackHandler){
|
|
131
|
+
resolver.resolve(await this.apiFallbackHandler(ctx, resolver));
|
|
132
|
+
}else if(isAPI){
|
|
133
|
+
resolver.resolve({ statusCode: 204, body: "API handler not set.", })
|
|
136
134
|
}else if(this.routeFallbackHandler){
|
|
137
135
|
resolver.resolve(await this.routeFallbackHandler(ctx, resolver));
|
|
138
136
|
}else{
|
|
@@ -144,12 +142,12 @@ export default class Lambder {
|
|
|
144
142
|
await moduleFn(this);
|
|
145
143
|
}
|
|
146
144
|
addRoute(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
|
|
147
|
-
this.
|
|
148
|
-
conditionFn:
|
|
145
|
+
this.actionList.push({
|
|
146
|
+
conditionFn: (ctx:RenderContext) => (
|
|
149
147
|
ctx.method === "GET" &&
|
|
150
148
|
(
|
|
151
149
|
(typeof condition === "string" && ctx.url === condition) ||
|
|
152
|
-
(typeof condition === "function" &&
|
|
150
|
+
(typeof condition === "function" && condition(ctx)) ||
|
|
153
151
|
(condition?.constructor == RegExp && condition.test(ctx.url))
|
|
154
152
|
)
|
|
155
153
|
),
|
|
@@ -158,40 +156,44 @@ export default class Lambder {
|
|
|
158
156
|
};
|
|
159
157
|
|
|
160
158
|
addSessionRoute(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
|
|
161
|
-
this.
|
|
162
|
-
conditionFn:
|
|
163
|
-
ctx.method === "GET" &&
|
|
159
|
+
this.actionList.push({
|
|
160
|
+
conditionFn: (ctx:RenderContext) => (
|
|
161
|
+
ctx.method === "GET" &&
|
|
164
162
|
(
|
|
165
163
|
(typeof condition === "string" && ctx.url === condition) ||
|
|
166
|
-
(typeof condition === "function" &&
|
|
164
|
+
(typeof condition === "function" && condition(ctx)) ||
|
|
167
165
|
(condition?.constructor == RegExp && condition.test(ctx.url))
|
|
168
166
|
)
|
|
169
167
|
),
|
|
170
|
-
actionFn: async (ctx:RenderContext, resolver: Resolver) =>
|
|
168
|
+
actionFn: async (ctx:RenderContext, resolver: Resolver) => {
|
|
169
|
+
const isSessionValid = this.validateSession(ctx.session);
|
|
170
|
+
if(!isSessionValid) throw new Error("Session not found");
|
|
171
|
+
return await actionFn(ctx, resolver);
|
|
172
|
+
}
|
|
171
173
|
});
|
|
172
174
|
};
|
|
173
175
|
|
|
174
176
|
addApi(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
|
|
175
|
-
this.
|
|
176
|
-
conditionFn:
|
|
177
|
+
this.actionList.push({
|
|
178
|
+
conditionFn: (ctx:RenderContext) => (
|
|
177
179
|
ctx.method === "POST" && ctx.url === this.apiPath &&
|
|
178
180
|
(
|
|
179
181
|
(typeof condition === "string" && ctx.post?.api === condition) ||
|
|
180
|
-
(typeof condition === "function" &&
|
|
182
|
+
(typeof condition === "function" && condition(ctx)) ||
|
|
181
183
|
(condition?.constructor == RegExp && condition.test(ctx.post?.api))
|
|
182
184
|
)
|
|
183
185
|
),
|
|
184
|
-
actionFn: async (ctx:RenderContext, resolver: Resolver) => await actionFn(ctx, resolver)
|
|
186
|
+
actionFn: async (ctx:RenderContext, resolver: Resolver) => await actionFn(ctx, resolver),
|
|
185
187
|
});
|
|
186
188
|
};
|
|
187
189
|
|
|
188
190
|
addSessionApi(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
|
|
189
|
-
this.
|
|
190
|
-
conditionFn:
|
|
191
|
-
ctx.method === "POST" && ctx.url === this.apiPath &&
|
|
191
|
+
this.actionList.push({
|
|
192
|
+
conditionFn: (ctx:RenderContext) => (
|
|
193
|
+
ctx.method === "POST" && ctx.url === this.apiPath &&
|
|
192
194
|
(
|
|
193
195
|
(typeof condition === "string" && ctx.post?.api === condition) ||
|
|
194
|
-
(typeof condition === "function" &&
|
|
196
|
+
(typeof condition === "function" && condition(ctx)) ||
|
|
195
197
|
(condition?.constructor == RegExp && condition.test(ctx.post?.api))
|
|
196
198
|
)
|
|
197
199
|
),
|
|
@@ -217,8 +219,8 @@ export default class Lambder {
|
|
|
217
219
|
if(hookEvent === "created"){
|
|
218
220
|
await hookFn(this);
|
|
219
221
|
}else{
|
|
220
|
-
this.
|
|
221
|
-
this.
|
|
222
|
+
this.hookList[hookEvent].push({ priority, hookFn });
|
|
223
|
+
this.hookList[hookEvent].sort((a, b) => a.priority - b.priority);
|
|
222
224
|
}
|
|
223
225
|
}
|
|
224
226
|
|
|
@@ -230,7 +232,7 @@ export default class Lambder {
|
|
|
230
232
|
});
|
|
231
233
|
};
|
|
232
234
|
|
|
233
|
-
private getResolver(resolve: (
|
|
235
|
+
private getResolver(resolve: (response: ResolverResponse) => void, reject: (err: Error) => void){
|
|
234
236
|
return new Resolver({
|
|
235
237
|
isCorsEnabled: this.isCorsEnabled,
|
|
236
238
|
publicPath: this.publicPath,
|
|
@@ -250,40 +252,29 @@ export default class Lambder {
|
|
|
250
252
|
eventRenderContext = ctx;
|
|
251
253
|
|
|
252
254
|
return await new Promise(async (
|
|
253
|
-
resolve:(
|
|
255
|
+
resolve:(response: ResolverResponse)=>void,
|
|
254
256
|
reject:(err: Error)=>void
|
|
255
257
|
)=> {
|
|
256
258
|
const resolver = this.getResolver(resolve, reject);
|
|
257
259
|
if(ctx.method === "OPTIONS") return resolver.cors();
|
|
258
260
|
|
|
259
|
-
const firstMatchedAction =
|
|
260
|
-
for(const action of this._actionList){
|
|
261
|
-
if(await action.conditionFn(ctx)) return action;
|
|
262
|
-
}
|
|
263
|
-
})();
|
|
264
|
-
|
|
261
|
+
const firstMatchedAction = this.actionList.find(action => action.conditionFn(ctx));
|
|
265
262
|
if(firstMatchedAction){
|
|
266
|
-
for(const hook of this.
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
for(const hook of this._hookList["afterRender"]){
|
|
271
|
-
renderResult = await hook.hookFn(ctx, resolver, renderResult);
|
|
272
|
-
}
|
|
273
|
-
resolve(renderResult);
|
|
263
|
+
for(const hook of this.hookList["beforeRender"]){ ctx = await hook.hookFn(ctx, resolver); }
|
|
264
|
+
let response = await firstMatchedAction.actionFn(ctx, resolver);
|
|
265
|
+
for(const hook of this.hookList["afterRender"]){ response = await hook.hookFn(ctx, resolver, response); }
|
|
266
|
+
resolve(response);
|
|
274
267
|
}else{
|
|
275
268
|
return this.handleNoMatchedAction(ctx, resolver);
|
|
276
269
|
}
|
|
277
|
-
}).then(async (
|
|
278
|
-
for(const hook of this.
|
|
279
|
-
|
|
280
|
-
}
|
|
281
|
-
return renderResult;
|
|
270
|
+
}).then(async (response: ResolverResponse):Promise<ResolverResponse> => {
|
|
271
|
+
for(const hook of this.hookList["completed"]){ response = await hook.hookFn(response); }
|
|
272
|
+
return response;
|
|
282
273
|
});
|
|
283
274
|
}catch(err){
|
|
284
|
-
const responseBuilder = this.getResponseBuilder();
|
|
285
|
-
const wrappedError = err instanceof Error ? err : new Error("Error: " + String(err));
|
|
286
275
|
if(this.globalErrorHandler){
|
|
276
|
+
const wrappedError = err instanceof Error ? err : new Error("Error: " + String(err));
|
|
277
|
+
const responseBuilder = this.getResponseBuilder();
|
|
287
278
|
return this.globalErrorHandler(wrappedError, eventRenderContext, responseBuilder);
|
|
288
279
|
}
|
|
289
280
|
return { statusCode: 500, body: "Internal Server Error.", }
|
package/src/Resolver.ts
CHANGED
|
@@ -16,7 +16,7 @@ interface DieResolverMethods {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export default class Resolver extends ResponseBuilder {
|
|
19
|
-
public resolve: (
|
|
19
|
+
public resolve: (response: ResolverResponse) => void;
|
|
20
20
|
public reject: (err: Error) => void;
|
|
21
21
|
public die: DieResolverMethods;
|
|
22
22
|
|
|
@@ -26,7 +26,7 @@ export default class Resolver extends ResponseBuilder {
|
|
|
26
26
|
isCorsEnabled: boolean,
|
|
27
27
|
publicPath: string,
|
|
28
28
|
apiVersion?: string|null,
|
|
29
|
-
resolve: (
|
|
29
|
+
resolve: (response: ResolverResponse) => void,
|
|
30
30
|
reject: (err: Error) => void,
|
|
31
31
|
}
|
|
32
32
|
){
|