lambder 1.0.29 → 1.0.36

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
@@ -1,5 +1,6 @@
1
1
  import type { APIGatewayProxyEvent, APIGatewayProxyEventHeaders, Context } from "aws-lambda";
2
- import Resolver, { ResolverResponse } from "./Resolver.js";
2
+ import Resolver from "./Resolver.js";
3
+ import ResolverLight, { ResolverResponse } from "./ResolverLight.js";
3
4
  type DDBSession = {
4
5
  userId: string;
5
6
  userIdHash: string;
@@ -35,6 +36,9 @@ type HookBeforeRenderFunction = (renderContext: RenderContext, resolver: Resolve
35
36
  type HookAfterRenderFunction = (renderContext: RenderContext, resolver: Resolver, renderResult: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
36
37
  type HookFallbackFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse | Promise<ResolverResponse>;
37
38
  type HookCompletedFunction = (renderResult: ResolverResponse) => ResolverResponse | Promise<ResolverResponse>;
39
+ type GlobalErrorHandlerFunction = (err: Error, renderContext: RenderContext | null, resolver: ResolverLight) => ResolverResponse | Promise<ResolverResponse>;
40
+ type RouteFallbackHandlerFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse;
41
+ type ApiFallbackHandlerFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse;
38
42
  export declare const createContext: (event: APIGatewayProxyEvent, lambdaContext: Context) => RenderContext;
39
43
  export default class Lambder {
40
44
  private apiPath;
@@ -52,9 +56,9 @@ export default class Lambder {
52
56
  apiVersion?: string;
53
57
  isCorsEnabled?: boolean;
54
58
  });
55
- setRouteFallbackHandler(routeFallbackHandler: (renderContext: RenderContext, resolver: Resolver) => ResolverResponse): void;
56
- setApiFallbackHandler(apiFallbackHandler: (renderContext: RenderContext, resolver: Resolver) => ResolverResponse): void;
57
- setGlobalErrorHandler(globalErrorHandler: (err: Error) => ResolverResponse): void;
59
+ setRouteFallbackHandler(routeFallbackHandler: RouteFallbackHandlerFunction): void;
60
+ setApiFallbackHandler(apiFallbackHandler: ApiFallbackHandlerFunction): void;
61
+ setGlobalErrorHandler(globalErrorHandler: GlobalErrorHandlerFunction): void;
58
62
  private validateSession;
59
63
  private handleNoMatchedAction;
60
64
  addModule(moduleFn: Function): Promise<void>;
package/dist/Lambder.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import querystring from "querystring";
2
2
  import cookieParser from "cookie";
3
3
  import Resolver from "./Resolver.js";
4
+ import ResolverLight from "./ResolverLight.js";
4
5
  export const createContext = (event, lambdaContext) => {
5
6
  const host = event.headers.Host || event.headers.host || "";
6
7
  const url = event.path;
@@ -147,14 +148,21 @@ export default class Lambder {
147
148
  }
148
149
  }
149
150
  async render(event, lambdaContext) {
151
+ let eventRenderContext = null;
152
+ const resolverLight = new ResolverLight({
153
+ isCorsEnabled: this.isCorsEnabled,
154
+ publicPath: this.publicPath,
155
+ apiVersion: this.apiVersion,
156
+ });
150
157
  try {
151
158
  let renderContext = createContext(event, lambdaContext);
159
+ eventRenderContext = renderContext;
152
160
  return await new Promise(async (resolve, reject) => {
153
161
  const resolver = new Resolver({
154
162
  isCorsEnabled: this.isCorsEnabled,
155
163
  publicPath: this.publicPath,
156
164
  apiVersion: this.apiVersion,
157
- resolve, reject,
165
+ resolve, reject
158
166
  });
159
167
  if (renderContext.method === "OPTIONS")
160
168
  return resolver.cors();
@@ -187,7 +195,7 @@ export default class Lambder {
187
195
  catch (err) {
188
196
  const wrappedError = err instanceof Error ? err : new Error("Error: " + String(err));
189
197
  if (this.globalErrorHandler) {
190
- return this.globalErrorHandler(wrappedError);
198
+ return this.globalErrorHandler(wrappedError, eventRenderContext, resolverLight);
191
199
  }
192
200
  return { statusCode: 500, body: "Internal Server Error.", };
193
201
  }
@@ -1,12 +1,4 @@
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
- };
1
+ import ResolverLight, { ResolverResponse } from "./ResolverLight";
10
2
  interface IResolverMethods {
11
3
  raw(param: {
12
4
  statusCode: number;
@@ -15,29 +7,29 @@ interface IResolverMethods {
15
7
  multiValueHeaders: {
16
8
  [key: string]: string[];
17
9
  };
18
- }): any;
10
+ }): ResolverResponse;
19
11
  json(data: {
20
12
  [key: string]: any;
21
13
  }, headers?: {
22
14
  [key: string]: string | string[];
23
- }): any;
24
- xml(data: string): any;
15
+ }): ResolverResponse;
16
+ xml(data: string): ResolverResponse;
25
17
  html(data: string, headers?: {
26
18
  [key: string]: string | string[];
27
- }): any;
19
+ }): ResolverResponse;
28
20
  status301(url: string, headers?: {
29
21
  [key: string]: string | string[];
30
- }): any;
22
+ }): ResolverResponse;
31
23
  status404(data: string, headers?: {
32
24
  [key: string]: string | string[];
33
- }): any;
34
- cors(): any;
25
+ }): ResolverResponse;
26
+ cors(): ResolverResponse;
35
27
  fileBase64(fileBase64: string, mimeType: string, headers?: {
36
28
  [key: string]: string | string[];
37
- }): any;
29
+ }): ResolverResponse;
38
30
  file(filePath: string, headers?: {
39
31
  [key: string]: string | string[];
40
- }): any;
32
+ }): ResolverResponse;
41
33
  api({ payload, versionExpired, sessionExpired, notAuthorized, message, errorMessage, ...other }: {
42
34
  payload?: any;
43
35
  versionExpired?: boolean;
@@ -47,14 +39,11 @@ interface IResolverMethods {
47
39
  errorMessage?: any;
48
40
  }, headers?: {
49
41
  [key: string]: string | string[];
50
- }): any;
42
+ }): ResolverResponse;
51
43
  }
52
- export default class Resolver {
53
- private isCorsEnabled;
54
- private publicPath;
55
- private apiVersion;
56
- resolve: Function;
57
- reject: Function;
44
+ export default class Resolver extends ResolverLight {
45
+ resolve: (renderResult: ResolverResponse) => void;
46
+ reject: (err: Error) => void;
58
47
  die: IResolverMethods;
59
48
  constructor({ isCorsEnabled, publicPath, apiVersion, resolve, reject }: {
60
49
  isCorsEnabled: boolean;
@@ -63,40 +52,6 @@ export default class Resolver {
63
52
  resolve: (renderResult: ResolverResponse) => void;
64
53
  reject: (err: Error) => void;
65
54
  });
66
- private readFileSync;
67
- private checkFileExist;
68
- raw(param: ResolverResponse): ResolverResponse;
69
- json(data: {
70
- [key: string]: any;
71
- }, headers?: {
72
- [key: string]: string | string[];
73
- }): ResolverResponse;
74
- xml(data: string): ResolverResponse;
75
- html(data: string, headers?: {
76
- [key: string]: string | string[];
77
- }): ResolverResponse;
78
- status301(url: string, headers?: {
79
- [key: string]: string | string[];
80
- }): ResolverResponse;
81
- status404(data: string, headers?: {
82
- [key: string]: string | string[];
83
- }): ResolverResponse;
84
- cors(): ResolverResponse;
85
- fileBase64(fileBase64: string, mimeType: string, headers?: {
86
- [key: string]: string | string[];
87
- }): ResolverResponse;
88
- file(filePath: string, headers?: {
89
- [key: string]: string | string[];
90
- }, fallbackFilePath?: string): ResolverResponse;
91
- api({ payload, versionExpired, sessionExpired, notAuthorized, message, errorMessage, ...other }: {
92
- payload?: any;
93
- versionExpired?: boolean;
94
- sessionExpired?: boolean;
95
- notAuthorized?: boolean;
96
- message?: any;
97
- errorMessage?: any;
98
- }, headers?: {
99
- [key: string]: string | string[];
100
- }): ResolverResponse;
55
+ private autoResolve;
101
56
  }
102
57
  export {};
package/dist/Resolver.js CHANGED
@@ -1,153 +1,32 @@
1
- import fs from "fs";
2
- import * as path 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;
1
+ import ResolverLight from "./ResolverLight";
2
+ export default class Resolver extends ResolverLight {
15
3
  resolve;
16
4
  reject;
17
5
  die;
18
6
  constructor({ isCorsEnabled, publicPath, apiVersion, resolve, reject }) {
19
- this.isCorsEnabled = isCorsEnabled;
20
- this.publicPath = publicPath;
21
- this.apiVersion = apiVersion ?? null;
7
+ super({ isCorsEnabled, publicPath, apiVersion });
22
8
  this.resolve = resolve;
23
9
  this.reject = reject;
10
+ // Bind ResolverLight methods to `this` for `die` and automatically resolve
24
11
  this.die = {
25
- raw: this.raw,
26
- json: this.json,
27
- xml: this.xml,
28
- html: this.html,
29
- status301: this.status301,
30
- status404: this.status404,
31
- cors: this.cors,
32
- fileBase64: this.fileBase64,
33
- file: this.file,
34
- api: this.api,
12
+ raw: this.autoResolve(this.raw),
13
+ json: this.autoResolve(this.json),
14
+ xml: this.autoResolve(this.xml),
15
+ html: this.autoResolve(this.html),
16
+ status301: this.autoResolve(this.status301),
17
+ status404: this.autoResolve(this.status404),
18
+ cors: this.autoResolve(this.cors),
19
+ fileBase64: this.autoResolve(this.fileBase64),
20
+ file: this.autoResolve(this.file),
21
+ api: this.autoResolve(this.api),
35
22
  };
36
23
  }
37
- ;
38
- readFileSync(filePath) {
39
- const publicPath = path.resolve(this.publicPath);
40
- const absolutePath = path.join(publicPath, filePath);
41
- console.log("readFileSync", { filePath, publicPath, absolutePath });
42
- if (!absolutePath.includes(publicPath)) {
43
- return "forbiddenpath";
44
- }
45
- return fs.readFileSync(absolutePath);
46
- }
47
- ;
48
- checkFileExist(filePath) {
49
- const publicPath = path.resolve(this.publicPath);
50
- const absolutePath = path.join(this.publicPath, filePath);
51
- console.log("checkFileExist", { filePath, publicPath, absolutePath });
52
- if (!absolutePath.includes(publicPath)) {
53
- return false;
54
- }
55
- return fs.existsSync(absolutePath) && fs.statSync(absolutePath).isFile();
56
- }
57
- ;
58
- raw(param) {
59
- return param;
60
- }
61
- ;
62
- json(data, headers) {
63
- return this.raw({
64
- statusCode: 200,
65
- multiValueHeaders: {
66
- "Content-Type": ["application/json; charset=utf-8"],
67
- ...(this.isCorsEnabled ? CORS_HEADERS : {}),
68
- ...convertToMultiHeader(headers)
69
- },
70
- body: JSON.stringify(data),
71
- });
72
- }
73
- xml(data) {
74
- return this.raw({
75
- statusCode: 200,
76
- isBase64Encoded: true,
77
- multiValueHeaders: { "Content-Type": ["application/xml; charset=utf-8"] },
78
- body: Buffer.from(data).toString("base64"),
79
- });
80
- }
81
- ;
82
- html(data, headers) {
83
- return this.raw({
84
- statusCode: 200,
85
- isBase64Encoded: true,
86
- multiValueHeaders: { "Content-Type": ["text/html; charset=utf-8"], ...convertToMultiHeader(headers) },
87
- body: Buffer.from(data).toString("base64"),
88
- });
89
- }
90
- ;
91
- status301(url, headers) {
92
- return this.raw({
93
- statusCode: 301,
94
- multiValueHeaders: { "Location": [url], ...convertToMultiHeader(headers) },
95
- body: null
96
- });
97
- }
98
- ;
99
- status404(data, headers) {
100
- return this.raw({
101
- statusCode: 404,
102
- isBase64Encoded: true,
103
- multiValueHeaders: { "Content-Type": ["text/html; charset=utf-8"], ...convertToMultiHeader(headers) },
104
- body: Buffer.from(data).toString("base64"),
105
- });
106
- }
107
- ;
108
- cors() {
109
- return this.raw({
110
- statusCode: 200,
111
- multiValueHeaders: this.isCorsEnabled ? CORS_HEADERS : {},
112
- body: JSON.stringify(""),
113
- });
114
- }
115
- ;
116
- fileBase64(fileBase64, mimeType, headers) {
117
- return this.raw({
118
- statusCode: 200,
119
- isBase64Encoded: true,
120
- multiValueHeaders: { "Content-Type": [mimeType || "text/html"], ...convertToMultiHeader(headers) },
121
- body: fileBase64,
122
- });
123
- }
124
- ;
125
- file(filePath, headers, fallbackFilePath) {
126
- if (!this.checkFileExist(filePath)) {
127
- if (fallbackFilePath && this.checkFileExist(fallbackFilePath)) {
128
- return this.file(fallbackFilePath, headers);
129
- }
130
- return this.json({ error: "File not found: " + filePath });
131
- }
132
- const mimeType = mimeTypeResolver.lookup(filePath);
133
- const body = this.readFileSync(filePath);
134
- const bodyBase64 = Buffer.from(body).toString("base64");
135
- console.log("bodyBase64.length", bodyBase64.length);
136
- return this.fileBase64(bodyBase64, mimeType || "", headers);
137
- }
138
- ;
139
- api({ payload, versionExpired, sessionExpired, notAuthorized, message = null, errorMessage = null, ...other }, headers) {
140
- if (Object.keys(other).length)
141
- console.log("ERROR: Unexpected key in result: " + Object.keys(other).join(", "));
142
- return this.json({
143
- apiVersion: this.apiVersion,
144
- payload,
145
- ...(versionExpired ? { versionExpired } : {}),
146
- ...(sessionExpired ? { sessionExpired } : {}),
147
- ...(notAuthorized ? { notAuthorized } : {}),
148
- ...(message ? { message } : {}),
149
- ...(errorMessage ? { errorMessage } : {}),
150
- }, headers);
24
+ autoResolve(method) {
25
+ return (...args) => {
26
+ const result = method.apply(this, args);
27
+ this.resolve(result);
28
+ return result;
29
+ };
151
30
  }
152
- ;
153
31
  }
32
+ ;
@@ -0,0 +1,54 @@
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
+ export default class ResolverLight {
11
+ private isCorsEnabled;
12
+ private publicPath;
13
+ private apiVersion;
14
+ constructor({ isCorsEnabled, publicPath, apiVersion }: {
15
+ isCorsEnabled: boolean;
16
+ publicPath: string;
17
+ apiVersion?: string | null;
18
+ });
19
+ private readFileSync;
20
+ private checkFileExist;
21
+ raw(param: ResolverResponse): ResolverResponse;
22
+ json(data: {
23
+ [key: string]: any;
24
+ }, headers?: {
25
+ [key: string]: string | string[];
26
+ }): ResolverResponse;
27
+ xml(data: string): ResolverResponse;
28
+ html(data: string, headers?: {
29
+ [key: string]: string | string[];
30
+ }): ResolverResponse;
31
+ status301(url: string, headers?: {
32
+ [key: string]: string | string[];
33
+ }): ResolverResponse;
34
+ status404(data: string, headers?: {
35
+ [key: string]: string | string[];
36
+ }): ResolverResponse;
37
+ cors(): ResolverResponse;
38
+ fileBase64(fileBase64: string, mimeType: string, headers?: {
39
+ [key: string]: string | string[];
40
+ }): ResolverResponse;
41
+ file(filePath: string, headers?: {
42
+ [key: string]: string | string[];
43
+ }, fallbackFilePath?: string): ResolverResponse;
44
+ api({ payload, versionExpired, sessionExpired, notAuthorized, message, errorMessage, ...other }: {
45
+ payload?: any;
46
+ versionExpired?: boolean;
47
+ sessionExpired?: boolean;
48
+ notAuthorized?: boolean;
49
+ message?: any;
50
+ errorMessage?: any;
51
+ }, headers?: {
52
+ [key: string]: string | string[];
53
+ }): ResolverResponse;
54
+ }
@@ -0,0 +1,137 @@
1
+ import fs from "fs";
2
+ import * as path 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 ResolverLight {
12
+ isCorsEnabled;
13
+ publicPath;
14
+ apiVersion;
15
+ constructor({ isCorsEnabled, publicPath, apiVersion }) {
16
+ this.isCorsEnabled = isCorsEnabled;
17
+ this.publicPath = publicPath;
18
+ this.apiVersion = apiVersion ?? null;
19
+ }
20
+ ;
21
+ readFileSync(filePath) {
22
+ const publicPath = path.resolve(this.publicPath);
23
+ const absolutePath = path.join(publicPath, filePath);
24
+ console.log("readFileSync", { filePath, publicPath, absolutePath });
25
+ if (!absolutePath.includes(publicPath)) {
26
+ return "forbiddenpath";
27
+ }
28
+ return fs.readFileSync(absolutePath);
29
+ }
30
+ ;
31
+ checkFileExist(filePath) {
32
+ const publicPath = path.resolve(this.publicPath);
33
+ const absolutePath = path.join(this.publicPath, filePath);
34
+ console.log("checkFileExist", { filePath, publicPath, absolutePath });
35
+ if (!absolutePath.includes(publicPath)) {
36
+ return false;
37
+ }
38
+ return fs.existsSync(absolutePath) && fs.statSync(absolutePath).isFile();
39
+ }
40
+ ;
41
+ raw(param) {
42
+ return param;
43
+ }
44
+ ;
45
+ json(data, headers) {
46
+ return this.raw({
47
+ statusCode: 200,
48
+ multiValueHeaders: {
49
+ "Content-Type": ["application/json; charset=utf-8"],
50
+ ...(this.isCorsEnabled ? CORS_HEADERS : {}),
51
+ ...convertToMultiHeader(headers)
52
+ },
53
+ body: JSON.stringify(data),
54
+ });
55
+ }
56
+ xml(data) {
57
+ return this.raw({
58
+ statusCode: 200,
59
+ isBase64Encoded: true,
60
+ multiValueHeaders: { "Content-Type": ["application/xml; charset=utf-8"] },
61
+ body: Buffer.from(data).toString("base64"),
62
+ });
63
+ }
64
+ ;
65
+ html(data, headers) {
66
+ return this.raw({
67
+ statusCode: 200,
68
+ isBase64Encoded: true,
69
+ multiValueHeaders: { "Content-Type": ["text/html; charset=utf-8"], ...convertToMultiHeader(headers) },
70
+ body: Buffer.from(data).toString("base64"),
71
+ });
72
+ }
73
+ ;
74
+ status301(url, headers) {
75
+ return this.raw({
76
+ statusCode: 301,
77
+ multiValueHeaders: { "Location": [url], ...convertToMultiHeader(headers) },
78
+ body: null
79
+ });
80
+ }
81
+ ;
82
+ status404(data, headers) {
83
+ return this.raw({
84
+ statusCode: 404,
85
+ isBase64Encoded: true,
86
+ multiValueHeaders: { "Content-Type": ["text/html; charset=utf-8"], ...convertToMultiHeader(headers) },
87
+ body: Buffer.from(data).toString("base64"),
88
+ });
89
+ }
90
+ ;
91
+ cors() {
92
+ return this.raw({
93
+ statusCode: 200,
94
+ multiValueHeaders: this.isCorsEnabled ? CORS_HEADERS : {},
95
+ body: JSON.stringify(""),
96
+ });
97
+ }
98
+ ;
99
+ fileBase64(fileBase64, mimeType, headers) {
100
+ return this.raw({
101
+ statusCode: 200,
102
+ isBase64Encoded: true,
103
+ multiValueHeaders: { "Content-Type": [mimeType || "text/html"], ...convertToMultiHeader(headers) },
104
+ body: fileBase64,
105
+ });
106
+ }
107
+ ;
108
+ file(filePath, headers, fallbackFilePath) {
109
+ if (!this.checkFileExist(filePath)) {
110
+ if (fallbackFilePath && this.checkFileExist(fallbackFilePath)) {
111
+ return this.file(fallbackFilePath, headers);
112
+ }
113
+ return this.json({ error: "File not found: " + filePath });
114
+ }
115
+ const mimeType = mimeTypeResolver.lookup(filePath);
116
+ const body = this.readFileSync(filePath);
117
+ const bodyBase64 = Buffer.from(body).toString("base64");
118
+ console.log("bodyBase64.length", bodyBase64.length);
119
+ return this.fileBase64(bodyBase64, mimeType || "", headers);
120
+ }
121
+ ;
122
+ api({ payload, versionExpired, sessionExpired, notAuthorized, message = null, errorMessage = null, ...other }, headers) {
123
+ if (Object.keys(other).length)
124
+ console.log("ERROR: Unexpected key in result: " + Object.keys(other).join(", "));
125
+ return this.json({
126
+ apiVersion: this.apiVersion,
127
+ payload,
128
+ ...(versionExpired ? { versionExpired } : {}),
129
+ ...(sessionExpired ? { sessionExpired } : {}),
130
+ ...(notAuthorized ? { notAuthorized } : {}),
131
+ ...(message ? { message } : {}),
132
+ ...(errorMessage ? { errorMessage } : {}),
133
+ }, headers);
134
+ }
135
+ ;
136
+ }
137
+ ;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  import Lambder from './Lambder.js';
2
2
  export default Lambder;
3
3
  export { default as LambderCaller } from "./LambderCaller.js";
4
+ export { default as ResolverLight } from "./ResolverLight.js";
5
+ export { default as Resolver } from "./Resolver.js";
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
1
  import Lambder from './Lambder.js';
2
2
  export default Lambder;
3
3
  export { default as LambderCaller } from "./LambderCaller.js";
4
+ export { default as ResolverLight } from "./ResolverLight.js";
5
+ export { default as Resolver } from "./Resolver.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lambder",
3
- "version": "1.0.29",
3
+ "version": "1.0.36",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/Lambder.ts CHANGED
@@ -2,7 +2,8 @@ import querystring from "querystring";
2
2
  import cookieParser from "cookie";
3
3
 
4
4
  import type { APIGatewayProxyEvent, APIGatewayProxyEventHeaders, Context } from "aws-lambda";
5
- import Resolver, { ResolverResponse } from "./Resolver.js";
5
+ import Resolver from "./Resolver.js";
6
+ import ResolverLight, { ResolverResponse } from "./ResolverLight.js";
6
7
 
7
8
  type DDBSession = {
8
9
  userId: string,
@@ -36,6 +37,10 @@ type HookAfterRenderFunction = (renderContext: RenderContext, resolver: Resolver
36
37
  type HookFallbackFunction = (renderContext: RenderContext, resolver: Resolver) => ResolverResponse|Promise<ResolverResponse>;
37
38
  type HookCompletedFunction = (renderResult: ResolverResponse) => ResolverResponse|Promise<ResolverResponse>;
38
39
 
40
+ type GlobalErrorHandlerFunction = (err: Error, renderContext: RenderContext|null, resolver: ResolverLight) => ResolverResponse|Promise<ResolverResponse>;
41
+ type RouteFallbackHandlerFunction = (renderContext:RenderContext, resolver: Resolver) => ResolverResponse;
42
+ type ApiFallbackHandlerFunction = (renderContext:RenderContext, resolver: Resolver) => ResolverResponse;
43
+
39
44
  type HookEventType = "created"|"beforeRender"|"afterRender"|"fallback"|"completed";
40
45
  type HookListType = {
41
46
  priority: number,
@@ -77,9 +82,9 @@ export default class Lambder {
77
82
  "fallback": { priority: number, hookFn: HookFallbackFunction }[],
78
83
  "completed": { priority: number, hookFn: HookCompletedFunction }[]
79
84
  };
80
- private globalErrorHandler: Function|null = null;
81
- private routeFallbackHandler: Function|null = null;
82
- private apiFallbackHandler: Function|null = null;
85
+ private globalErrorHandler: GlobalErrorHandlerFunction|null = null;
86
+ private routeFallbackHandler: RouteFallbackHandlerFunction|null = null;
87
+ private apiFallbackHandler: ApiFallbackHandlerFunction|null = null;
83
88
 
84
89
  constructor(
85
90
  { publicPath, apiPath, apiVersion, isCorsEnabled, }:
@@ -99,13 +104,13 @@ export default class Lambder {
99
104
  };
100
105
  }
101
106
 
102
- setRouteFallbackHandler(routeFallbackHandler: (renderContext:RenderContext, resolver: Resolver)=>ResolverResponse){
107
+ setRouteFallbackHandler(routeFallbackHandler: RouteFallbackHandlerFunction){
103
108
  this.routeFallbackHandler = routeFallbackHandler;
104
109
  }
105
- setApiFallbackHandler(apiFallbackHandler: (renderContext:RenderContext, resolver: Resolver)=>ResolverResponse){
110
+ setApiFallbackHandler(apiFallbackHandler: ApiFallbackHandlerFunction){
106
111
  this.apiFallbackHandler = apiFallbackHandler;
107
112
  }
108
- setGlobalErrorHandler(globalErrorHandler: (err: Error)=>ResolverResponse){
113
+ setGlobalErrorHandler(globalErrorHandler: GlobalErrorHandlerFunction){
109
114
  this.globalErrorHandler = globalErrorHandler;
110
115
  }
111
116
 
@@ -222,18 +227,26 @@ export default class Lambder {
222
227
  event: APIGatewayProxyEvent,
223
228
  lambdaContext: Context
224
229
  ): Promise<ResolverResponse>{
230
+ let eventRenderContext:RenderContext|null = null;
231
+ const resolverLight = new ResolverLight({
232
+ isCorsEnabled: this.isCorsEnabled,
233
+ publicPath: this.publicPath,
234
+ apiVersion: this.apiVersion,
235
+ })
236
+
225
237
  try {
226
- let renderContext:RenderContext = createContext(event, lambdaContext)
238
+ let renderContext = createContext(event, lambdaContext);
239
+ eventRenderContext = renderContext;
227
240
 
228
241
  return await new Promise(async (
229
242
  resolve:(renderResult: ResolverResponse)=>void,
230
243
  reject:(err: Error)=>void
231
244
  )=> {
232
- const resolver = new Resolver({
245
+ const resolver = new Resolver({
233
246
  isCorsEnabled: this.isCorsEnabled,
234
247
  publicPath: this.publicPath,
235
248
  apiVersion: this.apiVersion,
236
- resolve, reject,
249
+ resolve, reject
237
250
  });
238
251
  if(renderContext.method === "OPTIONS") return resolver.cors();
239
252
 
@@ -263,9 +276,8 @@ export default class Lambder {
263
276
  });
264
277
  }catch(err){
265
278
  const wrappedError = err instanceof Error ? err : new Error("Error: " + String(err));
266
-
267
279
  if(this.globalErrorHandler){
268
- return this.globalErrorHandler(wrappedError);
280
+ return this.globalErrorHandler(wrappedError, eventRenderContext, resolverLight);
269
281
  }
270
282
  return { statusCode: 500, body: "Internal Server Error.", }
271
283
 
package/src/Resolver.ts CHANGED
@@ -1,27 +1,4 @@
1
- import fs from "fs";
2
- import * as path from "path";
3
- import mimeTypeResolver from "mime-types";
4
-
5
- const convertToMultiHeader = (
6
- headers: { [key:string]: string|string[] } | undefined
7
- ):{ [key:string]: string[] } =>
8
- Object.fromEntries(Object.entries(headers||{}).map(([k,v])=>[ k, Array.isArray(v) ? v : [v] ]));
9
-
10
- const CORS_HEADERS = convertToMultiHeader({
11
- "Access-Control-Allow-Credentials": "true",
12
- "Access-Control-Allow-Headers" : "Origin, X-Requested-With, Content-Type, Accept",
13
- "Access-Control-Allow-Origin": "*",
14
- "Access-Control-Allow-Methods": "OPTIONS,POST",
15
- });
16
-
17
-
18
- export type ResolverResponse = {
19
- statusCode: number,
20
- multiValueHeaders?: { [key:string]: string[] },
21
- body: string | null,
22
- isBase64Encoded?: boolean,
23
- [key:string]: any,
24
- };
1
+ import ResolverLight, { ResolverResponse } from "./ResolverLight";
25
2
 
26
3
 
27
4
  interface IResolverMethods {
@@ -30,15 +7,15 @@ interface IResolverMethods {
30
7
  isBase64Encoded?: boolean,
31
8
  body: null | string,
32
9
  multiValueHeaders: { [key: string]: string[] },
33
- }): any;
34
- json(data: { [key: string]: any }, headers?: { [key: string]: string | string[] }): any;
35
- xml(data: string): any;
36
- html(data: string, headers?: { [key: string]: string | string[] }): any;
37
- status301(url: string, headers?: { [key: string]: string | string[] }): any;
38
- status404(data: string, headers?: { [key: string]: string | string[] }): any;
39
- cors(): any;
40
- fileBase64(fileBase64: string, mimeType: string, headers?: { [key: string]: string | string[] }): any;
41
- file(filePath: string, headers?: { [key: string]: string | string[] }): any;
10
+ }): ResolverResponse;
11
+ json(data: { [key: string]: any }, headers?: { [key: string]: string | string[] }): ResolverResponse;
12
+ xml(data: string): ResolverResponse;
13
+ html(data: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
14
+ status301(url: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
15
+ status404(data: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
16
+ cors(): ResolverResponse;
17
+ fileBase64(fileBase64: string, mimeType: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
18
+ file(filePath: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
42
19
  api({
43
20
  payload,
44
21
  versionExpired, sessionExpired, notAuthorized,
@@ -53,17 +30,14 @@ interface IResolverMethods {
53
30
  errorMessage?: any;
54
31
  },
55
32
  headers?: { [key:string]: string|string[] }
56
- ): any;
33
+ ): ResolverResponse;
57
34
  }
58
35
 
59
36
 
60
- export default class Resolver {
61
- private isCorsEnabled: boolean;
62
- private publicPath: string;
63
- private apiVersion: string|null;
64
- resolve: Function;
65
- reject: Function;
66
- die: IResolverMethods;
37
+ export default class Resolver extends ResolverLight {
38
+ public resolve: (renderResult: ResolverResponse) => void;
39
+ public reject: (err: Error) => void;
40
+ public die: IResolverMethods;
67
41
 
68
42
  constructor(
69
43
  { isCorsEnabled, publicPath, apiVersion, resolve, reject }:
@@ -71,173 +45,37 @@ export default class Resolver {
71
45
  isCorsEnabled: boolean,
72
46
  publicPath: string,
73
47
  apiVersion?: string|null,
74
- resolve:(renderResult: ResolverResponse)=>void,
75
- reject:(err: Error)=>void
48
+ resolve: (renderResult: ResolverResponse) => void,
49
+ reject: (err: Error) => void,
76
50
  }
77
51
  ){
78
- this.isCorsEnabled = isCorsEnabled;
79
- this.publicPath = publicPath;
80
- this.apiVersion = apiVersion ?? null;
52
+ super({ isCorsEnabled, publicPath, apiVersion });
81
53
  this.resolve = resolve;
82
54
  this.reject = reject;
83
- this.die = {
84
- raw: this.raw,
85
- json: this.json,
86
- xml: this.xml,
87
- html: this.html,
88
- status301: this.status301,
89
- status404: this.status404,
90
- cors: this.cors,
91
- fileBase64: this.fileBase64,
92
- file: this.file,
93
- api: this.api,
94
- }
95
- };
96
-
97
- private readFileSync(filePath: string){
98
- const publicPath = path.resolve(this.publicPath);
99
- const absolutePath = path.join(publicPath, filePath);
100
- console.log("readFileSync", { filePath, publicPath, absolutePath });
101
- if(!absolutePath.includes(publicPath)){ return "forbiddenpath"; }
102
- return fs.readFileSync(absolutePath);
103
- };
104
-
105
- private checkFileExist(filePath: string){
106
- const publicPath = path.resolve(this.publicPath);
107
- const absolutePath = path.join(this.publicPath, filePath);
108
- console.log("checkFileExist", { filePath, publicPath, absolutePath });
109
- if(!absolutePath.includes(publicPath)){ return false; }
110
- return fs.existsSync(absolutePath) && fs.statSync(absolutePath).isFile();
111
- };
112
55
 
113
- raw(param: ResolverResponse){
114
- return param;
115
- };
116
-
117
- json(
118
- data: { [key:string]: any },
119
- headers?: { [key:string]: string|string[] }
120
- ):ResolverResponse{
121
- return this.raw({
122
- statusCode: 200,
123
- multiValueHeaders: {
124
- "Content-Type": ["application/json; charset=utf-8"],
125
- ...(this.isCorsEnabled ? CORS_HEADERS : {}),
126
- ...convertToMultiHeader(headers)
127
- },
128
- body: JSON.stringify(data),
129
- });
56
+ // Bind ResolverLight methods to `this` for `die` and automatically resolve
57
+ this.die = {
58
+ raw: this.autoResolve(this.raw),
59
+ json: this.autoResolve(this.json),
60
+ xml: this.autoResolve(this.xml),
61
+ html: this.autoResolve(this.html),
62
+ status301: this.autoResolve(this.status301),
63
+ status404: this.autoResolve(this.status404),
64
+ cors: this.autoResolve(this.cors),
65
+ fileBase64: this.autoResolve(this.fileBase64),
66
+ file: this.autoResolve(this.file),
67
+ api: this.autoResolve(this.api),
68
+ };
130
69
  }
131
70
 
132
- xml(data: string):ResolverResponse{
133
- return this.raw({
134
- statusCode: 200,
135
- isBase64Encoded: true,
136
- multiValueHeaders: { "Content-Type": ["application/xml; charset=utf-8"]},
137
- body: Buffer.from(data).toString("base64"),
138
- });
139
- };
140
-
141
- html(
142
- data: string,
143
- headers?: { [key:string]: string|string[] },
144
- ):ResolverResponse{
145
- return this.raw({
146
- statusCode: 200,
147
- isBase64Encoded: true,
148
- multiValueHeaders: {"Content-Type": ["text/html; charset=utf-8"], ...convertToMultiHeader(headers)},
149
- body: Buffer.from(data).toString("base64"),
150
- });
151
- };
152
-
153
- status301(
154
- url: string,
155
- headers?: { [key:string]: string|string[] },
156
- ):ResolverResponse{
157
- return this.raw({
158
- statusCode: 301,
159
- multiValueHeaders: { "Location" : [url], ...convertToMultiHeader(headers) },
160
- body:null
161
- });
162
- };
163
-
164
- status404(
165
- data: string,
166
- headers?: { [key:string]: string|string[] },
167
- ):ResolverResponse{
168
- return this.raw({
169
- statusCode: 404,
170
- isBase64Encoded: true,
171
- multiValueHeaders: {"Content-Type": ["text/html; charset=utf-8"], ...convertToMultiHeader(headers)},
172
- body: Buffer.from(data).toString("base64"),
173
- });
174
- };
175
-
176
- cors():ResolverResponse{
177
- return this.raw({
178
- statusCode: 200,
179
- multiValueHeaders: this.isCorsEnabled ? CORS_HEADERS: {},
180
- body: JSON.stringify(""),
181
- });
182
- };
183
-
184
- fileBase64 (
185
- fileBase64: string,
186
- mimeType: string,
187
- headers?: { [key:string]: string|string[] },
188
- ):ResolverResponse{
189
- return this.raw({
190
- statusCode: 200,
191
- isBase64Encoded: true,
192
- multiValueHeaders: { "Content-Type": [mimeType || "text/html"], ...convertToMultiHeader(headers) },
193
- body: fileBase64,
194
- });
195
- };
196
-
197
- file(
198
- filePath: string,
199
- headers?: { [key:string]: string|string[] },
200
- fallbackFilePath?: string,
201
- ):ResolverResponse{
202
- if(!this.checkFileExist(filePath)){
203
- if(fallbackFilePath && this.checkFileExist(fallbackFilePath)){
204
- return this.file(fallbackFilePath, headers);
205
- }
206
- return this.json({ error: "File not found: " + filePath })
207
- }
208
- const mimeType = mimeTypeResolver.lookup(filePath);
209
- const body = this.readFileSync(filePath);
210
- const bodyBase64 = Buffer.from(body).toString("base64");
211
- console.log("bodyBase64.length",bodyBase64.length);
212
- return this.fileBase64(bodyBase64, mimeType || "", headers);
213
- };
71
+ private autoResolve<
72
+ T extends (...args: any[]) => ResolverResponse
73
+ >(method: T): (...funcArgs: Parameters<T>) => ResolverResponse {
74
+ return (...args: Parameters<T>): ResolverResponse => {
75
+ const result: ResolverResponse = method.apply(this, args);
76
+ this.resolve(result);
77
+ return result;
78
+ };
79
+ }
214
80
 
215
- api(
216
- {
217
- payload,
218
- versionExpired, sessionExpired, notAuthorized,
219
- message = null, errorMessage = null,
220
- ...other
221
- }: {
222
- payload?: any;
223
- versionExpired?: boolean;
224
- sessionExpired?: boolean;
225
- notAuthorized?: boolean;
226
- message?: any;
227
- errorMessage?: any;
228
- },
229
- headers?: { [key:string]: string|string[] },
230
- ): ResolverResponse {
231
- if(Object.keys(other).length) console.log("ERROR: Unexpected key in result: " + Object.keys(other).join(", "));
232
- return this.json({
233
- apiVersion: this.apiVersion,
234
- payload,
235
- ...(versionExpired ? {versionExpired} : {}),
236
- ...(sessionExpired ? {sessionExpired} : {}),
237
- ...(notAuthorized ? {notAuthorized} : {}),
238
- ...(message ? {message} : {}),
239
- ...(errorMessage ? {errorMessage} : {}),
240
- }, headers);
241
- };
242
-
243
- }
81
+ };
@@ -0,0 +1,224 @@
1
+ import fs from "fs";
2
+ import * as path from "path";
3
+ import mimeTypeResolver from "mime-types";
4
+
5
+ const convertToMultiHeader = (
6
+ headers: { [key:string]: string|string[] } | undefined
7
+ ):{ [key:string]: string[] } =>
8
+ Object.fromEntries(Object.entries(headers||{}).map(([k,v])=>[ k, Array.isArray(v) ? v : [v] ]));
9
+
10
+ const CORS_HEADERS = convertToMultiHeader({
11
+ "Access-Control-Allow-Credentials": "true",
12
+ "Access-Control-Allow-Headers" : "Origin, X-Requested-With, Content-Type, Accept",
13
+ "Access-Control-Allow-Origin": "*",
14
+ "Access-Control-Allow-Methods": "OPTIONS,POST",
15
+ });
16
+
17
+ export type ResolverResponse = {
18
+ statusCode: number,
19
+ multiValueHeaders?: { [key:string]: string[] },
20
+ body: string | null,
21
+ isBase64Encoded?: boolean,
22
+ [key:string]: any,
23
+ };
24
+
25
+
26
+ export default class ResolverLight {
27
+ private isCorsEnabled: boolean;
28
+ private publicPath: string;
29
+ private apiVersion: string|null;
30
+
31
+ constructor(
32
+ { isCorsEnabled, publicPath, apiVersion }:
33
+ {
34
+ isCorsEnabled: boolean,
35
+ publicPath: string,
36
+ apiVersion?: string|null,
37
+ }
38
+ ){
39
+ this.isCorsEnabled = isCorsEnabled;
40
+ this.publicPath = publicPath;
41
+ this.apiVersion = apiVersion ?? null;
42
+ };
43
+
44
+ private readFileSync(filePath: string){
45
+ const publicPath = path.resolve(this.publicPath);
46
+ const absolutePath = path.join(publicPath, filePath);
47
+ console.log("readFileSync", { filePath, publicPath, absolutePath });
48
+ if(!absolutePath.includes(publicPath)){ return "forbiddenpath"; }
49
+ return fs.readFileSync(absolutePath);
50
+ };
51
+
52
+ private checkFileExist(filePath: string){
53
+ const publicPath = path.resolve(this.publicPath);
54
+ const absolutePath = path.join(this.publicPath, filePath);
55
+ console.log("checkFileExist", { filePath, publicPath, absolutePath });
56
+ if(!absolutePath.includes(publicPath)){ return false; }
57
+ return fs.existsSync(absolutePath) && fs.statSync(absolutePath).isFile();
58
+ };
59
+
60
+ raw(param: ResolverResponse){
61
+ return param;
62
+ };
63
+
64
+ json(
65
+ data: { [key:string]: any },
66
+ headers?: { [key:string]: string|string[] }
67
+ ):ResolverResponse{
68
+ return this.raw({
69
+ statusCode: 200,
70
+ multiValueHeaders: {
71
+ "Content-Type": ["application/json; charset=utf-8"],
72
+ ...(this.isCorsEnabled ? CORS_HEADERS : {}),
73
+ ...convertToMultiHeader(headers)
74
+ },
75
+ body: JSON.stringify(data),
76
+ });
77
+ }
78
+
79
+ xml(data: string):ResolverResponse{
80
+ return this.raw({
81
+ statusCode: 200,
82
+ isBase64Encoded: true,
83
+ multiValueHeaders: { "Content-Type": ["application/xml; charset=utf-8"]},
84
+ body: Buffer.from(data).toString("base64"),
85
+ });
86
+ };
87
+
88
+ html(
89
+ data: string,
90
+ headers?: { [key:string]: string|string[] },
91
+ ):ResolverResponse{
92
+ return this.raw({
93
+ statusCode: 200,
94
+ isBase64Encoded: true,
95
+ multiValueHeaders: {"Content-Type": ["text/html; charset=utf-8"], ...convertToMultiHeader(headers)},
96
+ body: Buffer.from(data).toString("base64"),
97
+ });
98
+ };
99
+
100
+ status301(
101
+ url: string,
102
+ headers?: { [key:string]: string|string[] },
103
+ ):ResolverResponse{
104
+ return this.raw({
105
+ statusCode: 301,
106
+ multiValueHeaders: { "Location" : [url], ...convertToMultiHeader(headers) },
107
+ body:null
108
+ });
109
+ };
110
+
111
+ status404(
112
+ data: string,
113
+ headers?: { [key:string]: string|string[] },
114
+ ):ResolverResponse{
115
+ return this.raw({
116
+ statusCode: 404,
117
+ isBase64Encoded: true,
118
+ multiValueHeaders: {"Content-Type": ["text/html; charset=utf-8"], ...convertToMultiHeader(headers)},
119
+ body: Buffer.from(data).toString("base64"),
120
+ });
121
+ };
122
+
123
+ cors():ResolverResponse{
124
+ return this.raw({
125
+ statusCode: 200,
126
+ multiValueHeaders: this.isCorsEnabled ? CORS_HEADERS: {},
127
+ body: JSON.stringify(""),
128
+ });
129
+ };
130
+
131
+ fileBase64 (
132
+ fileBase64: string,
133
+ mimeType: string,
134
+ headers?: { [key:string]: string|string[] },
135
+ ):ResolverResponse{
136
+ return this.raw({
137
+ statusCode: 200,
138
+ isBase64Encoded: true,
139
+ multiValueHeaders: { "Content-Type": [mimeType || "text/html"], ...convertToMultiHeader(headers) },
140
+ body: fileBase64,
141
+ });
142
+ };
143
+
144
+ file(
145
+ filePath: string,
146
+ headers?: { [key:string]: string|string[] },
147
+ fallbackFilePath?: string,
148
+ ):ResolverResponse{
149
+ if(!this.checkFileExist(filePath)){
150
+ if(fallbackFilePath && this.checkFileExist(fallbackFilePath)){
151
+ return this.file(fallbackFilePath, headers);
152
+ }
153
+ return this.json({ error: "File not found: " + filePath })
154
+ }
155
+ const mimeType = mimeTypeResolver.lookup(filePath);
156
+ const body = this.readFileSync(filePath);
157
+ const bodyBase64 = Buffer.from(body).toString("base64");
158
+ console.log("bodyBase64.length",bodyBase64.length);
159
+ return this.fileBase64(bodyBase64, mimeType || "", headers);
160
+ };
161
+
162
+ api(
163
+ {
164
+ payload,
165
+ versionExpired, sessionExpired, notAuthorized,
166
+ message = null, errorMessage = null,
167
+ ...other
168
+ }: {
169
+ payload?: any;
170
+ versionExpired?: boolean;
171
+ sessionExpired?: boolean;
172
+ notAuthorized?: boolean;
173
+ message?: any;
174
+ errorMessage?: any;
175
+ },
176
+ headers?: { [key:string]: string|string[] },
177
+ ): ResolverResponse {
178
+ if(Object.keys(other).length) console.log("ERROR: Unexpected key in result: " + Object.keys(other).join(", "));
179
+ return this.json({
180
+ apiVersion: this.apiVersion,
181
+ payload,
182
+ ...(versionExpired ? {versionExpired} : {}),
183
+ ...(sessionExpired ? {sessionExpired} : {}),
184
+ ...(notAuthorized ? {notAuthorized} : {}),
185
+ ...(message ? {message} : {}),
186
+ ...(errorMessage ? {errorMessage} : {}),
187
+ }, headers);
188
+ };
189
+
190
+ };
191
+
192
+
193
+
194
+ interface IResolverMethods {
195
+ raw(param: {
196
+ statusCode: number,
197
+ isBase64Encoded?: boolean,
198
+ body: null | string,
199
+ multiValueHeaders: { [key: string]: string[] },
200
+ }): ResolverResponse;
201
+ json(data: { [key: string]: any }, headers?: { [key: string]: string | string[] }): ResolverResponse;
202
+ xml(data: string): ResolverResponse;
203
+ html(data: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
204
+ status301(url: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
205
+ status404(data: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
206
+ cors(): ResolverResponse;
207
+ fileBase64(fileBase64: string, mimeType: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
208
+ file(filePath: string, headers?: { [key: string]: string | string[] }): ResolverResponse;
209
+ api({
210
+ payload,
211
+ versionExpired, sessionExpired, notAuthorized,
212
+ message, errorMessage,
213
+ ...other
214
+ }: {
215
+ payload?: any;
216
+ versionExpired?: boolean;
217
+ sessionExpired?: boolean;
218
+ notAuthorized?: boolean;
219
+ message?: any;
220
+ errorMessage?: any;
221
+ },
222
+ headers?: { [key:string]: string|string[] }
223
+ ): ResolverResponse;
224
+ }
package/src/index.ts CHANGED
@@ -2,3 +2,5 @@ import Lambder from './Lambder.js';
2
2
 
3
3
  export default Lambder;
4
4
  export { default as LambderCaller } from "./LambderCaller.js";
5
+ export { default as ResolverLight } from "./ResolverLight.js";
6
+ export { default as Resolver } from "./Resolver.js";