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 +7 -8
- package/dist/Lambder.js +21 -15
- package/package.json +1 -1
- package/src/Lambder.ts +30 -29
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) =>
|
|
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(
|
|
64
|
-
addSessionApi(
|
|
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(
|
|
145
|
+
addApi(apiName, actionFn) {
|
|
146
146
|
this.actionList.push({
|
|
147
|
-
conditionFn: (ctx) => (
|
|
148
|
-
(
|
|
149
|
-
|
|
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(
|
|
154
|
+
addSessionApi(apiName, actionFn) {
|
|
156
155
|
this.actionList.push({
|
|
157
|
-
conditionFn: (ctx) => (
|
|
158
|
-
(
|
|
159
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
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) =>
|
|
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"
|
|
48
|
+
type HookEventType = "created"|"beforeRender"|"afterRender"|"fallback";
|
|
49
49
|
type HookListType = {
|
|
50
50
|
priority: number,
|
|
51
|
-
hookFn: HookCreatedFunction|HookBeforeRenderFunction|HookAfterRenderFunction|HookFallbackFunction
|
|
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"]){
|
|
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(
|
|
202
|
+
addApi(apiName: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
|
|
202
203
|
this.actionList.push({
|
|
203
204
|
conditionFn: (ctx:RenderContext) => (
|
|
204
|
-
|
|
205
|
-
(
|
|
206
|
-
|
|
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(
|
|
213
|
+
addSessionApi(apiName: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
|
|
216
214
|
this.actionList.push({
|
|
217
215
|
conditionFn: (ctx:RenderContext) => (
|
|
218
|
-
|
|
219
|
-
(
|
|
220
|
-
|
|
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
|
|
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"]){
|
|
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"]){
|
|
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);
|