lambder 1.0.40 → 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 +9 -9
- package/dist/Lambder.js +35 -35
- package/package.json +1 -1
- package/src/Lambder.ts +49 -48
package/dist/Lambder.d.ts
CHANGED
|
@@ -29,16 +29,16 @@ type RenderContext = {
|
|
|
29
29
|
session: DDBSession;
|
|
30
30
|
lambdaContext: Context;
|
|
31
31
|
};
|
|
32
|
-
type ConditionFunction = (
|
|
33
|
-
type ActionFunction = (
|
|
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 = (
|
|
36
|
-
type HookAfterRenderFunction = (
|
|
37
|
-
type HookFallbackFunction = (
|
|
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,
|
|
40
|
-
type RouteFallbackHandlerFunction = (
|
|
41
|
-
type ApiFallbackHandlerFunction = (
|
|
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;
|
|
@@ -72,7 +72,7 @@ export default class Lambder {
|
|
|
72
72
|
addHook(hookEvent: 'fallback', hookFn: HookFallbackFunction, priority?: number): Promise<void>;
|
|
73
73
|
addHook(hookEvent: 'completed', hookFn: HookCompletedFunction, priority?: number): Promise<void>;
|
|
74
74
|
getResponseBuilder(): ResponseBuilder;
|
|
75
|
-
getResolver
|
|
75
|
+
private getResolver;
|
|
76
76
|
render(event: APIGatewayProxyEvent, lambdaContext: Context): Promise<ResolverResponse>;
|
|
77
77
|
}
|
|
78
78
|
export {};
|
package/dist/Lambder.js
CHANGED
|
@@ -71,20 +71,20 @@ export default class Lambder {
|
|
|
71
71
|
return false;
|
|
72
72
|
}
|
|
73
73
|
;
|
|
74
|
-
async handleNoMatchedAction(
|
|
74
|
+
async handleNoMatchedAction(ctx, resolver) {
|
|
75
75
|
for (const hook of this._hookList["fallback"]) {
|
|
76
|
-
await hook.hookFn(
|
|
76
|
+
await hook.hookFn(ctx, resolver);
|
|
77
77
|
}
|
|
78
|
-
if (
|
|
78
|
+
if (ctx.url === this.apiPath) {
|
|
79
79
|
if (this.apiFallbackHandler) {
|
|
80
|
-
resolver.resolve(await this.apiFallbackHandler(
|
|
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(
|
|
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 (
|
|
99
|
-
((typeof condition === "string" &&
|
|
100
|
-
(typeof condition === "function" && (await condition(
|
|
101
|
-
(condition?.constructor == RegExp && condition.test(
|
|
102
|
-
actionFn: async (
|
|
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 (
|
|
109
|
-
((typeof condition === "string" &&
|
|
110
|
-
(typeof condition === "function" && (await condition(
|
|
111
|
-
(condition?.constructor == RegExp && condition.test(
|
|
112
|
-
actionFn: async (
|
|
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 (
|
|
119
|
-
((typeof condition === "string" &&
|
|
120
|
-
(typeof condition === "function" && (await condition(
|
|
121
|
-
(condition?.constructor == RegExp && condition.test(
|
|
122
|
-
actionFn: async (
|
|
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 (
|
|
129
|
-
((typeof condition === "string" &&
|
|
130
|
-
(typeof condition === "function" && (await condition(
|
|
131
|
-
(condition?.constructor == RegExp && condition.test(
|
|
132
|
-
actionFn: async (
|
|
133
|
-
const isSessionValid = this.validateSession(
|
|
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(
|
|
136
|
+
return await actionFn(ctx, resolver);
|
|
137
137
|
}
|
|
138
138
|
});
|
|
139
139
|
}
|
|
@@ -167,30 +167,30 @@ export default class Lambder {
|
|
|
167
167
|
async render(event, lambdaContext) {
|
|
168
168
|
let eventRenderContext = null;
|
|
169
169
|
try {
|
|
170
|
-
let
|
|
171
|
-
eventRenderContext =
|
|
170
|
+
let ctx = createContext(event, lambdaContext);
|
|
171
|
+
eventRenderContext = ctx;
|
|
172
172
|
return await new Promise(async (resolve, reject) => {
|
|
173
173
|
const resolver = this.getResolver(resolve, reject);
|
|
174
|
-
if (
|
|
174
|
+
if (ctx.method === "OPTIONS")
|
|
175
175
|
return resolver.cors();
|
|
176
176
|
const firstMatchedAction = await (async () => {
|
|
177
177
|
for (const action of this._actionList) {
|
|
178
|
-
if (await action.conditionFn(
|
|
178
|
+
if (await action.conditionFn(ctx))
|
|
179
179
|
return action;
|
|
180
180
|
}
|
|
181
181
|
})();
|
|
182
182
|
if (firstMatchedAction) {
|
|
183
183
|
for (const hook of this._hookList["beforeRender"]) {
|
|
184
|
-
|
|
184
|
+
ctx = await hook.hookFn(ctx, resolver);
|
|
185
185
|
}
|
|
186
|
-
let renderResult = await firstMatchedAction.actionFn(
|
|
186
|
+
let renderResult = await firstMatchedAction.actionFn(ctx, resolver);
|
|
187
187
|
for (const hook of this._hookList["afterRender"]) {
|
|
188
|
-
renderResult = await hook.hookFn(
|
|
188
|
+
renderResult = await hook.hookFn(ctx, resolver, renderResult);
|
|
189
189
|
}
|
|
190
190
|
resolve(renderResult);
|
|
191
191
|
}
|
|
192
192
|
else {
|
|
193
|
-
return this.handleNoMatchedAction(
|
|
193
|
+
return this.handleNoMatchedAction(ctx, resolver);
|
|
194
194
|
}
|
|
195
195
|
}).then(async (renderResult) => {
|
|
196
196
|
for (const hook of this._hookList["completed"]) {
|
package/package.json
CHANGED
package/src/Lambder.ts
CHANGED
|
@@ -27,19 +27,19 @@ type RenderContext = {
|
|
|
27
27
|
lambdaContext: Context;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
type ConditionFunction = (
|
|
31
|
-
type ActionFunction = (
|
|
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 = (
|
|
36
|
-
type HookAfterRenderFunction = (
|
|
37
|
-
type HookFallbackFunction = (
|
|
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,
|
|
41
|
-
type RouteFallbackHandlerFunction = (
|
|
42
|
-
type ApiFallbackHandlerFunction = (
|
|
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(
|
|
126
|
+
private async handleNoMatchedAction(ctx: RenderContext, resolver: Resolver){
|
|
127
127
|
for(const hook of this._hookList["fallback"]){
|
|
128
|
-
await hook.hookFn(
|
|
128
|
+
await hook.hookFn(ctx, resolver);
|
|
129
129
|
}
|
|
130
|
-
if(
|
|
130
|
+
if(ctx.url === this.apiPath){
|
|
131
131
|
if(this.apiFallbackHandler){
|
|
132
|
-
resolver.resolve(await this.apiFallbackHandler(
|
|
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(
|
|
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 (
|
|
149
|
-
|
|
148
|
+
conditionFn: async (ctx:RenderContext) => (
|
|
149
|
+
ctx.method === "GET" &&
|
|
150
150
|
(
|
|
151
|
-
(typeof condition === "string" &&
|
|
152
|
-
(typeof condition === "function" && (await condition(
|
|
153
|
-
(condition?.constructor == RegExp && condition.test(
|
|
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 (
|
|
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 (
|
|
163
|
-
|
|
162
|
+
conditionFn: async (ctx:RenderContext) => (
|
|
163
|
+
ctx.method === "GET" && !!ctx.session &&
|
|
164
164
|
(
|
|
165
|
-
(typeof condition === "string" &&
|
|
166
|
-
(typeof condition === "function" && (await condition(
|
|
167
|
-
(condition?.constructor == RegExp && condition.test(
|
|
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 (
|
|
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 (
|
|
177
|
-
|
|
176
|
+
conditionFn: async (ctx:RenderContext) => (
|
|
177
|
+
ctx.method === "POST" && ctx.url === this.apiPath &&
|
|
178
178
|
(
|
|
179
|
-
(typeof condition === "string" &&
|
|
180
|
-
(typeof condition === "function" && (await condition(
|
|
181
|
-
(condition?.constructor == RegExp && condition.test(
|
|
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 (
|
|
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 (
|
|
191
|
-
|
|
190
|
+
conditionFn: async (ctx:RenderContext) => (
|
|
191
|
+
ctx.method === "POST" && ctx.url === this.apiPath && !!ctx.session &&
|
|
192
192
|
(
|
|
193
|
-
(typeof condition === "string" &&
|
|
194
|
-
(typeof condition === "function" && (await condition(
|
|
195
|
-
(condition?.constructor == RegExp && condition.test(
|
|
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 (
|
|
199
|
-
const isSessionValid = this.validateSession(
|
|
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(
|
|
201
|
+
return await actionFn(ctx, resolver);
|
|
202
202
|
}
|
|
203
203
|
});
|
|
204
204
|
};
|
|
@@ -230,7 +230,7 @@ export default class Lambder {
|
|
|
230
230
|
});
|
|
231
231
|
};
|
|
232
232
|
|
|
233
|
-
|
|
233
|
+
private getResolver(resolve: (renderResult: ResolverResponse) => void, reject: (err: Error) => void){
|
|
234
234
|
return new Resolver({
|
|
235
235
|
isCorsEnabled: this.isCorsEnabled,
|
|
236
236
|
publicPath: this.publicPath,
|
|
@@ -244,34 +244,35 @@ export default class Lambder {
|
|
|
244
244
|
lambdaContext: Context
|
|
245
245
|
): Promise<ResolverResponse>{
|
|
246
246
|
let eventRenderContext:RenderContext|null = null;
|
|
247
|
+
|
|
247
248
|
try {
|
|
248
|
-
let
|
|
249
|
-
eventRenderContext =
|
|
249
|
+
let ctx = createContext(event, lambdaContext);
|
|
250
|
+
eventRenderContext = ctx;
|
|
250
251
|
|
|
251
252
|
return await new Promise(async (
|
|
252
253
|
resolve:(renderResult: ResolverResponse)=>void,
|
|
253
254
|
reject:(err: Error)=>void
|
|
254
255
|
)=> {
|
|
255
256
|
const resolver = this.getResolver(resolve, reject);
|
|
256
|
-
if(
|
|
257
|
+
if(ctx.method === "OPTIONS") return resolver.cors();
|
|
257
258
|
|
|
258
259
|
const firstMatchedAction = await (async () => {
|
|
259
260
|
for(const action of this._actionList){
|
|
260
|
-
if(await action.conditionFn(
|
|
261
|
+
if(await action.conditionFn(ctx)) return action;
|
|
261
262
|
}
|
|
262
263
|
})();
|
|
263
264
|
|
|
264
265
|
if(firstMatchedAction){
|
|
265
266
|
for(const hook of this._hookList["beforeRender"]){
|
|
266
|
-
|
|
267
|
+
ctx = await hook.hookFn(ctx, resolver);
|
|
267
268
|
}
|
|
268
|
-
let renderResult = await firstMatchedAction.actionFn(
|
|
269
|
+
let renderResult = await firstMatchedAction.actionFn(ctx, resolver);
|
|
269
270
|
for(const hook of this._hookList["afterRender"]){
|
|
270
|
-
renderResult = await hook.hookFn(
|
|
271
|
+
renderResult = await hook.hookFn(ctx, resolver, renderResult);
|
|
271
272
|
}
|
|
272
273
|
resolve(renderResult);
|
|
273
274
|
}else{
|
|
274
|
-
return this.handleNoMatchedAction(
|
|
275
|
+
return this.handleNoMatchedAction(ctx, resolver);
|
|
275
276
|
}
|
|
276
277
|
}).then(async (renderResult: ResolverResponse):Promise<ResolverResponse> => {
|
|
277
278
|
for(const hook of this._hookList["completed"]){
|