lambder 1.0.42 → 1.0.45

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 CHANGED
@@ -14,7 +14,10 @@ type Session = {
14
14
  };
15
15
  type RenderContext = {
16
16
  host: string;
17
- url: string;
17
+ path: string;
18
+ pathParams: {
19
+ [key: string]: any;
20
+ } | null;
18
21
  method: string;
19
22
  get: {
20
23
  [key: string]: any;
package/dist/Lambder.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import querystring from "querystring";
2
2
  import cookieParser from "cookie";
3
+ import { match } from "path-to-regexp";
3
4
  import Resolver from "./Resolver.js";
4
5
  import ResponseBuilder from "./ResponseBuilder.js";
5
6
  export const createContext = (event, lambdaContext) => {
6
7
  const host = event.headers.Host || event.headers.host || "";
7
- const url = event.path;
8
+ const path = event.path;
9
+ const pathParams = null;
8
10
  const get = event.queryStringParameters || {};
9
11
  const method = event.httpMethod;
10
12
  const cookie = cookieParser.parse(event.headers.Cookie || event.headers.cookie || "");
@@ -24,7 +26,7 @@ export const createContext = (event, lambdaContext) => {
24
26
  if (/^(((\d+\.)+\d+)|(([a-f\d]+:)+[a-f\d]+))$/.test(host)) {
25
27
  throw new Error("[404] Host cannot be an ip address: " + host);
26
28
  }
27
- return { host, url, method, get, post, cookie, headers, session, lambdaContext };
29
+ return { host, path, pathParams, method, get, post, cookie, headers, session, lambdaContext };
28
30
  };
29
31
  export default class Lambder {
30
32
  apiPath;
@@ -75,7 +77,7 @@ export default class Lambder {
75
77
  for (const hook of this.hookList["fallback"]) {
76
78
  await hook.hookFn(ctx, resolver);
77
79
  }
78
- const isAPI = ctx.url === this.apiPath;
80
+ const isAPI = ctx.path === this.apiPath;
79
81
  if (isAPI && this.apiFallbackHandler) {
80
82
  resolver.resolve(await this.apiFallbackHandler(ctx, resolver));
81
83
  }
@@ -86,7 +88,7 @@ export default class Lambder {
86
88
  resolver.resolve(await this.routeFallbackHandler(ctx, resolver));
87
89
  }
88
90
  else {
89
- resolver.resolve({ statusCode: 204, body: "Handler not set.", });
91
+ resolver.resolve({ statusCode: 204, body: "Route handler not set.", });
90
92
  }
91
93
  }
92
94
  async addModule(moduleFn) {
@@ -95,23 +97,37 @@ export default class Lambder {
95
97
  addRoute(condition, actionFn) {
96
98
  this.actionList.push({
97
99
  conditionFn: (ctx) => (ctx.method === "GET" &&
98
- ((typeof condition === "string" && ctx.url === condition) ||
100
+ ((typeof condition === "string" && ctx.path === condition) ||
99
101
  (typeof condition === "function" && condition(ctx)) ||
100
- (condition?.constructor == RegExp && condition.test(ctx.url)))),
101
- actionFn: async (ctx, resolver) => await actionFn(ctx, resolver)
102
+ (condition?.constructor == RegExp && condition.test(ctx.path)))),
103
+ actionFn: async (ctx, resolver) => {
104
+ if (typeof condition === "string") {
105
+ ctx.pathParams = (match(condition))(ctx.path) || {};
106
+ }
107
+ else if (condition?.constructor == RegExp) {
108
+ ctx.pathParams = ctx.path.match(condition);
109
+ }
110
+ return await actionFn(ctx, resolver);
111
+ }
102
112
  });
103
113
  }
104
114
  ;
105
115
  addSessionRoute(condition, actionFn) {
106
116
  this.actionList.push({
107
117
  conditionFn: (ctx) => (ctx.method === "GET" &&
108
- ((typeof condition === "string" && ctx.url === condition) ||
118
+ ((typeof condition === "string" && ctx.path === condition) ||
109
119
  (typeof condition === "function" && condition(ctx)) ||
110
- (condition?.constructor == RegExp && condition.test(ctx.url)))),
120
+ (condition?.constructor == RegExp && condition.test(ctx.path)))),
111
121
  actionFn: async (ctx, resolver) => {
112
122
  const isSessionValid = this.validateSession(ctx.session);
113
123
  if (!isSessionValid)
114
124
  throw new Error("Session not found");
125
+ if (typeof condition === "string") {
126
+ ctx.pathParams = (match(condition))(ctx.path) || {};
127
+ }
128
+ else if (condition?.constructor == RegExp) {
129
+ ctx.pathParams = ctx.path.match(condition);
130
+ }
115
131
  return await actionFn(ctx, resolver);
116
132
  }
117
133
  });
@@ -119,7 +135,7 @@ export default class Lambder {
119
135
  ;
120
136
  addApi(condition, actionFn) {
121
137
  this.actionList.push({
122
- conditionFn: (ctx) => (ctx.method === "POST" && ctx.url === this.apiPath &&
138
+ conditionFn: (ctx) => (ctx.method === "POST" && ctx.path === this.apiPath &&
123
139
  ((typeof condition === "string" && ctx.post?.api === condition) ||
124
140
  (typeof condition === "function" && condition(ctx)) ||
125
141
  (condition?.constructor == RegExp && condition.test(ctx.post?.api)))),
@@ -129,7 +145,7 @@ export default class Lambder {
129
145
  ;
130
146
  addSessionApi(condition, actionFn) {
131
147
  this.actionList.push({
132
- conditionFn: (ctx) => (ctx.method === "POST" && ctx.url === this.apiPath &&
148
+ conditionFn: (ctx) => (ctx.method === "POST" && ctx.path === this.apiPath &&
133
149
  ((typeof condition === "string" && ctx.post?.api === condition) ||
134
150
  (typeof condition === "function" && condition(ctx)) ||
135
151
  (condition?.constructor == RegExp && condition.test(ctx.post?.api)))),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lambder",
3
- "version": "1.0.42",
3
+ "version": "1.0.45",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -24,6 +24,7 @@
24
24
  "@types/js-cookie": "^3.0.6",
25
25
  "@types/mime-types": "^2.1.4",
26
26
  "@types/node": "^20.11.27",
27
+ "@types/path-to-regexp": "^1.7.0",
27
28
  "@typescript-eslint/eslint-plugin": "^7.2.0",
28
29
  "@typescript-eslint/parser": "^7.2.0",
29
30
  "eslint": "^8.57.0",
package/src/Lambder.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import querystring from "querystring";
2
2
  import cookieParser from "cookie";
3
+ import { match } from "path-to-regexp";
3
4
 
4
5
  import type { APIGatewayProxyEvent, APIGatewayProxyEventHeaders, Context } from "aws-lambda";
5
6
  import Resolver from "./Resolver.js";
@@ -17,7 +18,8 @@ type Session = {
17
18
 
18
19
  type RenderContext = {
19
20
  host: string;
20
- url: string;
21
+ path: string;
22
+ pathParams: { [key: string]: any } | null;
21
23
  method: string;
22
24
  get: { [key: string]: any };
23
25
  post: { [key: string]: any };
@@ -52,7 +54,8 @@ export const createContext = (
52
54
  lambdaContext: Context,
53
55
  ):RenderContext => {
54
56
  const host = event.headers.Host || event.headers.host || "";
55
- const url = event.path;
57
+ const path = event.path;
58
+ const pathParams = null;
56
59
  const get: { [key:string]: any } = event.queryStringParameters || {};
57
60
  const method = event.httpMethod;
58
61
  const cookie = cookieParser.parse(event.headers.Cookie || event.headers.cookie || "");
@@ -65,7 +68,7 @@ export const createContext = (
65
68
  catch(e){ post = querystring.parse(decodedBody) || {}; }
66
69
  }catch(e){}
67
70
  if(/^(((\d+\.)+\d+)|(([a-f\d]+:)+[a-f\d]+))$/.test(host)){ throw new Error("[404] Host cannot be an ip address: " + host); }
68
- return { host, url, method, get, post, cookie, headers, session, lambdaContext };
71
+ return { host, path, pathParams, method, get, post, cookie, headers, session, lambdaContext };
69
72
  }
70
73
 
71
74
 
@@ -126,7 +129,7 @@ export default class Lambder {
126
129
  private async handleNoMatchedAction(ctx: RenderContext, resolver: Resolver){
127
130
  for(const hook of this.hookList["fallback"]){ await hook.hookFn(ctx, resolver); }
128
131
 
129
- const isAPI = ctx.url === this.apiPath;
132
+ const isAPI = ctx.path === this.apiPath;
130
133
  if(isAPI && this.apiFallbackHandler){
131
134
  resolver.resolve(await this.apiFallbackHandler(ctx, resolver));
132
135
  }else if(isAPI){
@@ -134,7 +137,7 @@ export default class Lambder {
134
137
  }else if(this.routeFallbackHandler){
135
138
  resolver.resolve(await this.routeFallbackHandler(ctx, resolver));
136
139
  }else{
137
- resolver.resolve({ statusCode: 204, body: "Handler not set.", })
140
+ resolver.resolve({ statusCode: 204, body: "Route handler not set.", })
138
141
  }
139
142
  }
140
143
 
@@ -146,12 +149,19 @@ export default class Lambder {
146
149
  conditionFn: (ctx:RenderContext) => (
147
150
  ctx.method === "GET" &&
148
151
  (
149
- (typeof condition === "string" && ctx.url === condition) ||
152
+ (typeof condition === "string" && ctx.path === condition) ||
150
153
  (typeof condition === "function" && condition(ctx)) ||
151
- (condition?.constructor == RegExp && condition.test(ctx.url))
154
+ (condition?.constructor == RegExp && condition.test(ctx.path))
152
155
  )
153
156
  ),
154
- actionFn: async (ctx:RenderContext, resolver: Resolver) => await actionFn(ctx, resolver)
157
+ actionFn: async (ctx:RenderContext, resolver: Resolver) => {
158
+ if(typeof condition === "string"){
159
+ ctx.pathParams = (match(condition))(ctx.path) || {};
160
+ }else if(condition?.constructor == RegExp){
161
+ ctx.pathParams = ctx.path.match(condition);
162
+ }
163
+ return await actionFn(ctx, resolver);
164
+ }
155
165
  });
156
166
  };
157
167
 
@@ -160,14 +170,19 @@ export default class Lambder {
160
170
  conditionFn: (ctx:RenderContext) => (
161
171
  ctx.method === "GET" &&
162
172
  (
163
- (typeof condition === "string" && ctx.url === condition) ||
173
+ (typeof condition === "string" && ctx.path === condition) ||
164
174
  (typeof condition === "function" && condition(ctx)) ||
165
- (condition?.constructor == RegExp && condition.test(ctx.url))
175
+ (condition?.constructor == RegExp && condition.test(ctx.path))
166
176
  )
167
177
  ),
168
178
  actionFn: async (ctx:RenderContext, resolver: Resolver) => {
169
179
  const isSessionValid = this.validateSession(ctx.session);
170
180
  if(!isSessionValid) throw new Error("Session not found");
181
+ if(typeof condition === "string"){
182
+ ctx.pathParams = (match(condition))(ctx.path) || {};
183
+ }else if(condition?.constructor == RegExp){
184
+ ctx.pathParams = ctx.path.match(condition);
185
+ }
171
186
  return await actionFn(ctx, resolver);
172
187
  }
173
188
  });
@@ -176,7 +191,7 @@ export default class Lambder {
176
191
  addApi(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
177
192
  this.actionList.push({
178
193
  conditionFn: (ctx:RenderContext) => (
179
- ctx.method === "POST" && ctx.url === this.apiPath &&
194
+ ctx.method === "POST" && ctx.path === this.apiPath &&
180
195
  (
181
196
  (typeof condition === "string" && ctx.post?.api === condition) ||
182
197
  (typeof condition === "function" && condition(ctx)) ||
@@ -190,7 +205,7 @@ export default class Lambder {
190
205
  addSessionApi(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
191
206
  this.actionList.push({
192
207
  conditionFn: (ctx:RenderContext) => (
193
- ctx.method === "POST" && ctx.url === this.apiPath &&
208
+ ctx.method === "POST" && ctx.path === this.apiPath &&
194
209
  (
195
210
  (typeof condition === "string" && ctx.post?.api === condition) ||
196
211
  (typeof condition === "function" && condition(ctx)) ||