lambder 1.0.122 → 1.0.124

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
@@ -20,7 +20,15 @@ export type LambderRenderContext = {
20
20
  lambdaContext: Context;
21
21
  _otherInternal: {
22
22
  isApiCall: boolean;
23
- sessionCookieHeader: null | Record<"Set-Cookie", string[]>;
23
+ setHeaderFnAccumulator: {
24
+ key: string;
25
+ value: string | string[];
26
+ }[];
27
+ addHeaderFnAccumulator: {
28
+ key: string;
29
+ value: string;
30
+ }[];
31
+ logToApiResponseAccumulator: any[];
24
32
  };
25
33
  };
26
34
  type LambderModuleFunction = (lambderInstance: Lambder) => void | Promise<void>;
@@ -30,7 +38,7 @@ type HookCreatedFunction = (lambderInstance: Lambder) => Promise<void>;
30
38
  type HookBeforeRenderFunction = (ctx: LambderRenderContext, resolver: LambderResolver) => LambderRenderContext | Error | Promise<LambderRenderContext | Error>;
31
39
  type HookAfterRenderFunction = (ctx: LambderRenderContext, resolver: LambderResolver, response: LambderResolverResponse) => LambderResolverResponse | Error | Promise<LambderResolverResponse | Error>;
32
40
  type HookFallbackFunction = (ctx: LambderRenderContext, resolver: LambderResolver) => void | Promise<void>;
33
- type GlobalErrorHandlerFunction = (err: Error, ctx: LambderRenderContext | null, response: LambderResponseBuilder) => LambderResolverResponse | Promise<LambderResolverResponse>;
41
+ type GlobalErrorHandlerFunction = (err: Error, ctx: LambderRenderContext | null, response: LambderResponseBuilder, logListToApiResponse?: any[]) => LambderResolverResponse | Promise<LambderResolverResponse>;
34
42
  type RouteFallbackHandlerFunction = (ctx: LambderRenderContext, resolver: LambderResolver) => LambderResolverResponse;
35
43
  type ApiFallbackHandlerFunction = (ctx: LambderRenderContext, resolver: LambderResolver) => LambderResolverResponse;
36
44
  export declare const createContext: (event: APIGatewayProxyEvent, lambdaContext: Context, apiPath: string) => LambderRenderContext;
package/dist/Lambder.js CHANGED
@@ -36,7 +36,12 @@ export const createContext = (event, lambdaContext, apiPath) => {
36
36
  get, post, cookie,
37
37
  apiName, apiPayload,
38
38
  headers, session, lambdaContext,
39
- _otherInternal: { isApiCall, sessionCookieHeader: null }
39
+ _otherInternal: {
40
+ isApiCall,
41
+ setHeaderFnAccumulator: [],
42
+ addHeaderFnAccumulator: [],
43
+ logToApiResponseAccumulator: [],
44
+ }
40
45
  };
41
46
  };
42
47
  export default class Lambder {
@@ -207,13 +212,13 @@ export default class Lambder {
207
212
  });
208
213
  }
209
214
  ;
210
- getResolver(resolve, reject) {
215
+ getResolver(ctx, resolve, reject) {
211
216
  return new LambderResolver({
212
217
  isCorsEnabled: this.isCorsEnabled,
213
218
  publicPath: this.publicPath,
214
219
  apiVersion: this.apiVersion,
215
220
  lambderUtils: this.utils,
216
- resolve, reject
221
+ ctx, resolve, reject
217
222
  });
218
223
  }
219
224
  ;
@@ -224,7 +229,7 @@ export default class Lambder {
224
229
  eventRenderContext = ctx;
225
230
  return await new Promise(async (resolve, reject) => {
226
231
  try {
227
- const resolver = this.getResolver(resolve, reject);
232
+ const resolver = this.getResolver(ctx, resolve, reject);
228
233
  if (ctx.method === "OPTIONS")
229
234
  return resolver.cors();
230
235
  const firstMatchedAction = this.actionList.find(action => action.conditionFn(ctx));
@@ -247,12 +252,14 @@ export default class Lambder {
247
252
  }
248
253
  response = hookResponse;
249
254
  }
250
- // Apply session cookie if needed.
251
- if ((ctx._otherInternal.sessionCookieHeader)) {
252
- response.multiValueHeaders = {
253
- ...(response.multiValueHeaders || {}),
254
- ...(ctx._otherInternal.sessionCookieHeader || {}),
255
- };
255
+ // Apply setHeader, addHeader values.
256
+ response.multiValueHeaders = response.multiValueHeaders || {};
257
+ for (const header of ctx._otherInternal.setHeaderFnAccumulator) {
258
+ response.multiValueHeaders[header.key] = Array.isArray(header.value) ? header.value : [header.value];
259
+ }
260
+ for (const header of ctx._otherInternal.addHeaderFnAccumulator) {
261
+ response.multiValueHeaders[header.key] = response.multiValueHeaders[header.key] || [];
262
+ response.multiValueHeaders[header.key].push(header.value);
256
263
  }
257
264
  resolve(response);
258
265
  }
@@ -270,7 +277,7 @@ export default class Lambder {
270
277
  if (this.globalErrorHandler) {
271
278
  const wrappedError = err instanceof Error ? err : new Error("Error: " + String(err));
272
279
  const responseBuilder = this.getResponseBuilder();
273
- return this.globalErrorHandler(wrappedError, eventRenderContext, responseBuilder);
280
+ return this.globalErrorHandler(wrappedError, eventRenderContext, responseBuilder, eventRenderContext?._otherInternal.logToApiResponseAccumulator);
274
281
  }
275
282
  return { statusCode: 500, body: "Internal Server Error.", };
276
283
  }
@@ -65,6 +65,11 @@ export default class LambderCaller {
65
65
  activeFetchList: this.fetchTrackerList.filter(v => !v.done),
66
66
  });
67
67
  }
68
+ if (data && data.logList?.length) {
69
+ for (const record of data.logList) {
70
+ console.log("LogToApiResponse:", record);
71
+ }
72
+ }
68
73
  if (data && data.versionExpired) {
69
74
  if (this.versionExpiredHandler) {
70
75
  await this.versionExpiredHandler();
@@ -1,3 +1,4 @@
1
+ import type { LambderRenderContext } from "./Lambder.js";
1
2
  import LambderResponseBuilder, { LambderResolverResponse } from "./LambderResponseBuilder.js";
2
3
  import LambderUtils from "./LambderUtils.js";
3
4
  type MethodType<T, M extends keyof T> = T[M] extends (...args: any[]) => any ? T[M] : never;
@@ -19,11 +20,12 @@ export default class LambderResolver extends LambderResponseBuilder {
19
20
  resolve: (response: LambderResolverResponse) => void;
20
21
  reject: (err: Error) => void;
21
22
  die: DieResolverMethods;
22
- constructor({ isCorsEnabled, publicPath, apiVersion, lambderUtils, resolve, reject }: {
23
+ constructor({ isCorsEnabled, publicPath, apiVersion, lambderUtils, ctx, resolve, reject }: {
23
24
  isCorsEnabled: boolean;
24
25
  publicPath: string;
25
26
  apiVersion?: string | null;
26
27
  lambderUtils: LambderUtils;
28
+ ctx: LambderRenderContext;
27
29
  resolve: (response: LambderResolverResponse) => void;
28
30
  reject: (err: Error) => void;
29
31
  });
@@ -3,8 +3,8 @@ export default class LambderResolver extends LambderResponseBuilder {
3
3
  resolve;
4
4
  reject;
5
5
  die;
6
- constructor({ isCorsEnabled, publicPath, apiVersion, lambderUtils, resolve, reject }) {
7
- super({ isCorsEnabled, publicPath, apiVersion, lambderUtils });
6
+ constructor({ isCorsEnabled, publicPath, apiVersion, lambderUtils, ctx, resolve, reject }) {
7
+ super({ isCorsEnabled, publicPath, apiVersion, lambderUtils, ctx, });
8
8
  this.resolve = resolve;
9
9
  this.reject = reject;
10
10
  this.die = {
@@ -1,4 +1,5 @@
1
1
  import LambderUtils from "./LambderUtils.js";
2
+ import { LambderRenderContext } from "./Lambder.js";
2
3
  export type LambderResolverResponse = {
3
4
  statusCode: number;
4
5
  multiValueHeaders?: Record<string, string[]>;
@@ -11,6 +12,7 @@ export type LambderApiResponseConfig = {
11
12
  notAuthorized?: boolean;
12
13
  message?: any;
13
14
  errorMessage?: any;
15
+ logList?: any[];
14
16
  };
15
17
  export type LambderApiResponse<T> = LambderApiResponseConfig & {
16
18
  payload?: T | null;
@@ -20,14 +22,19 @@ export default class LambderResponseBuilder {
20
22
  private publicPath;
21
23
  private apiVersion;
22
24
  private lambderUtils;
23
- constructor({ isCorsEnabled, publicPath, apiVersion, lambderUtils }: {
25
+ private ctx?;
26
+ constructor({ isCorsEnabled, publicPath, apiVersion, lambderUtils, ctx }: {
24
27
  isCorsEnabled: boolean;
25
28
  publicPath: string;
26
29
  apiVersion?: string | null;
27
30
  lambderUtils: LambderUtils;
31
+ ctx?: LambderRenderContext;
28
32
  });
29
33
  private readPublicFileSync;
30
34
  private checkPublicFileExist;
35
+ addHeader(key: string, value: string): void;
36
+ setHeader(key: string, value: string | string[]): void;
37
+ logToApiResponse(input: any): void;
31
38
  raw(param: LambderResolverResponse): LambderResolverResponse;
32
39
  json(data: Record<string, any>, headers?: Record<string, string | string[]>): LambderResolverResponse;
33
40
  xml(data: string): LambderResolverResponse;
@@ -39,5 +46,5 @@ export default class LambderResponseBuilder {
39
46
  file(filePath: string, headers?: Record<string, string | string[]>, fallbackFilePath?: string): LambderResolverResponse;
40
47
  ejsTemplate(template: string, pageData: Record<string, any>, headers?: Record<string, string | string[]>): Promise<LambderResolverResponse>;
41
48
  ejsFile(filePath: string, pageData: Record<string, any>, headers?: Record<string, string | string[]>): Promise<LambderResolverResponse>;
42
- api<T = any>(payload: T | null, { versionExpired, sessionExpired, notAuthorized, message, errorMessage, }?: LambderApiResponseConfig, headers?: Record<string, string | string[]>): LambderResolverResponse;
49
+ api<T = any>(payload: T | null, { versionExpired, sessionExpired, notAuthorized, message, errorMessage, logList, }?: LambderApiResponseConfig, headers?: Record<string, string | string[]>): LambderResolverResponse;
43
50
  }
@@ -13,11 +13,13 @@ export default class LambderResponseBuilder {
13
13
  publicPath;
14
14
  apiVersion;
15
15
  lambderUtils;
16
- constructor({ isCorsEnabled, publicPath, apiVersion, lambderUtils }) {
16
+ ctx;
17
+ constructor({ isCorsEnabled, publicPath, apiVersion, lambderUtils, ctx }) {
17
18
  this.isCorsEnabled = isCorsEnabled;
18
19
  this.publicPath = publicPath;
19
20
  this.apiVersion = apiVersion ?? null;
20
21
  this.lambderUtils = lambderUtils;
22
+ this.ctx = ctx;
21
23
  }
22
24
  ;
23
25
  readPublicFileSync(filePath) {
@@ -40,6 +42,32 @@ export default class LambderResponseBuilder {
40
42
  return fs.existsSync(absolutePath) && fs.statSync(absolutePath).isFile();
41
43
  }
42
44
  ;
45
+ addHeader(key, value) {
46
+ if (!this.ctx)
47
+ throw new Error(".addHeader function is not available within this hook");
48
+ else {
49
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key, value });
50
+ }
51
+ }
52
+ ;
53
+ setHeader(key, value) {
54
+ if (!this.ctx)
55
+ throw new Error(".setHeader function is not available within this hook");
56
+ else {
57
+ this.ctx._otherInternal.addHeaderFnAccumulator = this.ctx._otherInternal.addHeaderFnAccumulator
58
+ .filter(header => header.key !== key);
59
+ this.ctx._otherInternal.setHeaderFnAccumulator.push({ key, value });
60
+ }
61
+ }
62
+ ;
63
+ logToApiResponse(input) {
64
+ if (!this.ctx)
65
+ throw new Error(".logToResponse function is not available within this hook");
66
+ else {
67
+ this.ctx._otherInternal.logToApiResponseAccumulator.push(input);
68
+ }
69
+ }
70
+ ;
43
71
  raw(param) {
44
72
  return param;
45
73
  }
@@ -141,10 +169,11 @@ export default class LambderResponseBuilder {
141
169
  });
142
170
  }
143
171
  ;
144
- api(payload, { versionExpired, sessionExpired, notAuthorized, message = null, errorMessage = null, } = {
172
+ api(payload, { versionExpired, sessionExpired, notAuthorized, message, errorMessage, logList, } = {
145
173
  versionExpired: undefined, sessionExpired: undefined, notAuthorized: undefined,
146
- message: null, errorMessage: null,
174
+ message: null, errorMessage: null, logList: undefined
147
175
  }, headers) {
176
+ const finalLogList = logList || this.ctx?._otherInternal?.logToApiResponseAccumulator;
148
177
  return this.json({
149
178
  apiVersion: this.apiVersion,
150
179
  payload,
@@ -153,6 +182,7 @@ export default class LambderResponseBuilder {
153
182
  ...(notAuthorized ? { notAuthorized } : {}),
154
183
  ...(message ? { message } : {}),
155
184
  ...(errorMessage ? { errorMessage } : {}),
185
+ ...(finalLogList?.length ? { logList: finalLogList } : {}),
156
186
  }, headers);
157
187
  }
158
188
  ;
@@ -25,12 +25,8 @@ export default class LambderSessionController {
25
25
  ;
26
26
  async createSession(sessionKey, data, ttlInSeconds) {
27
27
  const session = await this.lambderSessionManager.createSession(sessionKey, data, ttlInSeconds);
28
- this.ctx._otherInternal.sessionCookieHeader = {
29
- "Set-Cookie": [
30
- `${this.sessionTokenCookieKey}=${session.sessionToken}; Expires=${new Date(session.expiresAt * 1000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
31
- `${this.sessionCsrfCookieKey}=${session.csrfToken}; Expires=${new Date(session.expiresAt * 1000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
32
- ],
33
- };
28
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key: "Set-Cookie", value: `${this.sessionTokenCookieKey}=${session.sessionToken}; Expires=${new Date(session.expiresAt * 1000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure` });
29
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key: "Set-Cookie", value: `${this.sessionCsrfCookieKey}=${session.csrfToken}; Expires=${new Date(session.expiresAt * 1000).toUTCString()}; Path=/; SameSite=Lax; Secure` });
34
30
  this.ctx.session = session;
35
31
  return this.ctx.session;
36
32
  }
@@ -83,12 +79,8 @@ export default class LambderSessionController {
83
79
  if (!this.ctx.session)
84
80
  throw new Error("Session not found.");
85
81
  await this.lambderSessionManager.deleteSession(this.ctx.session);
86
- this.ctx._otherInternal.sessionCookieHeader = {
87
- "Set-Cookie": [
88
- `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
89
- `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
90
- ],
91
- };
82
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key: "Set-Cookie", value: `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure` });
83
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key: "Set-Cookie", value: `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure` });
92
84
  this.ctx.session = null;
93
85
  }
94
86
  ;
@@ -96,12 +88,8 @@ export default class LambderSessionController {
96
88
  if (!this.ctx.session)
97
89
  throw new Error("Session not found.");
98
90
  await this.lambderSessionManager.deleteSessionAll(this.ctx.session);
99
- this.ctx._otherInternal.sessionCookieHeader = {
100
- "Set-Cookie": [
101
- `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
102
- `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
103
- ],
104
- };
91
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key: "Set-Cookie", value: `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure` });
92
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key: "Set-Cookie", value: `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure` });
105
93
  this.ctx.session = null;
106
94
  }
107
95
  ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lambder",
3
- "version": "1.0.122",
3
+ "version": "1.0.124",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/Lambder.ts CHANGED
@@ -26,7 +26,9 @@ export type LambderRenderContext = {
26
26
  lambdaContext: Context;
27
27
  _otherInternal: {
28
28
  isApiCall: boolean,
29
- sessionCookieHeader: null|Record<"Set-Cookie",string[]>
29
+ setHeaderFnAccumulator: { key:string, value:string|string[] }[];
30
+ addHeaderFnAccumulator: { key:string, value:string }[];
31
+ logToApiResponseAccumulator: any[];
30
32
  };
31
33
  };
32
34
 
@@ -42,7 +44,7 @@ type HookBeforeRenderFunction = (ctx: LambderRenderContext, resolver: LambderRes
42
44
  type HookAfterRenderFunction = (ctx: LambderRenderContext, resolver: LambderResolver, response: LambderResolverResponse) => LambderResolverResponse|Error|Promise<LambderResolverResponse|Error>;
43
45
  type HookFallbackFunction = (ctx: LambderRenderContext, resolver: LambderResolver) => void|Promise<void>;
44
46
 
45
- type GlobalErrorHandlerFunction = (err: Error, ctx: LambderRenderContext|null, response: LambderResponseBuilder) => LambderResolverResponse|Promise<LambderResolverResponse>;
47
+ type GlobalErrorHandlerFunction = (err: Error, ctx: LambderRenderContext|null, response: LambderResponseBuilder, logListToApiResponse?: any[]) => LambderResolverResponse|Promise<LambderResolverResponse>;
46
48
  type RouteFallbackHandlerFunction = (ctx:LambderRenderContext, resolver: LambderResolver) => LambderResolverResponse;
47
49
  type ApiFallbackHandlerFunction = (ctx:LambderRenderContext, resolver: LambderResolver) => LambderResolverResponse;
48
50
 
@@ -79,7 +81,12 @@ export const createContext = (
79
81
  get, post, cookie,
80
82
  apiName, apiPayload,
81
83
  headers, session, lambdaContext,
82
- _otherInternal: { isApiCall, sessionCookieHeader: null }
84
+ _otherInternal: {
85
+ isApiCall,
86
+ setHeaderFnAccumulator: [],
87
+ addHeaderFnAccumulator: [],
88
+ logToApiResponseAccumulator: [],
89
+ }
83
90
  };
84
91
  }
85
92
 
@@ -296,13 +303,17 @@ export default class Lambder {
296
303
  });
297
304
  };
298
305
 
299
- private getResolver(resolve: (response: LambderResolverResponse) => void, reject: (err: Error) => void){
306
+ private getResolver(
307
+ ctx: LambderRenderContext,
308
+ resolve: (response: LambderResolverResponse) => void,
309
+ reject: (err: Error) => void
310
+ ){
300
311
  return new LambderResolver({
301
312
  isCorsEnabled: this.isCorsEnabled,
302
313
  publicPath: this.publicPath,
303
314
  apiVersion: this.apiVersion,
304
315
  lambderUtils: this.utils,
305
- resolve, reject
316
+ ctx, resolve, reject
306
317
  });
307
318
  };
308
319
 
@@ -313,7 +324,6 @@ export default class Lambder {
313
324
  let eventRenderContext:LambderRenderContext|null = null;
314
325
 
315
326
  try {
316
-
317
327
  let ctx = createContext(event, lambdaContext, this.apiPath);
318
328
  eventRenderContext = ctx;
319
329
 
@@ -322,7 +332,7 @@ export default class Lambder {
322
332
  reject:(err: Error)=>void
323
333
  )=> {
324
334
  try{
325
- const resolver = this.getResolver(resolve, reject);
335
+ const resolver = this.getResolver(ctx, resolve, reject);
326
336
  if(ctx.method === "OPTIONS") return resolver.cors();
327
337
 
328
338
  const firstMatchedAction = this.actionList.find(action => action.conditionFn(ctx));
@@ -341,12 +351,14 @@ export default class Lambder {
341
351
  if(hookResponse instanceof Error){ throw hookResponse; }
342
352
  response = hookResponse;
343
353
  }
344
- // Apply session cookie if needed.
345
- if((ctx._otherInternal.sessionCookieHeader)){
346
- response.multiValueHeaders = {
347
- ...(response.multiValueHeaders || {}),
348
- ...(ctx._otherInternal.sessionCookieHeader || {}),
349
- }
354
+ // Apply setHeader, addHeader values.
355
+ response.multiValueHeaders = response.multiValueHeaders || {};
356
+ for(const header of ctx._otherInternal.setHeaderFnAccumulator){
357
+ response.multiValueHeaders[header.key] = Array.isArray(header.value) ? header.value: [header.value];
358
+ }
359
+ for(const header of ctx._otherInternal.addHeaderFnAccumulator){
360
+ response.multiValueHeaders[header.key] = response.multiValueHeaders[header.key] || [];
361
+ response.multiValueHeaders[header.key].push(header.value);
350
362
  }
351
363
  resolve(response);
352
364
  }else{
@@ -362,7 +374,12 @@ export default class Lambder {
362
374
  if(this.globalErrorHandler){
363
375
  const wrappedError = err instanceof Error ? err : new Error("Error: " + String(err));
364
376
  const responseBuilder = this.getResponseBuilder();
365
- return this.globalErrorHandler(wrappedError, eventRenderContext, responseBuilder);
377
+ return this.globalErrorHandler(
378
+ wrappedError,
379
+ eventRenderContext,
380
+ responseBuilder,
381
+ eventRenderContext?._otherInternal.logToApiResponseAccumulator
382
+ );
366
383
  }
367
384
  return { statusCode: 500, body: "Internal Server Error.", }
368
385
 
@@ -130,6 +130,11 @@ export default class LambderCaller {
130
130
  activeFetchList: this.fetchTrackerList.filter(v=>!v.done),
131
131
  });
132
132
  }
133
+ if(data && data.logList?.length){
134
+ for(const record of data.logList){
135
+ console.log("LogToApiResponse:", record);
136
+ }
137
+ }
133
138
  if(data && data.versionExpired){
134
139
  if(this.versionExpiredHandler){
135
140
  await this.versionExpiredHandler();
@@ -1,3 +1,4 @@
1
+ import type { LambderRenderContext } from "./Lambder.js";
1
2
  import LambderResponseBuilder, { LambderResolverResponse } from "./LambderResponseBuilder.js";
2
3
  import LambderUtils from "./LambderUtils.js";
3
4
 
@@ -24,17 +25,18 @@ export default class LambderResolver extends LambderResponseBuilder {
24
25
  public die: DieResolverMethods;
25
26
 
26
27
  constructor(
27
- { isCorsEnabled, publicPath, apiVersion, lambderUtils, resolve, reject }:
28
+ { isCorsEnabled, publicPath, apiVersion, lambderUtils, ctx, resolve, reject }:
28
29
  {
29
30
  isCorsEnabled: boolean,
30
31
  publicPath: string,
31
32
  apiVersion?: string|null,
32
- lambderUtils: LambderUtils
33
+ lambderUtils: LambderUtils,
34
+ ctx: LambderRenderContext,
33
35
  resolve: (response: LambderResolverResponse) => void,
34
36
  reject: (err: Error) => void,
35
37
  }
36
38
  ){
37
- super({ isCorsEnabled, publicPath, apiVersion, lambderUtils });
39
+ super({ isCorsEnabled, publicPath, apiVersion, lambderUtils, ctx, });
38
40
  this.resolve = resolve;
39
41
  this.reject = reject;
40
42
 
@@ -3,6 +3,7 @@ import * as path from "path";
3
3
  import ejs from "ejs";
4
4
  import mimeTypeResolver from "mime-types";
5
5
  import LambderUtils from "./LambderUtils.js";
6
+ import { LambderRenderContext } from "./Lambder.js";
6
7
 
7
8
  const convertToMultiHeader = (
8
9
  headers: Record<string, string|string[]> | undefined
@@ -29,6 +30,7 @@ export type LambderApiResponseConfig = {
29
30
  notAuthorized?: boolean;
30
31
  message?: any;
31
32
  errorMessage?: any;
33
+ logList?: any[];
32
34
  }
33
35
 
34
36
 
@@ -41,20 +43,23 @@ export default class LambderResponseBuilder {
41
43
  private publicPath: string;
42
44
  private apiVersion: string|null;
43
45
  private lambderUtils: LambderUtils;
46
+ private ctx?: LambderRenderContext;
44
47
 
45
48
  constructor(
46
- { isCorsEnabled, publicPath, apiVersion, lambderUtils }:
49
+ { isCorsEnabled, publicPath, apiVersion, lambderUtils, ctx }:
47
50
  {
48
51
  isCorsEnabled: boolean,
49
52
  publicPath: string,
50
53
  apiVersion?: string|null,
51
- lambderUtils: LambderUtils
54
+ lambderUtils: LambderUtils,
55
+ ctx?: LambderRenderContext,
52
56
  }
53
57
  ){
54
58
  this.isCorsEnabled = isCorsEnabled;
55
59
  this.publicPath = publicPath;
56
60
  this.apiVersion = apiVersion ?? null;
57
61
  this.lambderUtils = lambderUtils;
62
+ this.ctx = ctx;
58
63
  };
59
64
 
60
65
  private readPublicFileSync(filePath: string){
@@ -73,6 +78,29 @@ export default class LambderResponseBuilder {
73
78
  return fs.existsSync(absolutePath) && fs.statSync(absolutePath).isFile();
74
79
  };
75
80
 
81
+ addHeader(key: string, value: string){
82
+ if(!this.ctx) throw new Error(".addHeader function is not available within this hook");
83
+ else{
84
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key, value });
85
+ }
86
+ };
87
+
88
+ setHeader(key: string, value: string|string[]){
89
+ if(!this.ctx) throw new Error(".setHeader function is not available within this hook");
90
+ else{
91
+ this.ctx._otherInternal.addHeaderFnAccumulator = this.ctx._otherInternal.addHeaderFnAccumulator
92
+ .filter(header=>header.key !== key);
93
+ this.ctx._otherInternal.setHeaderFnAccumulator.push({ key, value });
94
+ }
95
+ };
96
+
97
+ logToApiResponse(input:any){
98
+ if(!this.ctx) throw new Error(".logToResponse function is not available within this hook");
99
+ else{
100
+ this.ctx._otherInternal.logToApiResponseAccumulator.push(input);
101
+ }
102
+ };
103
+
76
104
 
77
105
  raw(param: LambderResolverResponse){
78
106
  return param;
@@ -210,13 +238,14 @@ export default class LambderResponseBuilder {
210
238
  payload: T | null,
211
239
  {
212
240
  versionExpired, sessionExpired, notAuthorized,
213
- message = null, errorMessage = null,
241
+ message, errorMessage, logList,
214
242
  }: LambderApiResponseConfig = {
215
243
  versionExpired: undefined, sessionExpired: undefined, notAuthorized: undefined,
216
- message: null, errorMessage: null,
244
+ message: null, errorMessage: null, logList: undefined
217
245
  },
218
246
  headers?: Record<string, string|string[]>,
219
247
  ): LambderResolverResponse {
248
+ const finalLogList = logList || this.ctx?._otherInternal?.logToApiResponseAccumulator;
220
249
  return this.json({
221
250
  apiVersion: this.apiVersion,
222
251
  payload,
@@ -225,6 +254,7 @@ export default class LambderResponseBuilder {
225
254
  ...(notAuthorized ? {notAuthorized} : {}),
226
255
  ...(message ? {message} : {}),
227
256
  ...(errorMessage ? {errorMessage} : {}),
257
+ ...(finalLogList?.length ? {logList: finalLogList} : {}),
228
258
  }, headers);
229
259
  };
230
260
 
@@ -42,12 +42,8 @@ export default class LambderSessionController {
42
42
 
43
43
  async createSession (sessionKey: string, data?: any, ttlInSeconds?: number): Promise<LambderSessionContext> {
44
44
  const session = await this.lambderSessionManager.createSession(sessionKey, data, ttlInSeconds);
45
- this.ctx._otherInternal.sessionCookieHeader = {
46
- "Set-Cookie": [
47
- `${this.sessionTokenCookieKey}=${session.sessionToken}; Expires=${new Date(session.expiresAt * 1000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
48
- `${this.sessionCsrfCookieKey}=${session.csrfToken}; Expires=${new Date(session.expiresAt * 1000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
49
- ],
50
- };
45
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key: "Set-Cookie", value: `${this.sessionTokenCookieKey}=${session.sessionToken}; Expires=${new Date(session.expiresAt * 1000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure` });
46
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key: "Set-Cookie", value: `${this.sessionCsrfCookieKey}=${session.csrfToken}; Expires=${new Date(session.expiresAt * 1000).toUTCString()}; Path=/; SameSite=Lax; Secure` });
51
47
  this.ctx.session = session;
52
48
  return this.ctx.session;
53
49
  };
@@ -94,24 +90,16 @@ export default class LambderSessionController {
94
90
  async endSession (){
95
91
  if(!this.ctx.session) throw new Error("Session not found.");
96
92
  await this.lambderSessionManager.deleteSession(this.ctx.session);
97
- this.ctx._otherInternal.sessionCookieHeader = {
98
- "Set-Cookie": [
99
- `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
100
- `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
101
- ],
102
- };
93
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key: "Set-Cookie", value: `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure` });
94
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key: "Set-Cookie", value: `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure` });
103
95
  this.ctx.session = null
104
96
  };
105
97
 
106
98
  async endSessionAll (){
107
99
  if(!this.ctx.session) throw new Error("Session not found.");
108
100
  await this.lambderSessionManager.deleteSessionAll(this.ctx.session);
109
- this.ctx._otherInternal.sessionCookieHeader = {
110
- "Set-Cookie": [
111
- `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
112
- `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
113
- ],
114
- };
101
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key: "Set-Cookie", value: `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure` });
102
+ this.ctx._otherInternal.addHeaderFnAccumulator.push({ key: "Set-Cookie", value: `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure` });
115
103
  this.ctx.session = null
116
104
  };
117
105
  };
File without changes