lambder 1.0.0 → 1.0.2

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/deploy.sh ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/bash
2
+
3
+ # Exit immediately if a command exits with a non-zero status.
4
+ set -e
5
+
6
+ # Update the version, build the project, and publish
7
+ npm version patch
8
+ npm run build
9
+ npm publish
10
+
11
+ echo "All operations completed successfully"
@@ -0,0 +1,94 @@
1
+ export type ResolverResponse = {
2
+ statusCode: number;
3
+ multiValueHeaders?: {
4
+ [key: string]: string[];
5
+ };
6
+ body: string | null;
7
+ isBase64Encoded?: boolean;
8
+ [key: string]: any;
9
+ };
10
+ interface IResolverMethods {
11
+ raw(param: {
12
+ statusCode: number;
13
+ isBase64Encoded?: boolean;
14
+ body: null | string;
15
+ multiValueHeaders: {
16
+ [key: string]: string[];
17
+ };
18
+ }): any;
19
+ json(data: {
20
+ [key: string]: any;
21
+ }, headers?: {
22
+ [key: string]: string | string[];
23
+ }): any;
24
+ xml(data: string): any;
25
+ html(data: string, headers?: {
26
+ [key: string]: string | string[];
27
+ }): any;
28
+ status301(url: string, headers?: {
29
+ [key: string]: string | string[];
30
+ }): any;
31
+ status404(data: string, headers?: {
32
+ [key: string]: string | string[];
33
+ }): any;
34
+ cors(): any;
35
+ fileBase64(fileBase64: string, mimeType: string, headers?: {
36
+ [key: string]: string | string[];
37
+ }): any;
38
+ file(filePath: string, headers?: {
39
+ [key: string]: string | string[];
40
+ }): any;
41
+ api({ payload, error, ...other }: {
42
+ payload?: any;
43
+ error?: any;
44
+ [key: string]: any;
45
+ }, headers?: {
46
+ [key: string]: string | string[];
47
+ }): any;
48
+ }
49
+ export default class Resolver {
50
+ private isCorsEnabled;
51
+ private publicPath;
52
+ private apiVersion;
53
+ resolve: Function;
54
+ reject: Function;
55
+ die: Partial<IResolverMethods>;
56
+ constructor({ isCorsEnabled, publicPath, apiVersion, resolve, reject }: {
57
+ isCorsEnabled: boolean;
58
+ publicPath: string;
59
+ apiVersion?: string | null;
60
+ resolve: (renderResult: ResolverResponse) => void;
61
+ reject: (err: Error) => void;
62
+ });
63
+ private readFileSync;
64
+ raw(param: ResolverResponse): ResolverResponse;
65
+ json(data: {
66
+ [key: string]: any;
67
+ }, headers?: {
68
+ [key: string]: string | string[];
69
+ }): ResolverResponse;
70
+ xml(data: string): ResolverResponse;
71
+ html(data: string, headers?: {
72
+ [key: string]: string | string[];
73
+ }): ResolverResponse;
74
+ status301(url: string, headers?: {
75
+ [key: string]: string | string[];
76
+ }): ResolverResponse;
77
+ status404(data: string, headers?: {
78
+ [key: string]: string | string[];
79
+ }): ResolverResponse;
80
+ cors(): ResolverResponse;
81
+ fileBase64(fileBase64: string, mimeType: string, headers?: {
82
+ [key: string]: string | string[];
83
+ }): ResolverResponse;
84
+ file(filePath: string, headers?: {
85
+ [key: string]: string | string[];
86
+ }): ResolverResponse;
87
+ api({ payload, error, ...other }: {
88
+ payload?: any;
89
+ error?: any;
90
+ }, headers?: {
91
+ [key: string]: string | string[];
92
+ }): ResolverResponse;
93
+ }
94
+ export {};
@@ -0,0 +1,135 @@
1
+ import fs from "fs";
2
+ import * as pathLibrary from "path";
3
+ import mimeTypeResolver from "mime-types";
4
+ const convertToMultiHeader = (headers) => Object.fromEntries(Object.entries(headers || {}).map(([k, v]) => [k, Array.isArray(v) ? v : [v]]));
5
+ const CORS_HEADERS = convertToMultiHeader({
6
+ "Access-Control-Allow-Credentials": "true",
7
+ "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
8
+ "Access-Control-Allow-Origin": "*",
9
+ "Access-Control-Allow-Methods": "OPTIONS,POST",
10
+ });
11
+ export default class Resolver {
12
+ isCorsEnabled;
13
+ publicPath;
14
+ apiVersion;
15
+ resolve;
16
+ reject;
17
+ die;
18
+ constructor({ isCorsEnabled, publicPath, apiVersion, resolve, reject }) {
19
+ this.isCorsEnabled = isCorsEnabled;
20
+ this.publicPath = publicPath;
21
+ this.apiVersion = apiVersion ?? null;
22
+ this.resolve = resolve;
23
+ this.reject = reject;
24
+ this.die = new Proxy(this, {
25
+ get: (target, prop) => {
26
+ const origProp = target[prop];
27
+ if (typeof origProp === 'function') {
28
+ return (...args) => {
29
+ this.resolve(origProp.apply(this, args));
30
+ };
31
+ }
32
+ return origProp;
33
+ }
34
+ });
35
+ }
36
+ readFileSync(filePath) {
37
+ const __dirname = pathLibrary.resolve(pathLibrary.dirname(""));
38
+ const absolutePath = pathLibrary.resolve(filePath);
39
+ const publicPath = pathLibrary.resolve(this.publicPath);
40
+ if (!absolutePath.includes(publicPath)) {
41
+ return "forbiddenpath";
42
+ }
43
+ return fs.readFileSync(filePath);
44
+ }
45
+ ;
46
+ raw(param) {
47
+ return param;
48
+ }
49
+ ;
50
+ json(data, headers) {
51
+ return this.raw({
52
+ statusCode: 200,
53
+ multiValueHeaders: {
54
+ "Content-Type": ["application/json; charset=utf-8"],
55
+ ...(this.isCorsEnabled ? CORS_HEADERS : {}),
56
+ ...convertToMultiHeader(headers)
57
+ },
58
+ body: JSON.stringify(data),
59
+ });
60
+ }
61
+ xml(data) {
62
+ return this.raw({
63
+ statusCode: 200,
64
+ isBase64Encoded: true,
65
+ multiValueHeaders: { "Content-Type": ["application/xml; charset=utf-8"] },
66
+ body: Buffer.from(data).toString("base64"),
67
+ });
68
+ }
69
+ ;
70
+ html(data, headers) {
71
+ return this.raw({
72
+ statusCode: 200,
73
+ isBase64Encoded: true,
74
+ multiValueHeaders: { "Content-Type": ["text/html; charset=utf-8"], ...convertToMultiHeader(headers) },
75
+ body: Buffer.from(data).toString("base64"),
76
+ });
77
+ }
78
+ ;
79
+ status301(url, headers) {
80
+ return this.raw({
81
+ statusCode: 301,
82
+ multiValueHeaders: { "Location": [url], ...convertToMultiHeader(headers) },
83
+ body: null
84
+ });
85
+ }
86
+ ;
87
+ status404(data, headers) {
88
+ return this.raw({
89
+ statusCode: 404,
90
+ isBase64Encoded: true,
91
+ multiValueHeaders: { "Content-Type": ["text/html; charset=utf-8"], ...convertToMultiHeader(headers) },
92
+ body: Buffer.from(data).toString("base64"),
93
+ });
94
+ }
95
+ ;
96
+ cors() {
97
+ return this.raw({
98
+ statusCode: 200,
99
+ multiValueHeaders: this.isCorsEnabled ? CORS_HEADERS : {},
100
+ body: JSON.stringify(""),
101
+ });
102
+ }
103
+ ;
104
+ fileBase64(fileBase64, mimeType, headers) {
105
+ return this.raw({
106
+ statusCode: 200,
107
+ isBase64Encoded: true,
108
+ multiValueHeaders: { "Content-Type": [mimeType || "text/html"], ...convertToMultiHeader(headers) },
109
+ body: fileBase64,
110
+ });
111
+ }
112
+ ;
113
+ file(filePath, headers) {
114
+ if (!fs.existsSync(filePath))
115
+ return this.json({ error: "File not found: " + filePath });
116
+ const mimeType = mimeTypeResolver.lookup(filePath);
117
+ const body = this.readFileSync(filePath);
118
+ const bodyBase64 = Buffer.from(body).toString("base64");
119
+ console.log("bodyBase64.length", bodyBase64.length);
120
+ return this.fileBase64(bodyBase64, mimeType || "", headers);
121
+ }
122
+ ;
123
+ api({ payload, error = null, ...other }, headers) {
124
+ if (error)
125
+ console.log("ERROR: ", error);
126
+ if (Object.keys(other).length)
127
+ console.log("ERROR: Unexpected key in result: " + Object.keys(other).join(", "));
128
+ return this.json({
129
+ apiVersion: this.apiVersion,
130
+ payload,
131
+ ...(error ? { error } : {}),
132
+ }, headers);
133
+ }
134
+ ;
135
+ }
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import type { APIGatewayProxyEvent, Context } from "aws-lambda";
2
- export declare const resolveEvent: (event: APIGatewayProxyEvent, resolve: any, reject: any) => {
1
+ import type { APIGatewayProxyEvent, APIGatewayProxyEventHeaders, Context } from "aws-lambda";
2
+ import Resolver, { ResolverResponse } from "./Resolver";
3
+ type RawResolvedContext = {
3
4
  host: string;
4
- realHost: string;
5
5
  url: string;
6
6
  method: string;
7
7
  get: {
@@ -10,27 +10,49 @@ export declare const resolveEvent: (event: APIGatewayProxyEvent, resolve: any, r
10
10
  post: {
11
11
  [key: string]: any;
12
12
  };
13
- cookie: any;
14
- headers: import("aws-lambda").APIGatewayProxyEventHeaders;
13
+ cookie: {
14
+ [key: string]: any;
15
+ };
16
+ headers: APIGatewayProxyEventHeaders;
17
+ };
18
+ type RenderContext = RawResolvedContext & {
19
+ runContext: Context;
20
+ resolver: Resolver;
15
21
  };
16
- declare const hookTypeList: readonly ["beforeRender", "afterRender", "created", "completed", "fallback"];
17
- type HookType = typeof hookTypeList[number];
22
+ type ConditionFunction = (renderContext: RenderContext) => boolean | Promise<boolean>;
23
+ type ActionFunction = (renderContext: RenderContext) => ResolverResponse | Promise<ResolverResponse>;
24
+ type HookCreatedFunction = (lambderInstance: Lambder) => Promise<void>;
25
+ type HookBeforeRenderFunction = (renderContext: RenderContext) => Promise<void>;
26
+ type HookAfterRenderFunction = (renderContext: RenderContext, renderResult: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
27
+ type HookFallbackFunction = (renderContext: RenderContext) => ResolverResponse | Promise<ResolverResponse>;
28
+ type HookCompletedFunction = (renderResult: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
29
+ export declare const resolveEvent: (event: APIGatewayProxyEvent, resolve: Function, reject: Function) => RawResolvedContext;
18
30
  export default class Lambder {
19
- apiPath: string;
20
- corsEnabled: boolean;
31
+ private apiPath;
32
+ private apiVersion;
33
+ private isCorsEnabled;
34
+ private publicPath;
21
35
  private _actionList;
22
36
  private _hookList;
23
- constructor({ apiPath, corsEnabled }: {
37
+ private globalErrorHandler;
38
+ constructor({ apiPath, apiVersion, isCorsEnabled, publicPath }: {
24
39
  apiPath?: string;
25
- corsEnabled?: boolean;
40
+ apiVersion?: string;
41
+ isCorsEnabled?: boolean;
42
+ publicPath: string;
26
43
  });
27
44
  private apiHandler;
28
45
  private pathHandler;
29
46
  private fallbackHandler;
30
- addApi(condition: string | Function | RegExp, actionFn: Function): number;
31
- addPath(condition: string | Function | RegExp, actionFn: Function): number;
32
- addHook(when: HookType, hookFn: Function, priority?: number): Promise<void>;
33
- addModule(moduleFn: any): Promise<void>;
34
- render(event: APIGatewayProxyEvent, runContext: Context): Promise<unknown>;
47
+ setGlobalErrorHandler(globalErrorHandler: (err: Error) => ResolverResponse): void;
48
+ addApi(condition: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
49
+ addPath(condition: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
50
+ addHook(hookEvent: 'created', hookFn: HookCreatedFunction, priority?: number): Promise<void>;
51
+ addHook(hookEvent: 'beforeRender', hookFn: HookBeforeRenderFunction, priority?: number): Promise<void>;
52
+ addHook(hookEvent: 'afterRender', hookFn: HookAfterRenderFunction, priority?: number): Promise<void>;
53
+ addHook(hookEvent: 'fallback', hookFn: HookFallbackFunction, priority?: number): Promise<void>;
54
+ addHook(hookEvent: 'completed', hookFn: HookCompletedFunction, priority?: number): Promise<void>;
55
+ addModule(moduleFn: Function): Promise<void>;
56
+ render(event: APIGatewayProxyEvent, runContext: Context): Promise<ResolverResponse>;
35
57
  }
36
58
  export {};
package/dist/index.js CHANGED
@@ -1,29 +1,14 @@
1
- import fs from "fs";
2
- import * as pathLibrary from "path";
3
1
  import querystring from "querystring";
4
2
  import cookieParser from "cookie";
5
- const readFileSync = (filePath) => {
6
- const __dirname = pathLibrary.resolve(pathLibrary.dirname(""));
7
- const absolutePath = pathLibrary.resolve(filePath);
8
- const publicPath = pathLibrary.resolve(`${__dirname}/www/`);
9
- if (!absolutePath.includes(publicPath)) {
10
- return "forbiddenpath";
11
- }
12
- return fs.readFileSync(filePath);
13
- };
14
- // export const millisecondCounter = (startTime = 0) => {
15
- // const time = process.hrtime();
16
- // return Number((time[0] + (time[1] / 1e9) - startTime).toFixed(3));
17
- // };
3
+ import Resolver from "./Resolver";
18
4
  export const resolveEvent = (event, resolve, reject) => {
19
- const realHost = event.headers.Host || event.headers.host || "";
20
- const host = realHost.replace(/^(\S+)--([a-z]+)\.beta00\.com$/, "$1.$2.com").replace(".beta00.com", ".com");
5
+ const host = event.headers.Host || event.headers.host || "";
21
6
  const url = event.path;
22
7
  const get = event.queryStringParameters || {};
23
8
  const method = event.httpMethod;
24
9
  const cookie = cookieParser.parse(event.headers.Cookie || event.headers.cookie || "");
25
10
  const headers = event.headers;
26
- let post;
11
+ let post = {};
27
12
  try {
28
13
  const decodedBody = event.isBase64Encoded ? (event.body ? Buffer.from(event.body, "base64").toString() : "{}") : (event.body || "{}");
29
14
  try {
@@ -33,64 +18,25 @@ export const resolveEvent = (event, resolve, reject) => {
33
18
  post = querystring.parse(decodedBody) || {};
34
19
  }
35
20
  }
36
- catch (e) {
37
- post = {};
38
- }
21
+ catch (e) { }
39
22
  if (/^(((\d+\.)+\d+)|(([a-f\d]+:)+[a-f\d]+))$/.test(host)) {
40
- reject("[404] Host cannot be an ip address: " + host);
23
+ reject(new Error("[404] Host cannot be an ip address: " + host));
41
24
  }
42
- return { host, realHost, url, method, get, post, cookie, headers };
25
+ return { host, url, method, get, post, cookie, headers };
43
26
  };
44
- // const parseHeader = (
45
- // headers: { [key:string]: string|string[] } | undefined
46
- // ):{ [key:string]: string[] } =>
47
- // Object.fromEntries(Object.entries(headers||{}).map(([k,v])=>[ k, Array.isArray(v) ? v : [v] ]));
48
- // const CORS_HEADERS = parseHeader({
49
- // "Access-Control-Allow-Credentials": "true",
50
- // "Access-Control-Allow-Headers" : "Origin, X-Requested-With, Content-Type, Accept",
51
- // "Access-Control-Allow-Origin": "*",
52
- // "Access-Control-Allow-Methods": "OPTIONS,POST",
53
- // });
54
- // export const dieRaw = (param: { body: null|string, statusCode: number, multiValueHeaders: {[key:string]: string[] }, isBase64Encoded?: boolean }) => { console.log("HandlerEnd: " + millisecondCounter() + " Size: " + (param.body || {}).length ); return param; };
55
- // export const dieJson = (data: { [key:string]: any }|string, headers?: { [key:string]: string|string[] }) => dieRaw({statusCode: 200,multiValueHeaders: { "Content-Type": ["application/json; charset=utf-8"], ...CORS_HEADERS, ...parseHeader(headers)},body: JSON.stringify(data),});
56
- // export const dieXml = (data: string) => dieRaw({statusCode: 200,isBase64Encoded: true,multiValueHeaders: { "Content-Type": ["application/xml; charset=utf-8"]}, body: Buffer.from(data).toString("base64"),});
57
- // export const dieHtml = (data: string, headers?: { [key:string]: string|string[] }) => dieRaw({statusCode: 200,isBase64Encoded: true,multiValueHeaders: {"Content-Type": ["text/html; charset=utf-8"], ...parseHeader(headers)},body: Buffer.from(data).toString("base64"),});
58
- // export const die301 = (url: string, headers?: { [key:string]: string|string[] }) => dieRaw({statusCode: 301, multiValueHeaders: { "Location" : [url], ...parseHeader(headers) },body:null});
59
- // export const die404 = (data: string,headers?: { [key:string]: string|string[] }) => dieRaw({statusCode: 404,isBase64Encoded: true,multiValueHeaders: {"Content-Type": ["text/html; charset=utf-8"], ...parseHeader(headers)},body: Buffer.from(data).toString("base64"),});
60
- // export const dieCors = () => dieRaw({ statusCode: 200,multiValueHeaders: CORS_HEADERS,body: JSON.stringify(""),});
61
- // export const dieFileBase64 = async (fileBase64: string, mimeType: string, headers?: { [key:string]: string|string[] }) => dieRaw({ statusCode: 200, isBase64Encoded: true, multiValueHeaders: { "Content-Type": [mimeType || "text/html"], ...parseHeader(headers) }, body: fileBase64, });
62
- // export const dieFile = async (file: string, headers?: { [key:string]: string|string[] }) => {
63
- // if(!fs.existsSync(file)) return dieJson("File not found: " + file );
64
- // const mimeType = mimeTypeResolver.lookup(file);
65
- // const body = readFileSync(file);
66
- // const bodyBase64 = Buffer.from(body).toString("base64");
67
- // console.log("bodyBase64.length",bodyBase64.length);
68
- // return dieFileBase64(bodyBase64, mimeType || "", headers);
69
- // };
70
- // export const dieApi = ({
71
- // payload, error=null,
72
- // ...other
73
- // }: {
74
- // payload?: any;
75
- // error?: any;
76
- // }, headers?: { [key:string]: string|string[] })=>{
77
- // if(error) console.log("ERROR: ", error);
78
- // if(Object.keys(other).length) console.log("ERROR: Unexpected key in result: " + Object.keys(other).join(", "));
79
- // return dieJson({
80
- // version: lambdaConfig.version,
81
- // payload,
82
- // ...(error ? {error} : {}),
83
- // },headers);
84
- // }
85
- const hookTypeList = ["beforeRender", "afterRender", "created", "completed", "fallback"];
86
27
  export default class Lambder {
87
28
  apiPath;
88
- corsEnabled;
29
+ apiVersion;
30
+ isCorsEnabled;
31
+ publicPath;
89
32
  _actionList;
90
33
  _hookList;
91
- constructor({ apiPath, corsEnabled }) {
34
+ globalErrorHandler = null;
35
+ constructor({ apiPath, apiVersion, isCorsEnabled, publicPath }) {
92
36
  this.apiPath = apiPath ?? "/api";
93
- this.corsEnabled = corsEnabled ?? true;
37
+ this.apiVersion = apiVersion ?? null;
38
+ this.isCorsEnabled = isCorsEnabled ?? false;
39
+ this.publicPath = publicPath || "/incorrect-path-not-found";
94
40
  this._actionList = [];
95
41
  this._hookList = {
96
42
  "beforeRender": [],
@@ -99,16 +45,19 @@ export default class Lambder {
99
45
  "completed": []
100
46
  };
101
47
  }
102
- async apiHandler(context, actionFn) {
48
+ async apiHandler(renderContext, actionFn) {
103
49
  // Do context stuff;
104
- return await actionFn(context);
50
+ return await actionFn(renderContext);
105
51
  }
106
- async pathHandler(context, actionFn) {
52
+ async pathHandler(renderContext, actionFn) {
107
53
  // Do context stuff;
108
- return await actionFn(context);
54
+ return await actionFn(renderContext);
109
55
  }
110
- async fallbackHandler(context) {
111
- return die404("Not Found");
56
+ async fallbackHandler(renderContext) {
57
+ return renderContext.resolver.file("index.html");
58
+ }
59
+ setGlobalErrorHandler(globalErrorHandler) {
60
+ this.globalErrorHandler = globalErrorHandler;
112
61
  }
113
62
  addApi(condition, actionFn) {
114
63
  let conditionFn = (renderContext) => false;
@@ -116,7 +65,7 @@ export default class Lambder {
116
65
  conditionFn = (renderContext) => renderContext.url === this.apiPath && (renderContext.post?.api) === condition;
117
66
  }
118
67
  else if (typeof condition === "function") {
119
- conditionFn = (renderContext) => renderContext.url === this.apiPath && condition(renderContext);
68
+ conditionFn = async (renderContext) => renderContext.url === this.apiPath && (await condition(renderContext));
120
69
  }
121
70
  else if (condition?.constructor == RegExp) {
122
71
  conditionFn = (renderContext) => renderContext.url === this.apiPath && condition.test(renderContext.post?.api);
@@ -124,7 +73,7 @@ export default class Lambder {
124
73
  else {
125
74
  throw "Unsupported API Condition";
126
75
  }
127
- return this._actionList.push({
76
+ this._actionList.push({
128
77
  conditionFn,
129
78
  actionFn: async (renderContext) => await this.apiHandler(renderContext, actionFn)
130
79
  });
@@ -135,7 +84,7 @@ export default class Lambder {
135
84
  conditionFn = (renderContext) => renderContext.url === condition;
136
85
  }
137
86
  else if (typeof condition === "function") {
138
- conditionFn = (renderContext) => condition(renderContext);
87
+ conditionFn = async (renderContext) => (await condition(renderContext));
139
88
  }
140
89
  else if (condition?.constructor == RegExp) {
141
90
  conditionFn = (renderContext) => condition.test(renderContext.url);
@@ -143,18 +92,18 @@ export default class Lambder {
143
92
  else {
144
93
  throw "Unsupported Path Condition";
145
94
  }
146
- return this._actionList.push({
95
+ this._actionList.push({
147
96
  conditionFn,
148
97
  actionFn: async (renderContext) => await this.pathHandler(renderContext, actionFn)
149
98
  });
150
99
  }
151
- async addHook(when, hookFn, priority = 0) {
152
- if (when === "created") {
100
+ async addHook(hookEvent, hookFn, priority = 0) {
101
+ if (hookEvent === "created") {
153
102
  await hookFn(this);
154
103
  }
155
104
  else {
156
- this._hookList[when].push({ priority, hookFn });
157
- this._hookList[when].sort((a, b) => a.priority - b.priority);
105
+ this._hookList[hookEvent].push({ priority, hookFn });
106
+ this._hookList[hookEvent].sort((a, b) => a.priority - b.priority);
158
107
  }
159
108
  }
160
109
  async addModule(moduleFn) {
@@ -162,10 +111,16 @@ export default class Lambder {
162
111
  }
163
112
  async render(event, runContext) {
164
113
  return await new Promise(async (resolve, reject) => {
114
+ const resolver = new Resolver({
115
+ isCorsEnabled: this.isCorsEnabled,
116
+ publicPath: this.publicPath,
117
+ apiVersion: this.apiVersion,
118
+ resolve, reject,
119
+ });
165
120
  const eventContext = resolveEvent(event, resolve, reject);
166
- const renderContext = { ...eventContext, runContext, resolve, reject };
121
+ const renderContext = { ...eventContext, runContext, resolver };
167
122
  if (renderContext.method === "OPTIONS")
168
- return dieCors();
123
+ return resolver.cors();
169
124
  let firstMatchedAction = null;
170
125
  for (const action of this._actionList) {
171
126
  const isConditionMet = await action.conditionFn(renderContext);
@@ -189,8 +144,16 @@ export default class Lambder {
189
144
  const renderResult = await this.fallbackHandler(renderContext);
190
145
  resolve(renderResult);
191
146
  }
147
+ }).then(async (renderResult) => {
148
+ for (const hook of this._hookList["completed"]) {
149
+ renderResult = await hook.hookFn(renderResult);
150
+ }
151
+ return renderResult;
152
+ }).catch(async (err) => {
153
+ if (this.globalErrorHandler) {
154
+ return this.globalErrorHandler(err);
155
+ }
156
+ return { statusCode: 501, body: "Unknown Server Error", };
192
157
  });
193
- for (const hook of this._hookList["completed"])
194
- await hook.hookFn(promiseResult);
195
158
  }
196
159
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lambder",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",