@63klabs/cache-data 1.3.4 → 1.3.6

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.
@@ -7,19 +7,28 @@ const textGenericResponse = require('./generic.response.text');
7
7
  const ClientRequest = require('./ClientRequest.class');
8
8
  const DebugAndLog = require('./DebugAndLog.class');
9
9
 
10
- /*
11
- Example Response
12
- statusCode: 404,
13
- headers: {
14
- "Access-Control-Allow-Origin": "*",
15
- "Content-Type": "application/json"
16
- },
17
- body: {
18
- message: "Not Found"
19
- }
20
- */
21
10
  /**
22
- * Can be used to create a custom Response interface
11
+ * Response class for creating and managing HTTP responses with support for multiple content types.
12
+ * Provides methods to build, customize, and finalize responses for Lambda functions or web services.
13
+ * Supports JSON, HTML, XML, RSS, and TEXT content types with automatic content type detection.
14
+ *
15
+ * @class Response
16
+ * @example
17
+ * // Create a JSON response
18
+ * const response = new Response(clientRequest);
19
+ * response.setStatusCode(200);
20
+ * response.setBody({ message: 'Success', data: results });
21
+ * return response.finalize();
22
+ *
23
+ * @example
24
+ * // Initialize Response class with custom settings
25
+ * Response.init({
26
+ * settings: {
27
+ * errorExpirationInSeconds: 180,
28
+ * routeExpirationInSeconds: 3600,
29
+ * contentType: Response.CONTENT_TYPE.JSON
30
+ * }
31
+ * });
23
32
  */
24
33
  class Response {
25
34
 
@@ -54,8 +63,16 @@ class Response {
54
63
  _body = null;
55
64
 
56
65
  /**
57
- * @param {ClientRequest} clientRequest
58
- * @param {{statusCode: number, headers: object, body: string|number|object|array }} obj Default structure.
66
+ * Creates a new Response instance.
67
+ *
68
+ * @param {ClientRequest} clientRequest - The client request object associated with this response
69
+ * @param {{statusCode: number, headers: Object, body: string|number|Object|Array}} [obj={}] - Initial response structure
70
+ * @param {string} [contentType=null] - Content type for the response (e.g., Response.CONTENT_TYPE.JSON)
71
+ * @example
72
+ * const response = new Response(clientRequest, { statusCode: 200, body: { success: true } });
73
+ *
74
+ * @example
75
+ * const response = new Response(clientRequest, {}, Response.CONTENT_TYPE.HTML);
59
76
  */
60
77
  constructor(clientRequest, obj = {}, contentType = null) {
61
78
  this._clientRequest = clientRequest;
@@ -70,13 +87,26 @@ class Response {
70
87
  */
71
88
 
72
89
  /**
73
- * Initialize the Response class for all responses.
74
- * Add Response.init(options) to the Config.init process or at the
75
- * top of the main index.js file outside of the handler.
76
- * @param {number} options.settings.errorExpirationInSeconds
77
- * @param {number} options.settings.routeExpirationInSeconds
78
- * @param {string} options.settings.contentType Any one of available Response.CONTENT_TYPE values
79
- * @param {{response200: statusResponseObject, response404: statusResponseObject, response500: statusResponseObject}} options.jsonResponses
90
+ * Initializes the Response class with custom settings and response templates.
91
+ * Should be called once during application initialization, typically in Config.init() or at the top of index.js.
92
+ *
93
+ * @param {Object} options - Configuration options with settings, jsonResponses, htmlResponses, xmlResponses, rssResponses, and textResponses properties
94
+ * @returns {void}
95
+ * @example
96
+ * Response.init({
97
+ * settings: {
98
+ * errorExpirationInSeconds: 300,
99
+ * routeExpirationInSeconds: 3600,
100
+ * contentType: Response.CONTENT_TYPE.JSON
101
+ * },
102
+ * jsonResponses: {
103
+ * response404: {
104
+ * statusCode: 404,
105
+ * headers: { 'Content-Type': 'application/json' },
106
+ * body: { error: 'Resource not found' }
107
+ * }
108
+ * }
109
+ * });
80
110
  */
81
111
  static init = (options) => {
82
112
  if (!Response.#isInitialized) {
@@ -122,11 +152,17 @@ class Response {
122
152
  };
123
153
 
124
154
  /**
125
- * Reset all properties of the response back to default values except for
126
- * those properties specified in the object. Note that ClientRequest
127
- * cannot be reset.
128
- * @param {{statusCode: number|string, headers: object, body: string|number|object|array}} obj
129
- * @param {string} contentType Accepted values may be obtained from Response.CONTENT_TYPES[JSON|HTML|XML|RSS|TEXT]
155
+ * Resets all properties of the response to default values except those specified in the object.
156
+ * ClientRequest cannot be reset. Uses generic response templates based on status code.
157
+ *
158
+ * @param {{statusCode: number|string, headers: Object, body: string|number|Object|Array}} obj - Properties to set after reset
159
+ * @param {string} [contentType=null] - Content type (use Response.CONTENT_TYPE values)
160
+ * @returns {void}
161
+ * @example
162
+ * response.reset({ statusCode: 404 });
163
+ *
164
+ * @example
165
+ * response.reset({ statusCode: 200, body: { data: results } }, Response.CONTENT_TYPE.JSON);
130
166
  */
131
167
  reset = (obj, contentType = null) => {
132
168
 
@@ -148,10 +184,17 @@ class Response {
148
184
  };
149
185
 
150
186
  /**
151
- * Set the properties of the response. This will overwrite only properties
152
- * supplied in the new object. Use .reset if you wish to clear out all properties even
153
- * if not explicitly set in the object. ClientRequest cannot be set.
154
- * @param {{statusCode: number|string, headers: object, body: string|number|object|array}} obj
187
+ * Sets properties of the response, overwriting only the supplied properties.
188
+ * Use reset() to clear all properties. ClientRequest cannot be set.
189
+ *
190
+ * @param {{statusCode: number|string, headers: Object, body: string|number|Object|Array}} obj - Properties to set
191
+ * @param {string} [contentType=null] - Content type (use Response.CONTENT_TYPE values)
192
+ * @returns {void}
193
+ * @example
194
+ * response.set({ statusCode: 201, body: { id: newId } });
195
+ *
196
+ * @example
197
+ * response.set({ headers: { 'X-Custom-Header': 'value' } });
155
198
  */
156
199
  set = (obj, contentType = null) => {
157
200
 
@@ -169,57 +212,88 @@ class Response {
169
212
  }
170
213
 
171
214
  /**
215
+ * Gets the current status code of the response.
172
216
  *
173
- * @returns {number} Current statusCode of the Response
217
+ * @returns {number} Current status code
218
+ * @example
219
+ * const statusCode = response.getStatusCode();
220
+ * console.log(`Response status: ${statusCode}`);
174
221
  */
175
222
  getStatusCode = () => {
176
223
  return this._statusCode;
177
224
  };
178
225
 
179
226
  /**
227
+ * Gets the current headers of the response.
180
228
  *
181
- * @returns {object} Current headers of the Response
229
+ * @returns {Object} Current headers object
230
+ * @example
231
+ * const headers = response.getHeaders();
232
+ * console.log(headers['Content-Type']);
182
233
  */
183
234
  getHeaders = () => {
184
235
  return this._headers;
185
236
  };
186
237
 
187
238
  /**
239
+ * Gets the current body of the response.
188
240
  *
189
- * @returns {object|array|string|number|null} Current body of the Response
241
+ * @returns {Object|Array|string|number|null} Current body content
242
+ * @example
243
+ * const body = response.getBody();
244
+ * console.log(body);
190
245
  */
191
246
  getBody = () => {
192
247
  return this._body;
193
248
  };
194
249
 
195
250
  /**
251
+ * Gets the default content type from settings.
196
252
  *
197
- * @returns {string} Current ContentType of the Response
253
+ * @returns {string} Default content type string
254
+ * @example
255
+ * const contentType = Response.getContentType();
256
+ * console.log(`Default content type: ${contentType}`);
198
257
  */
199
258
  static getContentType() {
200
259
  return Response.#settings.contentType;
201
260
  };
202
261
 
203
262
  /**
204
- *
205
- * @returns {number} Current errorExpirationInSeconds of the Response
263
+ * Gets the error expiration time in seconds from settings.
264
+ *
265
+ * @returns {number} Error expiration time in seconds
266
+ * @example
267
+ * const expiration = Response.getErrorExpirationInSeconds();
268
+ * console.log(`Error cache expires in ${expiration} seconds`);
206
269
  */
207
270
  static getErrorExpirationInSeconds() {
208
271
  return Response.#settings.errorExpirationInSeconds;
209
272
  };
210
273
 
211
274
  /**
212
- *
213
- * @returns {number} Current routeExpirationInSeconds of the Response
275
+ * Gets the route expiration time in seconds from settings.
276
+ *
277
+ * @returns {number} Route expiration time in seconds
278
+ * @example
279
+ * const expiration = Response.getRouteExpirationInSeconds();
280
+ * console.log(`Route cache expires in ${expiration} seconds`);
214
281
  */
215
282
  static getRouteExpirationInSeconds() {
216
283
  return Response.#settings.routeExpirationInSeconds;
217
284
  };
218
285
 
219
286
  /**
220
- * Static method to inspect the body and headers to determine the ContentType. Used by the internal methods.
221
- * @param {{headers: object, body: object|array|string|number|null}} obj Object to inspect
222
- * @returns {string|null} The ContentType as determined after inspecting the headers and body
287
+ * Inspects the body and headers to determine the content type.
288
+ * Checks headers first, then body content.
289
+ *
290
+ * @param {{headers: Object, body: Object|Array|string|number|null}} obj - Object to inspect
291
+ * @returns {string|null} The determined content type, or null if cannot be determined
292
+ * @example
293
+ * const contentType = Response.inspectContentType({
294
+ * headers: { 'Content-Type': 'application/json' },
295
+ * body: { data: 'test' }
296
+ * });
223
297
  */
224
298
  static inspectContentType = (obj) => {
225
299
  const headerResult = Response.inspectHeaderContentType(obj.headers);
@@ -228,9 +302,14 @@ class Response {
228
302
  }
229
303
 
230
304
  /**
231
- * Static method to inspect the body to determine the ContentType. Used by the internal methods.
232
- * @param {object|array|string|number|null} body
233
- * @returns {string|null} The ContentType as determined after inspecting just the body
305
+ * Inspects the body to determine the content type based on content.
306
+ * Detects HTML, RSS, XML, TEXT, or JSON based on body structure.
307
+ *
308
+ * @param {Object|Array|string|number|null} body - Body content to inspect
309
+ * @returns {string|null} The determined content type, or null if body is null
310
+ * @example
311
+ * const contentType = Response.inspectBodyContentType('<html></html>');
312
+ * // Returns Response.CONTENT_TYPE.HTML
234
313
  */
235
314
  static inspectBodyContentType = (body) => {
236
315
  if (body !== null) {
@@ -252,41 +331,60 @@ class Response {
252
331
  }
253
332
 
254
333
  /**
255
- * Static method to inspect the headers to determine the ContentType. Used by the internal methods.
256
- * @param {object} headers
257
- * @returns {string|null} The ContentType as determined after inspecting just the headers
334
+ * Inspects the headers to determine the content type.
335
+ *
336
+ * @param {Object} headers - Headers object to inspect
337
+ * @returns {string|null} The content type from headers, or null if not found
338
+ * @example
339
+ * const contentType = Response.inspectHeaderContentType({ 'Content-Type': 'application/json' });
258
340
  */
259
341
  static inspectHeaderContentType = (headers) => {
260
342
  return (headers && 'Content-Type' in headers ? headers['Content-Type'] : null);
261
343
  }
262
344
 
263
345
  /**
264
- * Inspect the content type of this Response. Passes this headers and this body to the static method
265
- * @returns {string|null} The ContentType as determined after inspecting the headers and body
346
+ * Inspects this response's content type by checking headers and body.
347
+ *
348
+ * @returns {string|null} The determined content type, or null if cannot be determined
349
+ * @example
350
+ * const contentType = response.inspectContentType();
266
351
  */
267
352
  inspectContentType = () => {
268
353
  return Response.inspectContentType({headers: this._headers, body: this._body});
269
354
  }
270
355
 
271
356
  /**
272
- * Inspect the body to determine the ContentType. Passes this body to the static method
273
- * @returns {string} ContentType string value determined from the current body
357
+ * Inspects this response's body to determine content type.
358
+ *
359
+ * @returns {string|null} Content type determined from the current body
360
+ * @example
361
+ * response.setBody({ data: 'test' });
362
+ * const contentType = response.inspectBodyContentType();
363
+ * // Returns Response.CONTENT_TYPE.JSON
274
364
  */
275
365
  inspectBodyContentType = () => {
276
366
  return Response.inspectBodyContentType(this._body);
277
367
  }
278
368
 
279
369
  /**
280
- * Inspect the headers to determine the ContentType. Passes this headers to the static method
281
- * @returns {string} ContentType string value determined from the current headers
370
+ * Inspects this response's headers to determine content type.
371
+ *
372
+ * @returns {string|null} Content type determined from the current headers
373
+ * @example
374
+ * const contentType = response.inspectHeaderContentType();
282
375
  */
283
376
  inspectHeaderContentType = () => {
284
377
  return Response.inspectHeaderContentType(this._headers);
285
378
  }
286
379
 
287
380
  /**
288
- * Get the current ContentType of the response. Inspects headers and body to determine ContentType. Returns the default from init if none is determined.
289
- * @returns {string} ContentType string value determined from the header or current body
381
+ * Gets the current content type of the response by inspecting headers and body.
382
+ * Returns the default content type from settings if none is determined.
383
+ *
384
+ * @returns {string} Content type string value
385
+ * @example
386
+ * const contentType = response.getContentType();
387
+ * console.log(`Response content type: ${contentType}`);
290
388
  */
291
389
  getContentType = () => {
292
390
  // Default content type is JSON
@@ -299,8 +397,13 @@ class Response {
299
397
  };
300
398
 
301
399
  /**
302
- * Get the content type code for the response. This is the key for the CONTENT_TYPE object.
303
- * @returns {string}
400
+ * Gets the content type code (key) for the response.
401
+ * Returns the key from CONTENT_TYPE object that matches the current content type.
402
+ *
403
+ * @returns {string} Content type code (e.g., 'JSON', 'HTML', 'XML')
404
+ * @example
405
+ * const code = response.getContentTypeCode();
406
+ * // Returns 'JSON' if content type is 'application/json'
304
407
  */
305
408
  getContentTypeCode = () => {
306
409
  const contentTypeStr = this.getContentType();
@@ -314,33 +417,54 @@ class Response {
314
417
  }
315
418
 
316
419
  /**
317
- * Set the status code of the response. This will overwrite the status code of the response.
318
- * @param {number} statusCode
420
+ * Sets the status code of the response, overwriting the current value.
421
+ *
422
+ * @param {number} statusCode - HTTP status code (e.g., 200, 404, 500)
423
+ * @returns {void}
424
+ * @example
425
+ * response.setStatusCode(201);
319
426
  */
320
427
  setStatusCode = (statusCode) => {
321
428
  this.set({statusCode: statusCode});
322
429
  };
323
430
 
324
431
  /**
325
- * Set the headers of the response. This will overwrite the headers of the response.
326
- * @param {object} headers
432
+ * Sets the headers of the response, overwriting the current headers.
433
+ *
434
+ * @param {Object} headers - Headers object with key-value pairs
435
+ * @returns {void}
436
+ * @example
437
+ * response.setHeaders({ 'Content-Type': 'application/json', 'X-Custom': 'value' });
327
438
  */
328
439
  setHeaders = (headers) => {
329
440
  this.set({headers: headers});
330
441
  };
331
442
 
332
443
  /**
333
- * Set the body of the response. This will overwrite the body of the response.
334
- * @param {string|number|object|array} body
444
+ * Sets the body of the response, overwriting the current body.
445
+ *
446
+ * @param {string|number|Object|Array} body - Response body content
447
+ * @returns {void}
448
+ * @example
449
+ * response.setBody({ message: 'Success', data: results });
450
+ *
451
+ * @example
452
+ * response.setBody('<html><body>Hello</body></html>');
335
453
  */
336
454
  setBody = (body) => {
337
455
  this.set({body: body});
338
456
  };
339
457
 
340
458
  /**
341
- * Get the generic response for the content type. Generic responses are either provided by default from Cache-Data or loaded in during Response.init()
342
- * @param {string} contentType
343
- * @returns {statusResponseObject}
459
+ * Gets the generic response templates for the specified content type.
460
+ * Generic responses are either provided by default or loaded during Response.init().
461
+ *
462
+ * @param {string} contentType - Content type (use Response.CONTENT_TYPE values or codes like 'JSON', 'HTML')
463
+ * @returns {Object} Generic response object with response templates
464
+ * @throws {Error} If content type is not implemented
465
+ * @example
466
+ * const jsonResponses = Response.getGenericResponses(Response.CONTENT_TYPE.JSON);
467
+ * const response404 = jsonResponses.response(404);
344
468
  */
345
469
  static getGenericResponses = (contentType) => {
346
470
  if (contentType === Response.CONTENT_TYPE.JSON || contentType === 'JSON') {
@@ -359,17 +483,30 @@ class Response {
359
483
  }
360
484
 
361
485
  /**
362
- * Add a header if it does not exist, if it exists then update the value
363
- * @param {string} key
364
- * @param {string} value
486
+ * Adds or updates a header in the response.
487
+ * If the header exists, its value is updated; otherwise, it's added.
488
+ *
489
+ * @param {string} key - Header name
490
+ * @param {string} value - Header value
491
+ * @returns {void}
492
+ * @example
493
+ * response.addHeader('X-Request-ID', '12345');
494
+ * response.addHeader('Cache-Control', 'no-cache');
365
495
  */
366
496
  addHeader = (key, value) => {
367
497
  this._headers[key] = value;
368
498
  };
369
499
 
370
500
  /**
501
+ * Adds properties to the JSON body by merging with existing body.
502
+ * Only works if the current body is an object.
371
503
  *
372
- * @param {object} obj
504
+ * @param {Object} obj - Object with properties to add to the body
505
+ * @returns {void}
506
+ * @example
507
+ * response.setBody({ message: 'Success' });
508
+ * response.addToJsonBody({ timestamp: Date.now(), version: '1.0' });
509
+ * // Body is now: { message: 'Success', timestamp: ..., version: '1.0' }
373
510
  */
374
511
  addToJsonBody = (obj) => {
375
512
  if (typeof this._body === 'object') {
@@ -378,8 +515,12 @@ class Response {
378
515
  };
379
516
 
380
517
  /**
518
+ * Converts the response to a plain object.
381
519
  *
382
- * @returns {{statusCode: number, headers: object, body: null|string|Array|object}}
520
+ * @returns {{statusCode: number, headers: Object, body: null|string|Array|Object}} Response as object
521
+ * @example
522
+ * const obj = response.toObject();
523
+ * console.log(obj.statusCode, obj.headers, obj.body);
383
524
  */
384
525
  toObject = () => {
385
526
  return {
@@ -390,27 +531,45 @@ class Response {
390
531
  };
391
532
 
392
533
  /**
534
+ * Converts the response to a JSON string.
393
535
  *
394
- * @returns {string} A string representation of the Response object
536
+ * @returns {string} JSON string representation of the response
537
+ * @example
538
+ * const jsonString = response.toString();
539
+ * console.log(jsonString);
395
540
  */
396
541
  toString = () => {
397
542
  return JSON.stringify(this.toObject());
398
543
  };
399
544
 
400
545
  /**
401
- * Used by JSON.stringify to convert the response to a stringified object
402
- * @returns {{statusCode: number, headers: object, body: null|string|Array|object}} this class in object form ready for use by JSON.stringify
546
+ * Converts the response to an object for JSON.stringify().
547
+ * Used automatically by JSON.stringify when serializing the response.
548
+ *
549
+ * @returns {{statusCode: number, headers: Object, body: null|string|Array|Object}} Response as object
550
+ * @example
551
+ * const json = JSON.stringify(response);
403
552
  */
404
553
  toJSON = () => {
405
554
  return this.toObject();
406
555
  };
407
556
 
408
557
  /**
409
- * Send the response back to the client. If the body is an object or array, it will be stringified.
410
- * If the body is a string or number and the Content-Type header is json, it will be placed as a single element in an array then stringified.
411
- * If the body of the response is null it returns null
412
- * A response log entry is also created and sent to CloudWatch.
413
- * @returns {{statusCode: number, headers: object, body: string}} An object containing response data formatted to return from Lambda
558
+ * Finalizes and prepares the response for sending to the client.
559
+ * Handles body stringification, sets appropriate headers (CORS, caching, execution time),
560
+ * and logs the response to CloudWatch. If body is an object/array, it's stringified.
561
+ * For JSON responses, string/number bodies are wrapped in an array.
562
+ *
563
+ * @returns {{statusCode: number, headers: Object, body: string}} Finalized response ready for Lambda return
564
+ * @example
565
+ * response.setStatusCode(200);
566
+ * response.setBody({ data: results });
567
+ * return response.finalize();
568
+ *
569
+ * @example
570
+ * // Finalize handles errors automatically
571
+ * response.setBody(new Error('Something failed'));
572
+ * return response.finalize(); // Returns 500 error response
414
573
  */
415
574
  finalize = () => {
416
575
 
@@ -491,8 +650,13 @@ class Response {
491
650
  };
492
651
 
493
652
  /**
494
- * Log the ClientRequest and Response to CloudWatch
495
- * Formats a log entry parsing in CloudWatch Dashboard.
653
+ * Logs the ClientRequest and Response to CloudWatch.
654
+ * Formats a log entry for parsing in CloudWatch Dashboard with fields:
655
+ * statusCode, bytes, contentType, execms, clientIp, userAgent, origin, referrer, resource, queryKeys, routeLog, queryLog, apiKey.
656
+ *
657
+ * @param {string} bodyAsString - The stringified response body
658
+ * @returns {void}
659
+ * @private
496
660
  */
497
661
  _log(bodyAsString) {
498
662