@63klabs/cache-data 1.3.7 → 1.3.9

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/CHANGELOG.md CHANGED
@@ -8,9 +8,128 @@ To report an issue, or to see proposed and upcoming enhancements, check out [63K
8
8
 
9
9
  Report all vulnerabilities under the [Security menu](https://github.com/63Klabs/cache-data/security/advisories) in the Cache-Data GitHub repository.
10
10
 
11
- ## v1.3.8 (unreleased)
11
+ ## v1.3.9 (unreleased)
12
12
 
13
- - Nothing yet
13
+ - Unreleased
14
+
15
+ ## v1.3.9 (2026-03-09)
16
+
17
+ ### Added
18
+ - **Body Parameter Validation for ClientRequest** [Spec: 1-3-9-body-validation-and-header-format-fix](.kiro/specs/1-3-9-body-validation-and-header-format-fix/)
19
+ - **Body Parameter Validation**: ClientRequest now validates body parameters using the same validation framework as path, query, header, and cookie parameters
20
+ - Automatic JSON parsing with error handling for request bodies
21
+ - Support for both API Gateway v1 and v2 formats
22
+ - Validation using existing ValidationMatcher and ValidationExecutor classes
23
+ - Body validation integrated into validation chain after cookie validation
24
+ - `getBodyParameters()` method now returns validated body parameters
25
+ - **Header Key Conversion Utility**: New static method `convertHeaderKeyToCamelCase(headerKey)` helps developers determine correct validation rule keys
26
+ - Converts HTTP header names from kebab-case to camelCase (e.g., `content-type` → `contentType`)
27
+ - Handles multiple hyphens and uppercase input correctly
28
+ - Documented with examples of common HTTP headers
29
+ - **Enhanced Documentation**: Comprehensive JSDoc documentation for header key conversion behavior
30
+ - Header key conversion reference table showing HTTP headers and their camelCase equivalents
31
+ - Detailed explanation of conversion algorithm and why it's necessary
32
+ - Examples showing validation configuration with converted header keys
33
+ - Complete body validation examples with error handling
34
+ - **Backwards Compatible**: All new features are opt-in and maintain full backwards compatibility
35
+ - Existing code continues to work without modification
36
+ - Body validation only activates when configured
37
+ - No changes to existing validation behavior for other parameter types
38
+ - **Comprehensive Testing**: 8 property-based tests and extensive unit/integration tests validate correctness properties
39
+ - Body validation round-trip property
40
+ - Validation failure propagation
41
+ - JSON parsing precondition
42
+ - Header key conversion correctness
43
+ - Backwards compatibility preservation
44
+ - Common validation pattern support
45
+ - Multi-parameter validation interface
46
+
47
+ ### Security
48
+ - **Fixed npm security vulnerabilities in serialize-javascript dependency** [Spec: 1-3-9-npm-security-vulnerabilities-fix](.kiro/specs/1-3-9-npm-security-vulnerabilities-fix/)
49
+ - Fixed 2 high severity vulnerabilities in serialize-javascript (RCE via RegExp.flags and Date.prototype.toISOString)
50
+ - Added npm override for serialize-javascript >=7.0.3 to force secure version
51
+ - No breaking changes to public APIs
52
+ - All existing tests pass
53
+
54
+ ### Added
55
+ - **Enhanced Validation System for ClientRequest** [Spec: 1-3-9-improve-validations-object](.kiro/specs/1-3-9-improve-validations-object/)
56
+ - **Route-Specific Validations**: Define different validation rules for the same parameter name in different routes (e.g., `id` in `/product/{id}` vs `/employee/{id}`)
57
+ - **Method-Specific Validations**: Define different validation rules based on HTTP method (e.g., stricter validation for `POST` than `GET`)
58
+ - **Method-and-Route Validations**: Most precise control with validation rules for specific method-route combinations (e.g., `POST:join/{id}`)
59
+ - **Multi-Parameter Validations**: Validate multiple parameters together to enforce cross-parameter constraints
60
+ - **Clear Priority Order**: Four-tier priority system (method-and-route > route-only > method-only > global)
61
+ - **Backwards Compatible**: Existing global parameter validations continue to work without any code changes
62
+ - **Performance Optimized**: Pattern normalization caching and early exit optimization for minimal overhead
63
+ - **Comprehensive Testing**: 15 correctness properties validated through property-based testing
64
+
65
+ ### Enhancement
66
+ - **AppConfig Async Initialization Optimization** [Spec: 1-3-9-appconfig-async-init-optimization](.kiro/specs/1-3-9-appconfig-async-init-optimization/)
67
+ - **Parallel Initialization**: All AppConfig.init() operations now execute asynchronously in parallel, improving Lambda cold start performance by 10-20%
68
+ - **Backwards Compatible**: No API changes - existing code continues to work without modifications
69
+ - **Optimized Operations**: Settings, connections, validations, responses, and SSM parameters all initialize concurrently
70
+ - **Error Resilient**: Individual initialization failures don't block other operations
71
+ - **Transparent**: Debug logging and error handling work identically to previous implementation
72
+ - **Performance**: Cold start time reduced from 62-212ms to 50-200ms (sequential to parallel execution)
73
+
74
+ ## v1.3.8 (2026-03-02)
75
+
76
+ ### Security
77
+ - **Updated the way dependencies are listed reduce npm Security Vulnerabilities** [Spec: 1-3-8-npm-security-vulnerabilities-fix](.kiro/specs/1-3-8-npm-security-vulnerabilities-fix/)
78
+ - Fixed 1 low, 20 high, and 1 critical severity vulnerabilities in development dependencies
79
+ - Updated devDependencies to specific secure versions:
80
+ - `@aws-sdk/client-dynamodb`, `@aws-sdk/client-s3`, `@aws-sdk/client-ssm`, `@aws-sdk/lib-dynamodb`: Updated from `3.x` to `^3.995.0`
81
+ - `mocha`: Updated from `^11.x` to `^11.7.5`
82
+ - `chai`: Updated from `^6.x` to `^6.2.2`
83
+ - `chai-http`: Updated from `^5.x` to `^5.1.2`
84
+ - `sinon`: Updated from `^21.x` to `^21.0.1`
85
+ - `fast-check`: Updated from `^4.x` to `^4.5.3`
86
+ - Added npm overrides for transitive dependencies:
87
+ - `diff`: `>=8.0.3` (fixes low severity DoS vulnerability)
88
+ - `minimatch`: `>=10.2.2` (fixes high severity ReDoS vulnerability)
89
+ - `glob`: `>=13.0.6` (fixes transitive vulnerabilities)
90
+ - No breaking changes to public APIs
91
+ - All existing tests pass
92
+ - Production dependencies remain secure (0 vulnerabilities)
93
+
94
+ ### Added
95
+ - **APIRequest Pagination, Retry, and X-Ray Enhancements** [Spec: 1-3-8-api-request-pagination-retries-xray](.kiro/specs/1-3-8-api-request-pagination-retries-xray/) addresses [#171](https://github.com/63Klabs/cache-data/issues/171), [#172](https://github.com/63Klabs/cache-data/issues/172), [#173](https://github.com/63Klabs/cache-data/issues/173)
96
+ - **Automatic Pagination**: APIRequest now supports automatic pagination for APIs that return paginated results
97
+ - Configurable pagination labels for different API response structures
98
+ - Batch processing for concurrent page requests
99
+ - Support for both offset-based and token-based pagination
100
+ - Automatic result combination into single response
101
+ - Pagination metadata in response (total pages, total items, incomplete status)
102
+ - **Automatic Retry Logic**: APIRequest now includes built-in retry functionality for transient failures
103
+ - Configurable retry attempts (default: 1 retry after initial attempt)
104
+ - Automatic retry on network errors, empty responses, parse errors, and 5xx status codes
105
+ - Optional retry on 4xx status codes (disabled by default)
106
+ - Retry metadata in response (attempts made, final attempt number)
107
+ - **Enhanced X-Ray Subsegments**: Improved AWS X-Ray tracing for better observability
108
+ - Unique subsegment names for each request using timestamps
109
+ - Retry and pagination metadata included in X-Ray traces
110
+ - Separate subsegments for each paginated request
111
+ - Detailed annotations and metadata for debugging
112
+ - **Response Metadata**: New optional metadata field in responses
113
+ - Retry information (occurred, attempts, final attempt)
114
+ - Pagination information (occurred, total pages, total items, incomplete status)
115
+ - Only present when retries or pagination occur
116
+ - **Backwards Compatibility Maintained**: All new features are opt-in via configuration
117
+ - Existing code continues to work without modification
118
+ - No breaking changes to public API
119
+ - Default behavior unchanged when new features not configured
120
+ - See documentation: [Pagination Guide](docs/features/tools/api-request-pagination.md), [Retry Guide](docs/features/tools/api-request-retry.md), [X-Ray Guide](docs/features/tools/api-request-xray.md)
121
+ - **tools.AppConfig** replaces `tools._ConfigSuperClass` and receives an `.init()` to simplify initialization
122
+ - Updated documentation to reflect how `Config` can be implemented to extend `tools._ConfigSuperClass`
123
+ - Instead of separate `Response.init()`, `ClientRequest.init()` and `Connections.init()` a single `AppConfig.init()` can be used within the `Config.init()`
124
+
125
+ ### Enhancement
126
+
127
+ - **Expanded Generic Responses** - Additional responses for status codes
128
+ - Added responses for 408, 418, and 427
129
+ - Ensured all generic responses have the same statuses
130
+ - **Revised Documentation** - Clarified and revised documentation
131
+ - Reviewed all code examples
132
+ - Reviewed implementation instructions
14
133
 
15
134
  ## v1.3.7 (2026-02-06)
16
135
 
package/CONTRIBUTING.md CHANGED
@@ -26,9 +26,9 @@ Spec-Driven, AI-Assisted Engineering (SD-AI) is a software development methodolo
26
26
 
27
27
  Code must be reviewed, understood, and tested by a human before being merged.
28
28
 
29
- Kiro is the required AI coding assistant for final integrations, documentation, and testing, as it is in the AWS Ecosystem and this project is deveoped to deploy on the AWS platform. Just like test suites, Kiro ensures the proper tests, documentation, and guardrails are in place. Kiro is as important as commit-hooks and tests as it is a tool that ensures quality checks and should not be bypassed.
29
+ Kiro is the required AI coding assistant for final integrations, documentation, and testing, as it is in the AWS Ecosystem and this project is developed to deploy on the AWS platform. Just like test suites, Kiro ensures the proper tests, documentation, and guardrails are in place. Kiro is as important as commit-hooks and tests as it is a tool that ensures quality checks and should not be bypassed.
30
30
 
31
- Ensure [AI Context](./AI_CONTEXT.md) and [Kiro steering documents](.kiro/steering/ai-context-reference.md) are reviewed, understood, and used by both humans and AI.
31
+ Ensure [AGENTS](./AGENTS.md) and Kiro steering documents are reviewed, understood, and used by both humans and AI.
32
32
 
33
33
  ## Development Setup
34
34
 
@@ -126,7 +126,7 @@ npm test -- test/cache/
126
126
 
127
127
  ## Documentation Standards
128
128
 
129
- All public APIs must have complete JSDoc documentation. See [Documentation Standards](.kiro/steering/documentation-standards.md) for detailed requirements.
129
+ All public APIs must have complete JSDoc documentation. See [JSDoc Documentation Standards](.kiro/steering/documentation-standards-jsdoc.md) for detailed requirements.
130
130
 
131
131
  **Required JSDoc tags:**
132
132
  - Description of what the function/class does
@@ -162,6 +162,5 @@ Thank you to the following people who have contributed to this project:
162
162
 
163
163
  Chad Kluck\
164
164
  DevOps & Developer Experience Engineer\
165
- AWS Certified Cloud Practitioner | AWS Certified Developer - Associate | AWS
166
- Certified Solutions Architect - Associate\
165
+ AWS Certified Developer and Solutions Architect\
167
166
  [Website](https://chadkluck.me)
package/README.md CHANGED
@@ -29,7 +29,10 @@ The @63klabs/cache-data package provides three main modules:
29
29
  - **Cache Profiles**: Configure multiple cache profiles with different expiration policies
30
30
 
31
31
  ### Endpoint Module
32
- - **HTTP/HTTPS Requests**: Make requests to external APIs and endpoints with built-in retry logic
32
+ - **HTTP/HTTPS Requests**: Make requests to external APIs and endpoints with automatic pagination, retry logic, and X-Ray tracing
33
+ - **Automatic Pagination**: Fetch all pages from paginated APIs automatically with configurable batch processing
34
+ - **Automatic Retry**: Retry failed requests with configurable conditions (network errors, server errors, empty responses)
35
+ - **Enhanced X-Ray Tracing**: Detailed monitoring and debugging with AWS X-Ray subsegments
33
36
  - **Connection Management**: Define and manage multiple endpoint connections with authentication
34
37
  - **Request Caching**: Automatically cache endpoint responses to reduce API calls and improve performance
35
38
  - **Flexible Configuration**: Support for custom headers, query parameters, request bodies, and timeouts
@@ -47,7 +50,7 @@ The @63klabs/cache-data package provides three main modules:
47
50
 
48
51
  ### Requirements
49
52
 
50
- - Node.js >=20.0.0 runtime on Lambda
53
+ - Node.js >=22.0.0 runtime on Lambda
51
54
  - AWS Services:
52
55
  - **AWS Lambda**: For running your serverless functions
53
56
  - **Amazon S3**: For storing large cached objects
@@ -65,7 +68,7 @@ Install the package using npm:
65
68
  npm install @63klabs/cache-data
66
69
  ```
67
70
 
68
- The simplest way to get started is to use the [63klabs Atlantis Templates and Script platform](https://github.com/63Klabs/atlantis-cfn-configuration-repo-for-serverless-deployments) to deploy this and other ready-to-run solutions via CI/CD.
71
+ The simplest way to get started is to use the [63klabs Atlantis Templates and Script Platform](https://github.com/63Klabs/atlantis) to deploy this and other ready-to-run solutions via CI/CD.
69
72
 
70
73
  However, if you want to write your own templates and code, follow the following steps:
71
74
 
@@ -99,26 +102,22 @@ It is recommended that you use the quick-start method when implementing for the
99
102
  ### Basic Caching Example
100
103
 
101
104
  ```javascript
102
- const { cache } = require("@63klabs/cache-data");
105
+ const { cache: {CacheableDataAccess, Cache}, endpoint } = require("@63klabs/cache-data");
103
106
 
104
107
  // Initialize cache with your S3 bucket and DynamoDB table
105
108
  cache.Cache.init({
106
- s3Bucket: process.env.CACHE_DATA_S3_BUCKET,
107
- dynamoDbTable: process.env.CACHE_DATA_DYNAMODB_TABLE,
108
- securityKey: process.env.CACHE_DATA_SECURITY_KEY
109
+ s3Bucket: process.env.CACHE_DATA_S3_BUCKET, // Cache.init will check this env variable automatically if not provided here
110
+ dynamoDbTable: process.env.CACHE_DATA_DYNAMODB_TABLE, // Cache.init will check this env variable automatically if not provided here
111
+ securityKey: process.env.CACHE_DATA_SECURITY_KEY // don't do this, use SSM Parameter Store - example only
109
112
  });
110
113
 
111
- // Cache some data
112
- const cacheKey = "my-data-key";
113
- const dataToCache = { message: "Hello, World!", timestamp: Date.now() };
114
-
115
- await cache.Cache.put(cacheKey, dataToCache, 3600); // Cache for 1 hour
114
+ //
116
115
 
117
116
  // Retrieve cached data
118
- const cachedData = await cache.Cache.get(cacheKey);
119
- if (cachedData) {
120
- console.log("Retrieved from cache:", cachedData);
121
- }
117
+ const conn = { host: "api.example.com", path: "api/users"};
118
+ const cacheProfile = {/* cache parameters */};
119
+ const cachedData = await CacheableDataAccess.getData(cacheProfile, endpoint.get, conn);
120
+ const data = cachedData.getBody(true);
122
121
  ```
123
122
 
124
123
  ### Making Endpoint Requests
@@ -128,21 +127,48 @@ const { endpoint } = require("@63klabs/cache-data");
128
127
 
129
128
  // Make a simple GET request to an API
130
129
  const response = await endpoint.get(
131
- { host: "api.example.com", path: "/data" },
132
- { parameters: { q: "search-term" } }
130
+ { host: "api.example.com", path: "/data", parameters: { q: "search-term" } }
133
131
  );
134
132
 
135
133
  console.log("API Response:", response.body);
136
134
  console.log("Status Code:", response.statusCode);
137
135
  ```
138
136
 
137
+ ### Using APIRequest with Pagination and Retry
138
+
139
+ ```javascript
140
+ const { tools: {APIRequest} } = require("@63klabs/cache-data");
141
+
142
+ // Make a request with automatic pagination and retry
143
+ const request = new tools.APIRequest({
144
+ host: "api.example.com",
145
+ path: "/users",
146
+ parameters: {
147
+ limit: 100 // Items per page
148
+ },
149
+ pagination: {
150
+ enabled: true // Automatically fetch all pages
151
+ },
152
+ retry: {
153
+ enabled: true,
154
+ maxRetries: 2 // Retry failed requests up to 2 times
155
+ }
156
+ });
157
+
158
+ const response = await request.send();
159
+
160
+ // Response contains all users from all pages
161
+ const allUsers = JSON.parse(response.body).items;
162
+ console.log(`Retrieved ${allUsers.length} total users`);
163
+ ```
164
+
139
165
  ### Using Utility Tools
140
166
 
141
167
  ```javascript
142
- const { tools } = require("@63klabs/cache-data");
168
+ const { tools: {DebugAndLog, Timer} } = require("@63klabs/cache-data");
143
169
 
144
170
  // Create a timer to measure performance
145
- const timer = new tools.Timer("my-operation");
171
+ const timer = new Timer("my-operation");
146
172
  timer.start();
147
173
 
148
174
  // Your code here...
@@ -151,9 +177,8 @@ timer.stop();
151
177
  console.log(`Operation took ${timer.elapsed()}ms`);
152
178
 
153
179
  // Use the logger
154
- const logger = new tools.DebugAndLog("MyApp");
155
- logger.info("Application started");
156
- logger.error("An error occurred", { details: "error info" });
180
+ DebugAndLog.debug("MyApp");
181
+ DebugAndLog.error("Error in Service", error.msg);
157
182
  ```
158
183
 
159
184
  ## Help
@@ -198,8 +223,8 @@ This will install dependencies, configure the pre-commit hook for documentation
198
223
 
199
224
  ## AI Context
200
225
 
201
- See [AI_CONTEXT.md](AI_CONTEXT.md) for important context and guidelines for AI-generated code in this repository.
226
+ See [AGENTS.md](AGENTS.md) for important context and guidelines for AI-generated code in this repository.
202
227
 
203
228
  The context file is also helpful (and perhaps essential) for HUMANS developing within the application's structured platform as well.
204
229
 
205
- AI Assisted Engineering of this solution was provided by [Kiro](https://kiro.dev/). Steering documents are provided in the repository's [.kiro](.kiro/steering/ai-context-reference.md) directory. Because testing is tightly coupled with the implementation, it is suggested all documents, code, and tests are thoroughly reviewed before, and updated after, any changes.
230
+ AI Assisted Engineering of this solution was provided by [Kiro](https://kiro.dev/). Steering documents are provided in the repository's `.kiro/steering/` directory. Because testing is tightly coupled with the implementation, it is suggested all documents, code, and tests are thoroughly reviewed before, and updated after, any changes.
@@ -0,0 +1,53 @@
1
+ import js from '@eslint/js';
2
+
3
+ export default [
4
+ js.configs.recommended,
5
+ {
6
+ languageOptions: {
7
+ ecmaVersion: 'latest',
8
+ sourceType: 'module',
9
+ globals: {
10
+ // Node.js globals
11
+ console: 'readonly',
12
+ process: 'readonly',
13
+ Buffer: 'readonly',
14
+ __dirname: 'readonly',
15
+ __filename: 'readonly',
16
+ exports: 'writable',
17
+ module: 'writable',
18
+ require: 'readonly',
19
+ global: 'readonly',
20
+ // Mocha globals
21
+ describe: 'readonly',
22
+ it: 'readonly',
23
+ before: 'readonly',
24
+ after: 'readonly',
25
+ beforeEach: 'readonly',
26
+ afterEach: 'readonly',
27
+ // ES2021 globals
28
+ globalThis: 'readonly'
29
+ }
30
+ },
31
+ rules: {
32
+ 'no-template-curly-in-string': 'error',
33
+ 'no-eval': 'error',
34
+ 'no-implied-eval': 'error',
35
+ 'no-new-func': 'error'
36
+ }
37
+ },
38
+ {
39
+ files: ['test/**/*.mjs', 'test/**/*.js', 'scripts/**/*.mjs', 'scripts/**/*.js', 'src/**/*.js'],
40
+ rules: {
41
+ 'no-restricted-imports': ['error', {
42
+ patterns: [{
43
+ group: ['child_process'],
44
+ importNames: ['exec', 'execSync'],
45
+ message: 'Use execFile or execFileSync instead of exec/execSync to prevent shell injection. See .kiro/steering/secure-coding-practices.md'
46
+ }]
47
+ }]
48
+ }
49
+ },
50
+ {
51
+ ignores: ['node_modules/**', 'coverage/**', 'coverage-jest/**', '.git/**']
52
+ }
53
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@63klabs/cache-data",
3
- "version": "1.3.7",
3
+ "version": "1.3.9",
4
4
  "description": "Cache data from an API endpoint or application process using AWS S3 and DynamoDb",
5
5
  "author": "Chad Leigh Kluck (https://chadkluck.me)",
6
6
  "license": "MIT",
@@ -16,37 +16,49 @@
16
16
  "node": ">=20.0.0"
17
17
  },
18
18
  "dependencies": {
19
- "aws-xray-sdk-core": "^3.12.0",
20
19
  "moment-timezone": "^0.6.0",
21
20
  "object-hash": "^3.0.0"
22
21
  },
23
22
  "devDependencies": {
24
- "@aws-sdk/client-dynamodb": "3.x",
25
- "@aws-sdk/client-s3": "3.x",
26
- "@aws-sdk/client-ssm": "3.x",
27
- "@aws-sdk/lib-dynamodb": "3.x",
28
- "chai": "^6.x",
29
- "chai-http": "^5.x",
30
- "fast-check": "^4.x",
23
+ "aws-xray-sdk-core": "^3.12.0",
24
+ "@aws-sdk/client-dynamodb": "^3.995.0",
25
+ "@aws-sdk/client-s3": "^3.995.0",
26
+ "@aws-sdk/client-ssm": "^3.995.0",
27
+ "@aws-sdk/lib-dynamodb": "^3.995.0",
28
+ "@eslint/js": "^10.0.1",
29
+ "chai": "^6.2.2",
30
+ "chai-http": "^5.1.2",
31
+ "eslint": "^10.0.1",
32
+ "fast-check": "^4.5.3",
31
33
  "jest": "^30.2.0",
32
- "mocha": "^11.x",
33
- "sinon": "^21.x"
34
+ "mocha": "^11.7.5",
35
+ "sinon": "^21.0.1"
34
36
  },
35
37
  "overrides": {
36
- "fast-xml-parser": ">=5.3.4"
38
+ "diff": ">=8.0.3",
39
+ "fast-xml-parser": ">=5.3.4",
40
+ "glob": ">=13.0.6",
41
+ "minimatch": ">=10.2.2",
42
+ "serialize-javascript": ">=7.0.3"
37
43
  },
38
44
  "scripts": {
39
- "test": "mocha 'test/**/*-tests.mjs'",
45
+ "test": "mocha 'test/**/*-tests.mjs' --exclude 'test/migration/property/test-execution-equivalence-property-tests.mjs'",
40
46
  "test:jest": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
41
47
  "test:all": "npm test && npm run test:jest",
48
+ "test:migration:validation": "mocha test/migration/property/test-execution-equivalence-property-tests.mjs",
42
49
  "test:cache": "mocha 'test/cache/**/*-tests.mjs'",
43
50
  "test:cache:jest": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/cache",
44
51
  "test:config": "mocha 'test/config/**/*-tests.mjs'",
45
52
  "test:endpoint": "mocha 'test/endpoint/**/*-tests.mjs'",
53
+ "test:endpoint:jest": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/endpoint",
54
+ "test:tools:jest": "node --experimental-vm-modules node_modules/jest/bin/jest.js test/tools",
46
55
  "test:logging": "mocha 'test/logging/**/*-tests.mjs'",
47
56
  "test:request": "mocha 'test/request/**/*-tests.mjs'",
48
57
  "test:response": "mocha 'test/response/**/*-tests.mjs'",
49
- "test:utils": "mocha 'test/utils/**/*-tests.mjs'"
58
+ "test:utils": "mocha 'test/utils/**/*-tests.mjs'",
59
+ "lint": "eslint .",
60
+ "lint:fix": "eslint . --fix",
61
+ "lint:ci": "eslint . --max-warnings 0"
50
62
  },
51
63
  "keywords": [
52
64
  "api",
@@ -1545,8 +1545,8 @@ class Cache {
1545
1545
  ("CACHE_DATA_USE_TOOLS_HASH" in process.env ? Cache.bool(process.env.CACHE_DATA_USE_TOOLS_HASH_METHOD) : false);
1546
1546
 
1547
1547
  // Initialize in-memory cache feature flag
1548
- this.#useInMemoryCache = parameters.useInMemoryCache ||
1549
- (process.env.CACHE_USE_IN_MEMORY === 'true') ||
1548
+ this.#useInMemoryCache = Cache.bool(parameters.useInMemoryCache) ||
1549
+ Cache.bool(process.env.CACHE_USE_IN_MEMORY) ||
1550
1550
  false;
1551
1551
 
1552
1552
  // Initialize InMemoryCache if enabled
@@ -1654,34 +1654,51 @@ class Cache {
1654
1654
  };
1655
1655
 
1656
1656
  /**
1657
- * Convert a value to boolean with special handling for the string "false".
1657
+ * Convert a value to boolean with strict handling for string values.
1658
1658
  *
1659
1659
  * JavaScript's Boolean() function treats any non-empty string as true, including
1660
- * the string "false". This method adds special handling for the string "false"
1661
- * (case-insensitive) to return false, which is useful when dealing with JSON data,
1662
- * query parameters, or configuration strings.
1660
+ * the string "false". This method provides strict boolean conversion where:
1661
+ * - The string "true" (case-insensitive) returns true
1662
+ * - The string "1" returns true
1663
+ * - The number 1 returns true
1664
+ * - The boolean true returns true
1665
+ * - All other values return false (including "false", "0", "no", whitespace, empty strings, null, undefined)
1663
1666
  *
1664
- * All other values are evaluated using JavaScript's standard Boolean() conversion.
1667
+ * This is useful when dealing with environment variables, JSON data, query parameters,
1668
+ * or configuration strings where only explicit "true" or "1" should enable a feature.
1665
1669
  *
1666
1670
  * @param {*} value A value to convert to boolean
1667
- * @returns {boolean} The boolean representation of the value, with "false" string treated as false
1671
+ * @returns {boolean} True only if value is explicitly truthy ("true", "1", 1, or true), false otherwise
1668
1672
  * @example
1669
1673
  * Cache.bool(true); // true
1670
1674
  * Cache.bool(false); // false
1671
1675
  * Cache.bool("true"); // true
1672
- * Cache.bool("false"); // false (special handling)
1673
- * Cache.bool("FALSE"); // false (case-insensitive)
1676
+ * Cache.bool("TRUE"); // true (case-insensitive)
1677
+ * Cache.bool("1"); // true
1674
1678
  * Cache.bool(1); // true
1679
+ * Cache.bool("false"); // false
1680
+ * Cache.bool("0"); // false
1681
+ * Cache.bool("no"); // false
1682
+ * Cache.bool(" "); // false (whitespace)
1683
+ * Cache.bool(" "); // false (whitespace)
1675
1684
  * Cache.bool(0); // false
1676
1685
  * Cache.bool(null); // false
1686
+ * Cache.bool(undefined); // false
1677
1687
  * Cache.bool(""); // false
1678
1688
  */
1679
1689
  static bool (value) {
1680
1690
 
1681
- if ( typeof value === 'string') { value = value.toLowerCase(); }
1691
+ // >! Handle strings with strict true/false logic
1692
+ // >! Only "true" and "1" are considered truthy strings
1693
+ if ( typeof value === 'string') {
1694
+ value = value.trim().toLowerCase();
1695
+ return value === 'true' || value === '1';
1696
+ }
1682
1697
 
1683
- // Boolean("false") is true so we need to code for it. As long as it is not "false", trust Boolean()
1684
- return (( value !== "false") ? Boolean(value) : false );
1698
+ // >! For non-strings, use standard Boolean conversion
1699
+ // >! This handles: true, 1, objects, arrays
1700
+ // >! And returns false for: false, 0, null, undefined, NaN
1701
+ return Boolean(value);
1685
1702
  };
1686
1703
 
1687
1704
  /**
@@ -3200,7 +3217,6 @@ class TestHarness {
3200
3217
  * WARNING: This method is for testing only and should never be used in production.
3201
3218
  *
3202
3219
  * @returns {{CacheData: typeof CacheData, S3Cache: typeof S3Cache, DynamoDbCache: typeof DynamoDbCache}} Object containing internal classes
3203
- * @private
3204
3220
  * @example
3205
3221
  * // In tests only - DO NOT use in production
3206
3222
  * const { CacheData, S3Cache, DynamoDbCache } = TestHarness.getInternals();