lambder 1.0.18 → 1.0.19
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/.vscode/settings.json +1 -1
- package/dist/LambderCaller.d.ts +39 -0
- package/dist/LambderCaller.js +93 -0
- package/dist/Resolver.d.ts +6 -2
- package/dist/Resolver.js +6 -4
- package/dist/index.d.ts +3 -2
- package/dist/index.js +24 -15
- package/package.json +3 -1
- package/src/LambderCaller.ts +121 -0
- package/src/Resolver.ts +22 -6
- package/src/index.ts +24 -14
package/.vscode/settings.json
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
type VoidFunction = () => void | Promise<void>;
|
|
2
|
+
type StartEndEventHandler = (activeFetchList: {
|
|
3
|
+
apiName: string;
|
|
4
|
+
done: boolean;
|
|
5
|
+
}[]) => void | Promise<void>;
|
|
6
|
+
type ErrorHandler = (err: Error) => void | Promise<void>;
|
|
7
|
+
type MessageHandler = (message: any) => void | Promise<void>;
|
|
8
|
+
export default class LambderCaller {
|
|
9
|
+
isCorsEnabled: boolean;
|
|
10
|
+
apiPath: string;
|
|
11
|
+
apiVersion?: string;
|
|
12
|
+
fetchTrackerList: {
|
|
13
|
+
apiName: string;
|
|
14
|
+
done: boolean;
|
|
15
|
+
}[];
|
|
16
|
+
versionExpiredHandler?: VoidFunction;
|
|
17
|
+
sessionExpiredHandler?: VoidFunction;
|
|
18
|
+
messageHandler?: MessageHandler;
|
|
19
|
+
errorMessageHandler?: MessageHandler;
|
|
20
|
+
notAuthorizedHandler?: VoidFunction;
|
|
21
|
+
errorHandler?: ErrorHandler;
|
|
22
|
+
fetchStartedHandler?: StartEndEventHandler;
|
|
23
|
+
fetchEndedHandler?: StartEndEventHandler;
|
|
24
|
+
constructor({ isCorsEnabled, apiPath, apiVersion, versionExpiredHandler, sessionExpiredHandler, messageHandler, errorMessageHandler, notAuthorizedHandler, errorHandler, fetchStartedHandler, fetchEndedHandler, }: {
|
|
25
|
+
isCorsEnabled: boolean;
|
|
26
|
+
apiPath: string;
|
|
27
|
+
apiVersion?: string;
|
|
28
|
+
versionExpiredHandler?: VoidFunction;
|
|
29
|
+
sessionExpiredHandler?: VoidFunction;
|
|
30
|
+
messageHandler?: MessageHandler;
|
|
31
|
+
errorMessageHandler?: MessageHandler;
|
|
32
|
+
notAuthorizedHandler?: VoidFunction;
|
|
33
|
+
errorHandler?: ErrorHandler;
|
|
34
|
+
fetchStartedHandler?: StartEndEventHandler;
|
|
35
|
+
fetchEndedHandler?: StartEndEventHandler;
|
|
36
|
+
});
|
|
37
|
+
private api;
|
|
38
|
+
}
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import Cookies from 'js-cookie';
|
|
2
|
+
export default class LambderCaller {
|
|
3
|
+
isCorsEnabled;
|
|
4
|
+
apiPath;
|
|
5
|
+
apiVersion;
|
|
6
|
+
fetchTrackerList = [];
|
|
7
|
+
versionExpiredHandler;
|
|
8
|
+
sessionExpiredHandler;
|
|
9
|
+
messageHandler;
|
|
10
|
+
errorMessageHandler;
|
|
11
|
+
notAuthorizedHandler;
|
|
12
|
+
errorHandler;
|
|
13
|
+
fetchStartedHandler;
|
|
14
|
+
fetchEndedHandler;
|
|
15
|
+
constructor({ isCorsEnabled, apiPath, apiVersion, versionExpiredHandler, sessionExpiredHandler, messageHandler, errorMessageHandler, notAuthorizedHandler, errorHandler, fetchStartedHandler, fetchEndedHandler, }) {
|
|
16
|
+
this.isCorsEnabled = isCorsEnabled;
|
|
17
|
+
this.apiPath = apiPath;
|
|
18
|
+
this.apiVersion = apiVersion;
|
|
19
|
+
this.versionExpiredHandler = versionExpiredHandler;
|
|
20
|
+
this.sessionExpiredHandler = sessionExpiredHandler;
|
|
21
|
+
this.messageHandler = messageHandler;
|
|
22
|
+
this.errorMessageHandler = errorMessageHandler;
|
|
23
|
+
this.notAuthorizedHandler = notAuthorizedHandler;
|
|
24
|
+
this.errorHandler = errorHandler;
|
|
25
|
+
this.fetchStartedHandler = fetchStartedHandler;
|
|
26
|
+
this.fetchEndedHandler = fetchEndedHandler;
|
|
27
|
+
}
|
|
28
|
+
;
|
|
29
|
+
async api(apiName, payload, headers) {
|
|
30
|
+
const fetchTracker = { apiName, done: false };
|
|
31
|
+
try {
|
|
32
|
+
this.fetchTrackerList.push(fetchTracker);
|
|
33
|
+
if (this.fetchStartedHandler)
|
|
34
|
+
await this.fetchStartedHandler(this.fetchTrackerList.filter(v => !v.done));
|
|
35
|
+
const version = this.apiVersion;
|
|
36
|
+
const token = Cookies.get("LMBRTOKEN") || "";
|
|
37
|
+
const siteHost = window.location.hostname;
|
|
38
|
+
let data = await fetch(this.apiPath, {
|
|
39
|
+
method: 'POST', mode: 'same-origin', cache: 'no-cache',
|
|
40
|
+
credentials: 'same-origin', redirect: 'follow', referrerPolicy: 'origin',
|
|
41
|
+
headers: { 'Content-Type': 'application/json', ...(headers || {}) },
|
|
42
|
+
body: JSON.stringify({ api: apiName, version, token, siteHost, payload, }),
|
|
43
|
+
}).then(res => {
|
|
44
|
+
if (res.status >= 500)
|
|
45
|
+
throw new Error("Request failed: " + res.status + " - " + res.statusText);
|
|
46
|
+
return res.json();
|
|
47
|
+
});
|
|
48
|
+
if (data && data.versionExpired) {
|
|
49
|
+
if (this.versionExpiredHandler) {
|
|
50
|
+
await this.versionExpiredHandler();
|
|
51
|
+
}
|
|
52
|
+
else if (this.errorHandler) {
|
|
53
|
+
await this.errorHandler(new Error("Version Expired; Please refresh;"));
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
if (data && data.sessionExpired) {
|
|
58
|
+
Cookies.set('LMBRAUTHID', '', { expires: -1 });
|
|
59
|
+
Cookies.set('LMBRTOKEN', '', { expires: -1 });
|
|
60
|
+
if (this.sessionExpiredHandler) {
|
|
61
|
+
await this.sessionExpiredHandler();
|
|
62
|
+
}
|
|
63
|
+
else if (this.errorHandler) {
|
|
64
|
+
await this.errorHandler(new Error("Version Expired; Please refresh;"));
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
if (data && data.notAuthorized) {
|
|
69
|
+
if (this.notAuthorizedHandler) {
|
|
70
|
+
await this.notAuthorizedHandler();
|
|
71
|
+
}
|
|
72
|
+
else if (this.errorHandler) {
|
|
73
|
+
await this.errorHandler(new Error("Version Expired; Please refresh;"));
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
if (data && data.message && this.messageHandler) {
|
|
78
|
+
await this.messageHandler(data.message);
|
|
79
|
+
}
|
|
80
|
+
if (data && data.errorMessage && this.errorMessageHandler) {
|
|
81
|
+
await this.errorMessageHandler(data.errorMessage);
|
|
82
|
+
}
|
|
83
|
+
return data.payload ?? null;
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
fetchTracker.done = true;
|
|
87
|
+
if (this.errorHandler) {
|
|
88
|
+
this.errorHandler(err instanceof Error ? err : new Error("Error: " + String(err)));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
;
|
|
93
|
+
}
|
package/dist/Resolver.d.ts
CHANGED
|
@@ -85,9 +85,13 @@ export default class Resolver {
|
|
|
85
85
|
file(filePath: string, headers?: {
|
|
86
86
|
[key: string]: string | string[];
|
|
87
87
|
}, fallbackFilePath?: string): ResolverResponse;
|
|
88
|
-
api({ payload,
|
|
88
|
+
api({ payload, versionExpired, sessionExpired, notAuthorized, message, errorMessage, ...other }: {
|
|
89
89
|
payload?: any;
|
|
90
|
-
|
|
90
|
+
versionExpired?: boolean;
|
|
91
|
+
sessionExpired?: boolean;
|
|
92
|
+
notAuthorized?: boolean;
|
|
93
|
+
message?: any;
|
|
94
|
+
errorMessage?: any;
|
|
91
95
|
}, headers?: {
|
|
92
96
|
[key: string]: string | string[];
|
|
93
97
|
}): ResolverResponse;
|
package/dist/Resolver.js
CHANGED
|
@@ -136,15 +136,17 @@ export default class Resolver {
|
|
|
136
136
|
return this.fileBase64(bodyBase64, mimeType || "", headers);
|
|
137
137
|
}
|
|
138
138
|
;
|
|
139
|
-
api({ payload,
|
|
140
|
-
if (error)
|
|
141
|
-
console.log("ERROR: ", error);
|
|
139
|
+
api({ payload, versionExpired, sessionExpired, notAuthorized, message = null, errorMessage = null, ...other }, headers) {
|
|
142
140
|
if (Object.keys(other).length)
|
|
143
141
|
console.log("ERROR: Unexpected key in result: " + Object.keys(other).join(", "));
|
|
144
142
|
return this.json({
|
|
145
143
|
apiVersion: this.apiVersion,
|
|
146
144
|
payload,
|
|
147
|
-
...(
|
|
145
|
+
...(versionExpired ? { versionExpired } : {}),
|
|
146
|
+
...(sessionExpired ? { sessionExpired } : {}),
|
|
147
|
+
...(notAuthorized ? { notAuthorized } : {}),
|
|
148
|
+
...(message ? { message } : {}),
|
|
149
|
+
...(errorMessage ? { errorMessage } : {}),
|
|
148
150
|
}, headers);
|
|
149
151
|
}
|
|
150
152
|
;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { APIGatewayProxyEvent, APIGatewayProxyEventHeaders, Context } from "aws-lambda";
|
|
2
2
|
import Resolver, { ResolverResponse } from "./Resolver.js";
|
|
3
|
+
export { default as LambderCaller } from "./LambderCaller.js";
|
|
3
4
|
type DDBSession = {
|
|
4
5
|
userId: string;
|
|
5
6
|
userIdHash: string;
|
|
@@ -55,8 +56,9 @@ export default class Lambder {
|
|
|
55
56
|
setRouteFallbackHandler(routeFallbackHandler: (renderContext: RenderContext, resolver: Resolver) => ResolverResponse): void;
|
|
56
57
|
setApiFallbackHandler(apiFallbackHandler: (renderContext: RenderContext, resolver: Resolver) => ResolverResponse): void;
|
|
57
58
|
setGlobalErrorHandler(globalErrorHandler: (err: Error) => ResolverResponse): void;
|
|
58
|
-
addModule(moduleFn: Function): Promise<void>;
|
|
59
59
|
private validateSession;
|
|
60
|
+
private handleNoMatchedAction;
|
|
61
|
+
addModule(moduleFn: Function): Promise<void>;
|
|
60
62
|
addRoute(condition: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
|
|
61
63
|
addSessionRoute(condition: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
|
|
62
64
|
addApi(condition: string | ConditionFunction | RegExp, actionFn: ActionFunction): void;
|
|
@@ -68,4 +70,3 @@ export default class Lambder {
|
|
|
68
70
|
addHook(hookEvent: 'completed', hookFn: HookCompletedFunction, priority?: number): Promise<void>;
|
|
69
71
|
render(event: APIGatewayProxyEvent, lambdaContext: Context): Promise<ResolverResponse>;
|
|
70
72
|
}
|
|
71
|
-
export {};
|
package/dist/index.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
|
+
export { default as LambderCaller } from "./LambderCaller.js";
|
|
4
5
|
export const createContext = (event, lambdaContext, resolve, reject) => {
|
|
5
6
|
const host = event.headers.Host || event.headers.host || "";
|
|
6
7
|
const url = event.path;
|
|
@@ -57,9 +58,6 @@ export default class Lambder {
|
|
|
57
58
|
setGlobalErrorHandler(globalErrorHandler) {
|
|
58
59
|
this.globalErrorHandler = globalErrorHandler;
|
|
59
60
|
}
|
|
60
|
-
async addModule(moduleFn) {
|
|
61
|
-
await moduleFn(this);
|
|
62
|
-
}
|
|
63
61
|
async validateSession(session) {
|
|
64
62
|
if (!session)
|
|
65
63
|
return false;
|
|
@@ -73,6 +71,28 @@ export default class Lambder {
|
|
|
73
71
|
return false;
|
|
74
72
|
}
|
|
75
73
|
;
|
|
74
|
+
async handleNoMatchedAction(renderContext, resolver) {
|
|
75
|
+
for (const hook of this._hookList["fallback"]) {
|
|
76
|
+
await hook.hookFn(renderContext, resolver);
|
|
77
|
+
}
|
|
78
|
+
if (renderContext.url === this.apiPath) {
|
|
79
|
+
if (this.apiFallbackHandler) {
|
|
80
|
+
resolver.resolve(await this.apiFallbackHandler(renderContext, resolver));
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
resolver.resolve({ statusCode: 204, body: "API handler not set.", });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else if (this.routeFallbackHandler) {
|
|
87
|
+
resolver.resolve(await this.routeFallbackHandler(renderContext, resolver));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
resolver.resolve({ statusCode: 204, body: "Handler not set.", });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async addModule(moduleFn) {
|
|
94
|
+
await moduleFn(this);
|
|
95
|
+
}
|
|
76
96
|
addRoute(condition, actionFn) {
|
|
77
97
|
this._actionList.push({
|
|
78
98
|
conditionFn: async (renderContext) => (renderContext.method === "GET" &&
|
|
@@ -155,18 +175,7 @@ export default class Lambder {
|
|
|
155
175
|
resolve(renderResult);
|
|
156
176
|
}
|
|
157
177
|
else {
|
|
158
|
-
|
|
159
|
-
await hook.hookFn(renderContext, resolver);
|
|
160
|
-
}
|
|
161
|
-
if (renderContext.url === this.apiPath && this.apiFallbackHandler) {
|
|
162
|
-
resolve(await this.apiFallbackHandler(renderContext, resolver));
|
|
163
|
-
}
|
|
164
|
-
else if (this.routeFallbackHandler) {
|
|
165
|
-
resolve(await this.routeFallbackHandler(renderContext, resolver));
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
resolve({ statusCode: 204, body: "Fallback handler not set.", });
|
|
169
|
-
}
|
|
178
|
+
return this.handleNoMatchedAction(renderContext, resolver);
|
|
170
179
|
}
|
|
171
180
|
}).then(async (renderResult) => {
|
|
172
181
|
for (const hook of this._hookList["completed"]) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lambder",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.19",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,12 +14,14 @@
|
|
|
14
14
|
"license": "ISC",
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"cookie": "^0.6.0",
|
|
17
|
+
"js-cookie": "^3.0.5",
|
|
17
18
|
"mime-types": "^2.1.35",
|
|
18
19
|
"querystring": "^0.2.1"
|
|
19
20
|
},
|
|
20
21
|
"devDependencies": {
|
|
21
22
|
"@types/aws-lambda": "^8.10.136",
|
|
22
23
|
"@types/cookie": "^0.6.0",
|
|
24
|
+
"@types/js-cookie": "^3.0.6",
|
|
23
25
|
"@types/mime-types": "^2.1.4",
|
|
24
26
|
"@types/node": "^20.11.27",
|
|
25
27
|
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import Cookies from 'js-cookie';
|
|
2
|
+
|
|
3
|
+
type VoidFunction = ()=>void|Promise<void>;
|
|
4
|
+
type StartEndEventHandler = (activeFetchList:{ apiName: string, done: boolean}[])=>void|Promise<void>;
|
|
5
|
+
type ErrorHandler = (err: Error) => void|Promise<void>;
|
|
6
|
+
type MessageHandler = (message:any) => void|Promise<void>;
|
|
7
|
+
|
|
8
|
+
export default class LambderCaller {
|
|
9
|
+
isCorsEnabled: boolean;
|
|
10
|
+
apiPath: string;
|
|
11
|
+
apiVersion?: string;
|
|
12
|
+
|
|
13
|
+
fetchTrackerList: { apiName: string, done: boolean}[] = [];
|
|
14
|
+
versionExpiredHandler?: VoidFunction;
|
|
15
|
+
sessionExpiredHandler?: VoidFunction;
|
|
16
|
+
|
|
17
|
+
messageHandler?: MessageHandler;
|
|
18
|
+
errorMessageHandler?: MessageHandler;
|
|
19
|
+
notAuthorizedHandler?: VoidFunction;
|
|
20
|
+
errorHandler?: ErrorHandler;
|
|
21
|
+
|
|
22
|
+
fetchStartedHandler?: StartEndEventHandler;
|
|
23
|
+
fetchEndedHandler?: StartEndEventHandler;
|
|
24
|
+
|
|
25
|
+
constructor(
|
|
26
|
+
{
|
|
27
|
+
isCorsEnabled, apiPath, apiVersion,
|
|
28
|
+
versionExpiredHandler, sessionExpiredHandler,
|
|
29
|
+
messageHandler, errorMessageHandler,
|
|
30
|
+
notAuthorizedHandler, errorHandler,
|
|
31
|
+
fetchStartedHandler, fetchEndedHandler,
|
|
32
|
+
}:
|
|
33
|
+
{
|
|
34
|
+
isCorsEnabled: boolean,
|
|
35
|
+
apiPath: string,
|
|
36
|
+
apiVersion?: string,
|
|
37
|
+
versionExpiredHandler?: VoidFunction,
|
|
38
|
+
sessionExpiredHandler?: VoidFunction,
|
|
39
|
+
messageHandler?: MessageHandler,
|
|
40
|
+
errorMessageHandler?: MessageHandler,
|
|
41
|
+
notAuthorizedHandler?: VoidFunction,
|
|
42
|
+
errorHandler?: ErrorHandler,
|
|
43
|
+
fetchStartedHandler?: StartEndEventHandler,
|
|
44
|
+
fetchEndedHandler?: StartEndEventHandler,
|
|
45
|
+
}
|
|
46
|
+
){
|
|
47
|
+
this.isCorsEnabled = isCorsEnabled;
|
|
48
|
+
this.apiPath = apiPath;
|
|
49
|
+
this.apiVersion = apiVersion;
|
|
50
|
+
|
|
51
|
+
this.versionExpiredHandler = versionExpiredHandler;
|
|
52
|
+
this.sessionExpiredHandler = sessionExpiredHandler;
|
|
53
|
+
|
|
54
|
+
this.messageHandler = messageHandler;
|
|
55
|
+
this.errorMessageHandler = errorMessageHandler;
|
|
56
|
+
this.notAuthorizedHandler = notAuthorizedHandler;
|
|
57
|
+
this.errorHandler = errorHandler;
|
|
58
|
+
|
|
59
|
+
this.fetchStartedHandler = fetchStartedHandler;
|
|
60
|
+
this.fetchEndedHandler = fetchEndedHandler;
|
|
61
|
+
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
private async api(apiName: string, payload: any, headers?: { [key:string]: any }){
|
|
65
|
+
const fetchTracker = { apiName, done: false };
|
|
66
|
+
try {
|
|
67
|
+
this.fetchTrackerList.push(fetchTracker);
|
|
68
|
+
if(this.fetchStartedHandler) await this.fetchStartedHandler(this.fetchTrackerList.filter(v=>!v.done));
|
|
69
|
+
const version = this.apiVersion;
|
|
70
|
+
const token = Cookies.get("LMBRTOKEN") || "";
|
|
71
|
+
const siteHost = window.location.hostname;
|
|
72
|
+
let data = await fetch(this.apiPath, {
|
|
73
|
+
method: 'POST', mode: 'same-origin', cache: 'no-cache',
|
|
74
|
+
credentials: 'same-origin', redirect: 'follow', referrerPolicy: 'origin',
|
|
75
|
+
headers: { 'Content-Type': 'application/json', ...(headers || {}) },
|
|
76
|
+
body: JSON.stringify({ api: apiName, version, token, siteHost, payload, }),
|
|
77
|
+
}).then(res=>{
|
|
78
|
+
if(res.status >= 500) throw new Error("Request failed: " + res.status + " - " + res.statusText);
|
|
79
|
+
return res.json();
|
|
80
|
+
});
|
|
81
|
+
if(data && data.versionExpired){
|
|
82
|
+
if(this.versionExpiredHandler){
|
|
83
|
+
await this.versionExpiredHandler();
|
|
84
|
+
}else if(this.errorHandler){
|
|
85
|
+
await this.errorHandler(new Error("Version Expired; Please refresh;"));
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
if(data && data.sessionExpired){
|
|
90
|
+
Cookies.set('LMBRAUTHID', '', { expires: -1 });
|
|
91
|
+
Cookies.set('LMBRTOKEN', '', { expires: -1 });
|
|
92
|
+
if(this.sessionExpiredHandler){
|
|
93
|
+
await this.sessionExpiredHandler();
|
|
94
|
+
}else if(this.errorHandler){
|
|
95
|
+
await this.errorHandler(new Error("Version Expired; Please refresh;"));
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
if(data && data.notAuthorized){
|
|
100
|
+
if(this.notAuthorizedHandler){
|
|
101
|
+
await this.notAuthorizedHandler();
|
|
102
|
+
}else if(this.errorHandler){
|
|
103
|
+
await this.errorHandler(new Error("Version Expired; Please refresh;"));
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
if(data && data.message && this.messageHandler){
|
|
108
|
+
await this.messageHandler(data.message);
|
|
109
|
+
}
|
|
110
|
+
if(data && data.errorMessage && this.errorMessageHandler){
|
|
111
|
+
await this.errorMessageHandler(data.errorMessage);
|
|
112
|
+
}
|
|
113
|
+
return data.payload ?? null;
|
|
114
|
+
}catch(err){
|
|
115
|
+
fetchTracker.done = true
|
|
116
|
+
if(this.errorHandler){
|
|
117
|
+
this.errorHandler(err instanceof Error ? err : new Error("Error: " + String(err)));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
package/src/Resolver.ts
CHANGED
|
@@ -198,16 +198,32 @@ export default class Resolver {
|
|
|
198
198
|
return this.fileBase64(bodyBase64, mimeType || "", headers);
|
|
199
199
|
};
|
|
200
200
|
|
|
201
|
-
|
|
202
|
-
{
|
|
201
|
+
api(
|
|
202
|
+
{
|
|
203
|
+
payload,
|
|
204
|
+
versionExpired, sessionExpired, notAuthorized,
|
|
205
|
+
message = null, errorMessage = null,
|
|
206
|
+
...other
|
|
207
|
+
}: {
|
|
208
|
+
payload?: any;
|
|
209
|
+
versionExpired?: boolean;
|
|
210
|
+
sessionExpired?: boolean;
|
|
211
|
+
notAuthorized?: boolean;
|
|
212
|
+
message?: any;
|
|
213
|
+
errorMessage?: any;
|
|
214
|
+
},
|
|
203
215
|
headers?: { [key:string]: string|string[] },
|
|
204
|
-
):ResolverResponse{
|
|
205
|
-
if(error) console.log("ERROR: ", error);
|
|
216
|
+
): ResolverResponse {
|
|
206
217
|
if(Object.keys(other).length) console.log("ERROR: Unexpected key in result: " + Object.keys(other).join(", "));
|
|
207
218
|
return this.json({
|
|
208
219
|
apiVersion: this.apiVersion,
|
|
209
|
-
payload,
|
|
210
|
-
...(
|
|
220
|
+
payload,
|
|
221
|
+
...(versionExpired ? {versionExpired} : {}),
|
|
222
|
+
...(sessionExpired ? {sessionExpired} : {}),
|
|
223
|
+
...(notAuthorized ? {notAuthorized} : {}),
|
|
224
|
+
...(message ? {message} : {}),
|
|
225
|
+
...(errorMessage ? {errorMessage} : {}),
|
|
211
226
|
}, headers);
|
|
212
227
|
};
|
|
228
|
+
|
|
213
229
|
}
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,8 @@ import cookieParser from "cookie";
|
|
|
4
4
|
import type { APIGatewayProxyEvent, APIGatewayProxyEventHeaders, Context } from "aws-lambda";
|
|
5
5
|
import Resolver, { ResolverResponse } from "./Resolver.js";
|
|
6
6
|
|
|
7
|
+
export { default as LambderCaller } from "./LambderCaller.js";
|
|
8
|
+
|
|
7
9
|
type DDBSession = {
|
|
8
10
|
userId: string,
|
|
9
11
|
userIdHash: string;
|
|
@@ -111,10 +113,6 @@ export default class Lambder {
|
|
|
111
113
|
this.globalErrorHandler = globalErrorHandler;
|
|
112
114
|
}
|
|
113
115
|
|
|
114
|
-
async addModule(moduleFn: Function): Promise<void>{
|
|
115
|
-
await moduleFn(this);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
116
|
private async validateSession (session: DDBSession): Promise<boolean>{
|
|
119
117
|
if(!session) return false;
|
|
120
118
|
if(!session.userId || !session.userIdHash || !session.sessionHash || !session.csrfToken) return false;
|
|
@@ -124,6 +122,26 @@ export default class Lambder {
|
|
|
124
122
|
return false;
|
|
125
123
|
};
|
|
126
124
|
|
|
125
|
+
private async handleNoMatchedAction(renderContext: RenderContext, resolver: Resolver){
|
|
126
|
+
for(const hook of this._hookList["fallback"]){
|
|
127
|
+
await hook.hookFn(renderContext, resolver);
|
|
128
|
+
}
|
|
129
|
+
if(renderContext.url === this.apiPath){
|
|
130
|
+
if(this.apiFallbackHandler){
|
|
131
|
+
resolver.resolve(await this.apiFallbackHandler(renderContext, resolver));
|
|
132
|
+
}else{
|
|
133
|
+
resolver.resolve({ statusCode: 204, body: "API handler not set.", })
|
|
134
|
+
}
|
|
135
|
+
}else if(this.routeFallbackHandler){
|
|
136
|
+
resolver.resolve(await this.routeFallbackHandler(renderContext, resolver));
|
|
137
|
+
}else{
|
|
138
|
+
resolver.resolve({ statusCode: 204, body: "Handler not set.", })
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async addModule(moduleFn: Function): Promise<void>{
|
|
143
|
+
await moduleFn(this);
|
|
144
|
+
}
|
|
127
145
|
addRoute(condition: string|ConditionFunction|RegExp, actionFn: ActionFunction):void{
|
|
128
146
|
this._actionList.push({
|
|
129
147
|
conditionFn: async (renderContext:RenderContext) => (
|
|
@@ -203,6 +221,7 @@ export default class Lambder {
|
|
|
203
221
|
}
|
|
204
222
|
}
|
|
205
223
|
|
|
224
|
+
|
|
206
225
|
async render(
|
|
207
226
|
event: APIGatewayProxyEvent,
|
|
208
227
|
lambdaContext: Context
|
|
@@ -236,16 +255,7 @@ export default class Lambder {
|
|
|
236
255
|
}
|
|
237
256
|
resolve(renderResult);
|
|
238
257
|
}else{
|
|
239
|
-
|
|
240
|
-
await hook.hookFn(renderContext, resolver);
|
|
241
|
-
}
|
|
242
|
-
if(renderContext.url === this.apiPath && this.apiFallbackHandler){
|
|
243
|
-
resolve(await this.apiFallbackHandler(renderContext, resolver));
|
|
244
|
-
}else if(this.routeFallbackHandler){
|
|
245
|
-
resolve(await this.routeFallbackHandler(renderContext, resolver));
|
|
246
|
-
}else{
|
|
247
|
-
resolve({ statusCode: 204, body: "Fallback handler not set.", })
|
|
248
|
-
}
|
|
258
|
+
return this.handleNoMatchedAction(renderContext, resolver);
|
|
249
259
|
}
|
|
250
260
|
}).then(async (renderResult: ResolverResponse):Promise<ResolverResponse> => {
|
|
251
261
|
for(const hook of this._hookList["completed"]){
|