lambder 1.0.28 → 1.0.31
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 -4
- package/dist/Lambder.js +42 -36
- package/package.json +1 -1
- package/src/Lambder.ts +54 -44
package/dist/Lambder.d.ts
CHANGED
|
@@ -35,7 +35,10 @@ type HookBeforeRenderFunction = (renderContext: RenderContext, resolver: Resolve
|
|
|
35
35
|
type HookAfterRenderFunction = (renderContext: RenderContext, resolver: Resolver, renderResult: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
|
|
36
36
|
type HookFallbackFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse | Promise<ResolverResponse>;
|
|
37
37
|
type HookCompletedFunction = (renderResult: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
|
|
38
|
-
|
|
38
|
+
type GlobalErrorHandlerFunction = (err: Error, renderContext: RenderContext | null) => ResolverResponse | Promise<ResolverResponse>;
|
|
39
|
+
type RouteFallbackHandlerFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse;
|
|
40
|
+
type ApiFallbackHandlerFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse;
|
|
41
|
+
export declare const createContext: (event: APIGatewayProxyEvent, lambdaContext: Context) => RenderContext;
|
|
39
42
|
export default class Lambder {
|
|
40
43
|
private apiPath;
|
|
41
44
|
private apiVersion;
|
|
@@ -52,9 +55,9 @@ export default class Lambder {
|
|
|
52
55
|
apiVersion?: string;
|
|
53
56
|
isCorsEnabled?: boolean;
|
|
54
57
|
});
|
|
55
|
-
setRouteFallbackHandler(routeFallbackHandler:
|
|
56
|
-
setApiFallbackHandler(apiFallbackHandler:
|
|
57
|
-
setGlobalErrorHandler(globalErrorHandler:
|
|
58
|
+
setRouteFallbackHandler(routeFallbackHandler: RouteFallbackHandlerFunction): void;
|
|
59
|
+
setApiFallbackHandler(apiFallbackHandler: ApiFallbackHandlerFunction): void;
|
|
60
|
+
setGlobalErrorHandler(globalErrorHandler: GlobalErrorHandlerFunction): void;
|
|
58
61
|
private validateSession;
|
|
59
62
|
private handleNoMatchedAction;
|
|
60
63
|
addModule(moduleFn: Function): Promise<void>;
|
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
|
-
export const createContext = (event, lambdaContext
|
|
4
|
+
export const createContext = (event, lambdaContext) => {
|
|
5
5
|
const host = event.headers.Host || event.headers.host || "";
|
|
6
6
|
const url = event.path;
|
|
7
7
|
const get = event.queryStringParameters || {};
|
|
@@ -21,7 +21,7 @@ export const createContext = (event, lambdaContext, resolve, reject) => {
|
|
|
21
21
|
}
|
|
22
22
|
catch (e) { }
|
|
23
23
|
if (/^(((\d+\.)+\d+)|(([a-f\d]+:)+[a-f\d]+))$/.test(host)) {
|
|
24
|
-
|
|
24
|
+
throw new Error("[404] Host cannot be an ip address: " + host);
|
|
25
25
|
}
|
|
26
26
|
return { host, url, method, get, post, cookie, headers, session, lambdaContext };
|
|
27
27
|
};
|
|
@@ -147,45 +147,51 @@ export default class Lambder {
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
async render(event, lambdaContext) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
150
|
+
let eventRenderContext = null;
|
|
151
|
+
try {
|
|
152
|
+
let renderContext = createContext(event, lambdaContext);
|
|
153
|
+
eventRenderContext = renderContext;
|
|
154
|
+
return await new Promise(async (resolve, reject) => {
|
|
155
|
+
const resolver = new Resolver({
|
|
156
|
+
isCorsEnabled: this.isCorsEnabled,
|
|
157
|
+
publicPath: this.publicPath,
|
|
158
|
+
apiVersion: this.apiVersion,
|
|
159
|
+
resolve, reject,
|
|
160
|
+
});
|
|
161
|
+
if (renderContext.method === "OPTIONS")
|
|
162
|
+
return resolver.cors();
|
|
163
|
+
const firstMatchedAction = await (async () => {
|
|
164
|
+
for (const action of this._actionList) {
|
|
165
|
+
if (await action.conditionFn(renderContext))
|
|
166
|
+
return action;
|
|
167
|
+
}
|
|
168
|
+
})();
|
|
169
|
+
if (firstMatchedAction) {
|
|
170
|
+
for (const hook of this._hookList["beforeRender"]) {
|
|
171
|
+
renderContext = await hook.hookFn(renderContext, resolver);
|
|
172
|
+
}
|
|
173
|
+
let renderResult = await firstMatchedAction.actionFn(renderContext, resolver);
|
|
174
|
+
for (const hook of this._hookList["afterRender"]) {
|
|
175
|
+
renderResult = await hook.hookFn(renderContext, resolver, renderResult);
|
|
176
|
+
}
|
|
177
|
+
resolve(renderResult);
|
|
164
178
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
for (const hook of this._hookList["beforeRender"]) {
|
|
168
|
-
renderContext = await hook.hookFn(renderContext, resolver);
|
|
179
|
+
else {
|
|
180
|
+
return this.handleNoMatchedAction(renderContext, resolver);
|
|
169
181
|
}
|
|
170
|
-
|
|
171
|
-
for (const hook of this._hookList["
|
|
172
|
-
renderResult = await hook.hookFn(
|
|
182
|
+
}).then(async (renderResult) => {
|
|
183
|
+
for (const hook of this._hookList["completed"]) {
|
|
184
|
+
renderResult = await hook.hookFn(renderResult);
|
|
173
185
|
}
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}).then(async (renderResult) => {
|
|
180
|
-
for (const hook of this._hookList["completed"]) {
|
|
181
|
-
renderResult = await hook.hookFn(renderResult);
|
|
182
|
-
}
|
|
183
|
-
return renderResult;
|
|
184
|
-
}).catch(async (err) => {
|
|
186
|
+
return renderResult;
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
const wrappedError = err instanceof Error ? err : new Error("Error: " + String(err));
|
|
185
191
|
if (this.globalErrorHandler) {
|
|
186
|
-
return this.globalErrorHandler(
|
|
192
|
+
return this.globalErrorHandler(wrappedError, eventRenderContext);
|
|
187
193
|
}
|
|
188
194
|
return { statusCode: 500, body: "Internal Server Error.", };
|
|
189
|
-
}
|
|
195
|
+
}
|
|
190
196
|
}
|
|
191
197
|
}
|
package/package.json
CHANGED
package/src/Lambder.ts
CHANGED
|
@@ -36,6 +36,10 @@ type HookAfterRenderFunction = (renderContext: RenderContext, resolver: Resolver
|
|
|
36
36
|
type HookFallbackFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse|Promise<ResolverResponse>;
|
|
37
37
|
type HookCompletedFunction = (renderResult: ResolverResponse) => ResolverResponse|Promise<ResolverResponse>;
|
|
38
38
|
|
|
39
|
+
type GlobalErrorHandlerFunction = (err: Error, renderContext: RenderContext|null) => ResolverResponse|Promise<ResolverResponse>;
|
|
40
|
+
type RouteFallbackHandlerFunction = (renderContext:RenderContext, resolver: Resolver) => ResolverResponse;
|
|
41
|
+
type ApiFallbackHandlerFunction = (renderContext:RenderContext, resolver: Resolver) => ResolverResponse;
|
|
42
|
+
|
|
39
43
|
type HookEventType = "created"|"beforeRender"|"afterRender"|"fallback"|"completed";
|
|
40
44
|
type HookListType = {
|
|
41
45
|
priority: number,
|
|
@@ -45,8 +49,6 @@ type HookListType = {
|
|
|
45
49
|
export const createContext = (
|
|
46
50
|
event: APIGatewayProxyEvent,
|
|
47
51
|
lambdaContext: Context,
|
|
48
|
-
resolve: Function,
|
|
49
|
-
reject: Function
|
|
50
52
|
):RenderContext => {
|
|
51
53
|
const host = event.headers.Host || event.headers.host || "";
|
|
52
54
|
const url = event.path;
|
|
@@ -61,7 +63,7 @@ export const createContext = (
|
|
|
61
63
|
try { post = JSON.parse(decodedBody) || {}; }
|
|
62
64
|
catch(e){ post = querystring.parse(decodedBody) || {}; }
|
|
63
65
|
}catch(e){}
|
|
64
|
-
if(/^(((\d+\.)+\d+)|(([a-f\d]+:)+[a-f\d]+))$/.test(host)){
|
|
66
|
+
if(/^(((\d+\.)+\d+)|(([a-f\d]+:)+[a-f\d]+))$/.test(host)){ throw new Error("[404] Host cannot be an ip address: " + host); }
|
|
65
67
|
return { host, url, method, get, post, cookie, headers, session, lambdaContext };
|
|
66
68
|
}
|
|
67
69
|
|
|
@@ -79,9 +81,9 @@ export default class Lambder {
|
|
|
79
81
|
"fallback": { priority: number, hookFn: HookFallbackFunction }[],
|
|
80
82
|
"completed": { priority: number, hookFn: HookCompletedFunction }[]
|
|
81
83
|
};
|
|
82
|
-
private globalErrorHandler:
|
|
83
|
-
private routeFallbackHandler:
|
|
84
|
-
private apiFallbackHandler:
|
|
84
|
+
private globalErrorHandler: GlobalErrorHandlerFunction|null = null;
|
|
85
|
+
private routeFallbackHandler: RouteFallbackHandlerFunction|null = null;
|
|
86
|
+
private apiFallbackHandler: ApiFallbackHandlerFunction|null = null;
|
|
85
87
|
|
|
86
88
|
constructor(
|
|
87
89
|
{ publicPath, apiPath, apiVersion, isCorsEnabled, }:
|
|
@@ -101,13 +103,13 @@ export default class Lambder {
|
|
|
101
103
|
};
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
setRouteFallbackHandler(routeFallbackHandler:
|
|
106
|
+
setRouteFallbackHandler(routeFallbackHandler: RouteFallbackHandlerFunction){
|
|
105
107
|
this.routeFallbackHandler = routeFallbackHandler;
|
|
106
108
|
}
|
|
107
|
-
setApiFallbackHandler(apiFallbackHandler:
|
|
109
|
+
setApiFallbackHandler(apiFallbackHandler: ApiFallbackHandlerFunction){
|
|
108
110
|
this.apiFallbackHandler = apiFallbackHandler;
|
|
109
111
|
}
|
|
110
|
-
setGlobalErrorHandler(globalErrorHandler:
|
|
112
|
+
setGlobalErrorHandler(globalErrorHandler: GlobalErrorHandlerFunction){
|
|
111
113
|
this.globalErrorHandler = globalErrorHandler;
|
|
112
114
|
}
|
|
113
115
|
|
|
@@ -224,48 +226,56 @@ export default class Lambder {
|
|
|
224
226
|
event: APIGatewayProxyEvent,
|
|
225
227
|
lambdaContext: Context
|
|
226
228
|
): Promise<ResolverResponse>{
|
|
227
|
-
|
|
228
|
-
resolve:(renderResult: ResolverResponse)=>void,
|
|
229
|
-
reject:(err: Error)=>void
|
|
230
|
-
)=> {
|
|
231
|
-
const resolver = new Resolver({
|
|
232
|
-
isCorsEnabled: this.isCorsEnabled,
|
|
233
|
-
publicPath: this.publicPath,
|
|
234
|
-
apiVersion: this.apiVersion,
|
|
235
|
-
resolve, reject,
|
|
236
|
-
});
|
|
237
|
-
let renderContext:RenderContext = createContext(event, lambdaContext, resolve, reject)
|
|
238
|
-
if(renderContext.method === "OPTIONS") return resolver.cors();
|
|
229
|
+
let eventRenderContext:RenderContext|null = null;
|
|
239
230
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
})();
|
|
231
|
+
try {
|
|
232
|
+
let renderContext = createContext(event, lambdaContext);
|
|
233
|
+
eventRenderContext = renderContext;
|
|
245
234
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
235
|
+
return await new Promise(async (
|
|
236
|
+
resolve:(renderResult: ResolverResponse)=>void,
|
|
237
|
+
reject:(err: Error)=>void
|
|
238
|
+
)=> {
|
|
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();
|
|
246
|
+
|
|
247
|
+
const firstMatchedAction = await (async () => {
|
|
248
|
+
for(const action of this._actionList){
|
|
249
|
+
if(await action.conditionFn(renderContext)) return action;
|
|
250
|
+
}
|
|
251
|
+
})();
|
|
252
|
+
|
|
253
|
+
if(firstMatchedAction){
|
|
254
|
+
for(const hook of this._hookList["beforeRender"]){
|
|
255
|
+
renderContext = await hook.hookFn(renderContext, resolver);
|
|
256
|
+
}
|
|
257
|
+
let renderResult = await firstMatchedAction.actionFn(renderContext, resolver);
|
|
258
|
+
for(const hook of this._hookList["afterRender"]){
|
|
259
|
+
renderResult = await hook.hookFn(renderContext, resolver, renderResult);
|
|
260
|
+
}
|
|
261
|
+
resolve(renderResult);
|
|
262
|
+
}else{
|
|
263
|
+
return this.handleNoMatchedAction(renderContext, resolver);
|
|
249
264
|
}
|
|
250
|
-
|
|
251
|
-
for(const hook of this._hookList["
|
|
252
|
-
renderResult = await hook.hookFn(
|
|
265
|
+
}).then(async (renderResult: ResolverResponse):Promise<ResolverResponse> => {
|
|
266
|
+
for(const hook of this._hookList["completed"]){
|
|
267
|
+
renderResult = await hook.hookFn(renderResult);
|
|
253
268
|
}
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}).then(async (renderResult: ResolverResponse):Promise<ResolverResponse> => {
|
|
259
|
-
for(const hook of this._hookList["completed"]){
|
|
260
|
-
renderResult = await hook.hookFn(renderResult);
|
|
261
|
-
}
|
|
262
|
-
return renderResult;
|
|
263
|
-
}).catch(async (err: Error):Promise<ResolverResponse> => {
|
|
269
|
+
return renderResult;
|
|
270
|
+
});
|
|
271
|
+
}catch(err){
|
|
272
|
+
const wrappedError = err instanceof Error ? err : new Error("Error: " + String(err));
|
|
264
273
|
if(this.globalErrorHandler){
|
|
265
|
-
return this.globalErrorHandler(
|
|
274
|
+
return this.globalErrorHandler(wrappedError, eventRenderContext);
|
|
266
275
|
}
|
|
267
276
|
return { statusCode: 500, body: "Internal Server Error.", }
|
|
268
|
-
|
|
277
|
+
|
|
278
|
+
}
|
|
269
279
|
}
|
|
270
280
|
|
|
271
281
|
}
|