@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/AGENTS.md +1107 -0
- package/CHANGELOG.md +121 -2
- package/CONTRIBUTING.md +4 -5
- package/README.md +50 -25
- package/eslint.config.js +53 -0
- package/package.json +26 -14
- package/src/lib/dao-cache.js +30 -14
- package/src/lib/tools/APIRequest.class.js +948 -91
- package/src/lib/tools/AWS.classes.js +58 -5
- package/src/lib/tools/CachedParametersSecrets.classes.js +1 -0
- package/src/lib/tools/ClientRequest.class.js +858 -31
- package/src/lib/tools/Connections.classes.js +40 -3
- package/src/lib/tools/Response.class.js +11 -0
- package/src/lib/tools/generic.response.html.js +33 -0
- package/src/lib/tools/generic.response.json.js +40 -1
- package/src/lib/tools/generic.response.rss.js +33 -0
- package/src/lib/tools/generic.response.text.js +34 -1
- package/src/lib/tools/generic.response.xml.js +39 -0
- package/src/lib/tools/index.js +211 -50
- package/src/lib/utils/ValidationExecutor.class.js +66 -0
- package/src/lib/utils/ValidationMatcher.class.js +405 -0
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.
|
|
11
|
+
## v1.3.9 (unreleased)
|
|
12
12
|
|
|
13
|
-
-
|
|
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
|
|
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 [
|
|
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
|
|
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
|
|
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 >=
|
|
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
|
|
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
|
-
//
|
|
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
|
|
119
|
-
|
|
120
|
-
|
|
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
|
|
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
|
-
|
|
155
|
-
|
|
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 [
|
|
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
|
|
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.
|
package/eslint.config.js
ADDED
|
@@ -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.
|
|
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
|
-
"
|
|
25
|
-
"@aws-sdk/client-
|
|
26
|
-
"@aws-sdk/client-
|
|
27
|
-
"@aws-sdk/
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
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.
|
|
33
|
-
"sinon": "^21.
|
|
34
|
+
"mocha": "^11.7.5",
|
|
35
|
+
"sinon": "^21.0.1"
|
|
34
36
|
},
|
|
35
37
|
"overrides": {
|
|
36
|
-
"
|
|
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",
|
package/src/lib/dao-cache.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
1661
|
-
* (case-insensitive)
|
|
1662
|
-
*
|
|
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
|
-
*
|
|
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}
|
|
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("
|
|
1673
|
-
* Cache.bool("
|
|
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
|
-
|
|
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
|
-
//
|
|
1684
|
-
|
|
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();
|