@63klabs/cache-data 1.3.6 → 1.3.8

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.
@@ -44,19 +44,31 @@ const { Connections, Connection, ConnectionRequest, ConnectionAuthentication } =
44
44
  */
45
45
 
46
46
  /**
47
- * @typedef ConnectionObject
48
- * @property {object} connection A connection object
49
- * @property {string} connection.method GET or POST
50
- * @property {string} connection.uri the full uri (overrides protocol, host, path, and parameters) ex https://example.com/api/v1/1004/?key=asdf&y=4
51
- * @property {string} connection.protocol https
52
- * @property {string} connection.host host/domain: example.com
53
- * @property {string} connection.path path of the request: /api/v1/1004
54
- * @property {object} connection.parameters parameters for the query string as an object in key/value pairs
55
- * @property {object} connection.headers headers for the request as an object in key/value pairs
56
- * @property {string} connection.body for POST requests, the body
57
- * @property {string} connection.note a note for logging
58
- * @property {object} connection.options https_get options
59
- * @property {number} connection.options.timeout timeout in milliseconds
47
+ * @typedef {Object} ConnectionObject
48
+ * @property {string} method GET or POST
49
+ * @property {string} uri the full uri (overrides protocol, host, path, and parameters) ex https://example.com/api/v1/1004/?key=asdf&y=4
50
+ * @property {string} protocol https
51
+ * @property {string} host host/domain: example.com
52
+ * @property {string} path path of the request: /api/v1/1004
53
+ * @property {object} parameters parameters for the query string as an object in key/value pairs
54
+ * @property {object} headers headers for the request as an object in key/value pairs
55
+ * @property {string} body for POST requests, the body
56
+ * @property {string} note a note for logging
57
+ * @property {object} options https_get options
58
+ * @property {number} options.timeout timeout in milliseconds
59
+ * @property {CacheProfileObject[]} cache
60
+ */
61
+
62
+ /**
63
+ * @typedef {Object} CacheProfileObject
64
+ * @property {string} profile The name of the cache profile
65
+ * @property {boolean} overrideOriginHeaderExpiration If true, the cache expiration will be overridden by the origin header expiration
66
+ * @property {number} defaultExpirationInSeconds The default expiration time in seconds
67
+ * @property {boolean} expirationIsOnInterval If true, the cache expiration will be on an interval
68
+ * @property {array<string>} headersToRetain
69
+ * @property {string} hostId The host ID to use for the cache key
70
+ * @property {string} pathId The path ID to use for the cache key
71
+ * @property {boolean} encrypt If true, the cache data will be encrypted
60
72
  */
61
73
 
62
74
  /* ****************************************************************************
@@ -69,7 +81,7 @@ const { Connections, Connection, ConnectionRequest, ConnectionAuthentication } =
69
81
  *************************************************************************** */
70
82
 
71
83
  /**
72
- * _ConfigSuperClass needs to be extended by your own Config class definition.
84
+ * AppConfig needs to be extended by your own Config class definition.
73
85
  *
74
86
  * This super class holds common variables and methods that can be used by any
75
87
  * application. However, each application requires it's own methods and logic
@@ -80,36 +92,119 @@ const { Connections, Connection, ConnectionRequest, ConnectionAuthentication } =
80
92
  * initialized.
81
93
  *
82
94
  * @example
83
- * class Config extends tools._ConfigSuperClass {
95
+ * class Config extends tools.AppConfig {
84
96
  * // your custom class definition including your implementation of .init()
85
97
  * }
86
98
  *
87
99
  * Config.init();
88
100
  */
89
- class _ConfigSuperClass {
101
+ class AppConfig {
90
102
 
91
103
  static _promise = null;
104
+ static _promises = [];
92
105
  static _connections = null;
93
106
  static _settings = null;
107
+ static _ssmParameters = null;
108
+
109
+ /**
110
+ * Initialize the Config class
111
+ *
112
+ * @param {object} options Configuration options
113
+ * @param {object} options.settings Application settings retrieved by Config.settings()
114
+ * @param {ConnectionObject[]} options.connections Application connections that can then be retrieved by Config.getConn() or Config.getConnCacheProfile()
115
+ * @param {object} options.validations ClientRequest.init() options
116
+ * @param {object} options.responses Response.init() options
117
+ * @param {object} options.responses.settings
118
+ * @param {number} options.responses.settings.errorExpirationInSeconds
119
+ * @param {number} options.responses.settings.routeExpirationInSeconds
120
+ * @param {number} options.responses.settings.externalRequestHeadroomInMs
121
+ * @param {object} options.responses.jsonResponses
122
+ * @param {object} options.responses.htmlResponses
123
+ * @param {object} options.responses.xmlResponses
124
+ * @param {object} options.responses.rssResponses
125
+ * @param {object} options.responses.textResponses
126
+ * @param {object} options.ssmParameters Parameter Store
127
+ * @returns {Promise<void>}
128
+ * @example
129
+ * const { Config } = require("./config");
130
+ * Config.init({
131
+ * settings: {
132
+ * dataLimit: 1000,
133
+ * cacheTTL: 300
134
+ * },
135
+ * connections: {
136
+ * myConnection: {
137
+ * method: "GET",
138
+ * host: "example.com",
139
+ * path: "/api/v1/data",
140
+ * parameters: {
141
+ * limit: 100
142
+ * }
143
+ * }
144
+ * }
145
+ * });
146
+ */
147
+ static init(options = {}) {
148
+
149
+ try {
150
+
151
+ const debug = (options?.debug === true);
152
+ if (debug) {
153
+ DebugAndLog.debug("Config Init in debug mode");
154
+ }
155
+
156
+ if (options.settings) {
157
+ AppConfig._settings = options.settings;
158
+ if (debug) { DebugAndLog.debug("Settings initialized", AppConfig._settings); }
159
+ }
160
+
161
+ if (options.connections) {
162
+ AppConfig._connections = new Connections(options.connections);
163
+ if (debug) { DebugAndLog.debug("Connections initialized", AppConfig._connections.info()); }
164
+ }
165
+
166
+ if (options.validations) {
167
+ ClientRequest.init(options.validations);
168
+ if (debug) { DebugAndLog.debug("ClientRequest initialized", ClientRequest.info()); }
169
+ }
170
+
171
+ if (options.responses) {
172
+ Response.init(options.responses);
173
+ if (debug) { DebugAndLog.debug("Response initialized", Response.info()); }
174
+ }
175
+
176
+ if (options.ssmParameters) {
177
+ AppConfig._ssmParameters = AppConfig._initParameters(options.ssmParameters);
178
+ AppConfig.add(AppConfig._ssmParameters);
179
+ }
180
+
181
+ return true;
182
+
183
+ } catch (error) {
184
+ DebugAndLog.error(`Could not initialize Config ${error.message}`, error.stack);
185
+ return false;
186
+ }
187
+ };
188
+
189
+ /**
190
+ * Add a promise to AppConfig. Use AppConfig.promise() to ensure all are resolved.
191
+ * @param {Promise} promise
192
+ */
193
+ static add(promise) {
194
+ AppConfig._promises.push(promise);
195
+ }
94
196
 
95
197
  /**
96
198
  * Get the application settings object
97
199
  *
98
- * Returns the settings object that was initialized during Config.init().
99
- * This typically contains application-specific configuration values loaded
100
- * from parameter store, environment variables, or other sources.
101
- *
102
200
  * @returns {object|null} Settings object containing application configuration, or null if not initialized
103
201
  * @example
104
- * // Access application settings
105
- * const settings = Config.settings();
106
- * if (settings) {
107
- * console.log('App version:', settings.version);
108
- * console.log('Environment:', settings.environment);
109
- * }
202
+ * // Config extends AppConfig
203
+ * const { Config } = require("./config");
204
+ * const limit = Config.settings().dataLimit;
110
205
  */
111
206
  static settings() {
112
- return _ConfigSuperClass._settings;
207
+ return AppConfig._settings;
113
208
  };
114
209
 
115
210
  /**
@@ -117,7 +212,7 @@ class _ConfigSuperClass {
117
212
  * @returns {Connections}
118
213
  */
119
214
  static connections() {
120
- return _ConfigSuperClass._connections;
215
+ return AppConfig._connections;
121
216
  };
122
217
 
123
218
  /**
@@ -127,10 +222,10 @@ class _ConfigSuperClass {
127
222
  * @returns {Connection|null} Connection instance or null if not found
128
223
  */
129
224
  static getConnection(name) {
130
- if (_ConfigSuperClass._connections === null) {
225
+ if (AppConfig._connections === null) {
131
226
  return null;
132
227
  }
133
- return _ConfigSuperClass._connections.get(name);
228
+ return AppConfig._connections.get(name);
134
229
  }
135
230
 
136
231
  /**
@@ -147,11 +242,11 @@ class _ConfigSuperClass {
147
242
  * )
148
243
  * */
149
244
  static getConn(name) {
150
- if (_ConfigSuperClass._connections === null) {
245
+ if (AppConfig._connections === null) {
151
246
  return null;
152
247
  }
153
248
 
154
- const connection = _ConfigSuperClass._connections.get(name);
249
+ const connection = AppConfig._connections.get(name);
155
250
 
156
251
  if (connection === null) {
157
252
  return null;
@@ -175,29 +270,31 @@ class _ConfigSuperClass {
175
270
  */
176
271
  static getConnCacheProfile(connectionName, cacheProfileName) {
177
272
 
178
- if (_ConfigSuperClass._connections === null) {
273
+ if (AppConfig._connections === null) {
179
274
  return { conn: null, cacheProfile: null };
180
275
  }
181
276
 
182
- const connection = _ConfigSuperClass._connections.get(connectionName);
277
+ const connection = AppConfig._connections.get(connectionName);
183
278
 
184
279
  if (connection === null) {
185
280
  return { conn: null, cacheProfile: null };
186
281
  }
187
282
 
188
- let cacheProfile = null;
283
+ let cacheProfile;
284
+
189
285
  try {
190
286
  const profile = connection.getCacheProfile(cacheProfileName);
191
287
  cacheProfile = (profile === undefined) ? null : profile;
192
- } catch (error) {
288
+ } catch {
193
289
  // getCacheProfile throws if _cacheProfiles is null
194
290
  cacheProfile = null;
195
291
  }
196
292
 
197
293
  return {
198
294
  conn: connection.toObject(),
199
- cacheProfile: cacheProfile
200
- };
295
+ cacheProfile
296
+ };
297
+
201
298
  }
202
299
 
203
300
  /**
@@ -205,7 +302,10 @@ class _ConfigSuperClass {
205
302
  * @returns {Promise} A promise that resolves when the Config class has finished initializing
206
303
  */
207
304
  static promise() {
208
- return _ConfigSuperClass._promise;
305
+ if (AppConfig._promise !== null ) { // Backwards compatibility
306
+ AppConfig._promises.push(AppConfig._promise);
307
+ }
308
+ return Promise.all[AppConfig._promises];
209
309
  };
210
310
 
211
311
 
@@ -246,8 +346,6 @@ class _ConfigSuperClass {
246
346
  return { names: names, paths: paths};
247
347
  };
248
348
 
249
- let request = [];
250
-
251
349
  let pNames = paramNames();
252
350
 
253
351
  if (pNames.names.length > 0 || pNames.paths.length > 0 ) {
@@ -352,20 +450,20 @@ class _ConfigSuperClass {
352
450
  * ]
353
451
  * );
354
452
  * @param {array} parameters An array of parameter locations
355
- * @returns {object} Parameters from the parameter store
453
+ * @returns {Promise<object>} Parameters from the parameter store
356
454
  */
357
455
  static async _initParameters(parameters) {
358
456
  // make the call to get the parameters and wait before proceeding to the return
359
457
  return await this._getParameters(parameters);
360
458
  };
361
459
 
362
- static async _initS3File(paths) {
363
- return {};
364
- };
460
+ // static async _initS3File(paths) {
461
+ // return {};
462
+ // };
365
463
 
366
- static async _initDynamoDbRecord(query) {
367
- return {};
368
- };
464
+ // static async _initDynamoDbRecord(query) {
465
+ // return {};
466
+ // };
369
467
 
370
468
  };
371
469
 
@@ -388,7 +486,8 @@ module.exports = {
388
486
  ClientRequest,
389
487
  ResponseDataModel,
390
488
  Response,
391
- _ConfigSuperClass,
489
+ AppConfig,
490
+ _ConfigSuperClass: AppConfig, // Alias
392
491
  CachedSSMParameter,
393
492
  CachedSecret,
394
493
  CachedParameterSecret,
package/scripts/README.md DELETED
@@ -1,175 +0,0 @@
1
- # Documentation Validation Scripts
2
-
3
- This directory contains scripts for validating and auditing documentation in the @63klabs/cache-data package.
4
-
5
- ## Scripts
6
-
7
- ### audit-documentation.mjs
8
-
9
- Comprehensive documentation audit and validation script that checks:
10
-
11
- - **JSDoc Completeness**: Ensures all exported functions have complete JSDoc with required tags (@param, @returns, @example)
12
- - **JSDoc Accuracy**: Verifies that documented parameters match actual function signatures
13
- - **Link Validation**: Checks all links in documentation files to ensure they point to existing files
14
- - **Example Code Validation**: Validates that JavaScript code examples have correct syntax
15
-
16
- #### Usage
17
-
18
- ```bash
19
- node scripts/audit-documentation.mjs
20
- ```
21
-
22
- #### Output
23
-
24
- The script generates a detailed report at:
25
- ```
26
- .kiro/specs/1-3-6-documentation-enhancement/audit-report.json
27
- ```
28
-
29
- The report includes:
30
- - Summary statistics (coverage percentages, error counts)
31
- - List of functions missing JSDoc
32
- - List of functions with incomplete JSDoc
33
- - List of functions with inaccurate JSDoc (hallucinated parameters)
34
- - List of broken links in documentation
35
- - List of invalid code examples
36
-
37
- #### Exit Codes
38
-
39
- - `0`: All validation checks passed
40
- - `1`: Critical errors found (missing JSDoc, inaccurate JSDoc, broken links, or invalid examples)
41
-
42
- ### Pre-Commit Hook
43
-
44
- A Git pre-commit hook is installed at `.git/hooks/pre-commit` that automatically runs documentation validation before each commit.
45
-
46
- #### How It Works
47
-
48
- 1. When you run `git commit`, the hook automatically executes
49
- 2. It runs `audit-documentation.mjs` to validate all documentation
50
- 3. If critical errors are found, the commit is blocked
51
- 4. You must fix the errors before committing
52
-
53
- #### Bypassing the Hook
54
-
55
- If you need to commit despite validation errors (not recommended):
56
-
57
- ```bash
58
- git commit --no-verify
59
- ```
60
-
61
- #### Installing the Hook
62
-
63
- The hook is automatically created when task 16.3 is completed. If you need to reinstall it:
64
-
65
- ```bash
66
- chmod +x .git/hooks/pre-commit
67
- ```
68
-
69
- ## Validation Requirements
70
-
71
- ### JSDoc Requirements
72
-
73
- All exported functions, methods, and classes must have:
74
-
75
- 1. **Description**: Clear explanation of what the function does
76
- 2. **@param tags**: For each parameter, with type and description
77
- 3. **@returns tag**: With detailed type information and description
78
- 4. **@example tag**: Demonstrating typical usage
79
- 5. **@throws tag**: If the function can throw errors (optional but recommended)
80
-
81
- ### Type Annotation Standards
82
-
83
- - Promises: `{Promise<ResolvedType>}`
84
- - Arrays: `{Array.<ElementType>}`
85
- - Objects: `{Object.<string, Type>}` or detailed property list
86
- - Complex returns: `{Promise<{prop1: Type1, prop2: Type2}>}`
87
- - Optional parameters: `{Type} [paramName=default]`
88
- - Union types: `{Type1|Type2}`
89
-
90
- ### Example Code Standards
91
-
92
- All JavaScript code examples in documentation must:
93
-
94
- - Have valid syntax (pass Node.js syntax check)
95
- - Include necessary imports if using package functionality
96
- - Not use deprecated APIs
97
- - Be executable or clearly marked as snippets
98
-
99
- ### Link Standards
100
-
101
- All links in documentation must:
102
-
103
- - Point to existing files for internal links
104
- - Be valid URLs for external links
105
- - Use relative paths for internal documentation
106
-
107
- ## Common Issues and Fixes
108
-
109
- ### Missing JSDoc
110
-
111
- **Issue**: Function has no JSDoc comment
112
-
113
- **Fix**: Add a JSDoc comment block above the function:
114
-
115
- ```javascript
116
- /**
117
- * Description of what the function does
118
- *
119
- * @param {Type} paramName - Description of parameter
120
- * @returns {ReturnType} Description of return value
121
- * @example
122
- * // Example usage
123
- * const result = functionName(param);
124
- */
125
- function functionName(paramName) {
126
- // ...
127
- }
128
- ```
129
-
130
- ### Incomplete JSDoc
131
-
132
- **Issue**: JSDoc is missing required tags
133
-
134
- **Fix**: Add the missing tags (@param, @returns, @example)
135
-
136
- ### Inaccurate JSDoc
137
-
138
- **Issue**: JSDoc documents parameters that don't exist in the function signature
139
-
140
- **Fix**: Update JSDoc to match the actual function signature, or update the function signature if JSDoc is correct
141
-
142
- ### Broken Links
143
-
144
- **Issue**: Documentation contains links to non-existent files
145
-
146
- **Fix**: Update the link to point to the correct file, or create the missing file
147
-
148
- ### Invalid Code Examples
149
-
150
- **Issue**: Code example has syntax errors
151
-
152
- **Fix**: Correct the syntax error, or mark the code as a snippet if it's intentionally incomplete
153
-
154
- ## Integration with CI/CD
155
-
156
- To integrate documentation validation into your CI/CD pipeline:
157
-
158
- ```yaml
159
- # Example GitHub Actions workflow
160
- - name: Validate Documentation
161
- run: node scripts/audit-documentation.mjs
162
- ```
163
-
164
- The script will exit with code 1 if validation fails, causing the CI/CD pipeline to fail.
165
-
166
- ## Maintenance
167
-
168
- The validation script should be updated when:
169
-
170
- - New JSDoc requirements are added
171
- - New documentation standards are established
172
- - New types of validation checks are needed
173
- - Deprecated APIs change
174
-
175
- See `.kiro/specs/1-3-6-documentation-enhancement/STEERING.md` for documentation standards and maintenance procedures.