qa360 1.4.5 → 2.0.1
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/README.md +1 -1
- package/dist/commands/ai.d.ts +41 -0
- package/dist/commands/ai.js +499 -0
- package/dist/commands/ask.js +12 -12
- package/dist/commands/coverage.d.ts +8 -0
- package/dist/commands/coverage.js +252 -0
- package/dist/commands/explain.d.ts +27 -0
- package/dist/commands/explain.js +630 -0
- package/dist/commands/flakiness.d.ts +73 -0
- package/dist/commands/flakiness.js +435 -0
- package/dist/commands/generate.d.ts +66 -0
- package/dist/commands/generate.js +438 -0
- package/dist/commands/init.d.ts +56 -9
- package/dist/commands/init.js +217 -10
- package/dist/commands/monitor.d.ts +27 -0
- package/dist/commands/monitor.js +225 -0
- package/dist/commands/ollama.d.ts +40 -0
- package/dist/commands/ollama.js +301 -0
- package/dist/commands/pack.d.ts +37 -9
- package/dist/commands/pack.js +240 -141
- package/dist/commands/regression.d.ts +8 -0
- package/dist/commands/regression.js +340 -0
- package/dist/commands/repair.d.ts +26 -0
- package/dist/commands/repair.js +307 -0
- package/dist/commands/retry.d.ts +43 -0
- package/dist/commands/retry.js +275 -0
- package/dist/commands/run.d.ts +8 -3
- package/dist/commands/run.js +45 -31
- package/dist/commands/slo.d.ts +8 -0
- package/dist/commands/slo.js +327 -0
- package/dist/core/adapters/playwright-native-api.d.ts +183 -0
- package/dist/core/adapters/playwright-native-api.js +461 -0
- package/dist/core/adapters/playwright-ui.d.ts +7 -0
- package/dist/core/adapters/playwright-ui.js +29 -1
- package/dist/core/ai/anthropic-provider.d.ts +50 -0
- package/dist/core/ai/anthropic-provider.js +211 -0
- package/dist/core/ai/deepseek-provider.d.ts +81 -0
- package/dist/core/ai/deepseek-provider.js +254 -0
- package/dist/core/ai/index.d.ts +60 -0
- package/dist/core/ai/index.js +18 -0
- package/dist/core/ai/llm-client.d.ts +45 -0
- package/dist/core/ai/llm-client.js +7 -0
- package/dist/core/ai/mock-provider.d.ts +49 -0
- package/dist/core/ai/mock-provider.js +121 -0
- package/dist/core/ai/ollama-provider.d.ts +78 -0
- package/dist/core/ai/ollama-provider.js +192 -0
- package/dist/core/ai/openai-provider.d.ts +48 -0
- package/dist/core/ai/openai-provider.js +188 -0
- package/dist/core/ai/provider-factory.d.ts +160 -0
- package/dist/core/ai/provider-factory.js +269 -0
- package/dist/core/auth/api-key-provider.d.ts +16 -0
- package/dist/core/auth/api-key-provider.js +63 -0
- package/dist/core/auth/aws-iam-provider.d.ts +35 -0
- package/dist/core/auth/aws-iam-provider.js +177 -0
- package/dist/core/auth/azure-ad-provider.d.ts +15 -0
- package/dist/core/auth/azure-ad-provider.js +99 -0
- package/dist/core/auth/basic-auth-provider.d.ts +26 -0
- package/dist/core/auth/basic-auth-provider.js +111 -0
- package/dist/core/auth/gcp-adc-provider.d.ts +27 -0
- package/dist/core/auth/gcp-adc-provider.js +126 -0
- package/dist/core/auth/index.d.ts +238 -0
- package/dist/core/auth/index.js +82 -0
- package/dist/core/auth/jwt-provider.d.ts +19 -0
- package/dist/core/auth/jwt-provider.js +160 -0
- package/dist/core/auth/manager.d.ts +84 -0
- package/dist/core/auth/manager.js +230 -0
- package/dist/core/auth/oauth2-provider.d.ts +17 -0
- package/dist/core/auth/oauth2-provider.js +114 -0
- package/dist/core/auth/totp-provider.d.ts +31 -0
- package/dist/core/auth/totp-provider.js +134 -0
- package/dist/core/auth/ui-login-provider.d.ts +26 -0
- package/dist/core/auth/ui-login-provider.js +198 -0
- package/dist/core/cache/index.d.ts +7 -0
- package/dist/core/cache/index.js +6 -0
- package/dist/core/cache/lru-cache.d.ts +203 -0
- package/dist/core/cache/lru-cache.js +397 -0
- package/dist/core/coverage/analyzer.d.ts +101 -0
- package/dist/core/coverage/analyzer.js +415 -0
- package/dist/core/coverage/collector.d.ts +74 -0
- package/dist/core/coverage/collector.js +459 -0
- package/dist/core/coverage/config.d.ts +37 -0
- package/dist/core/coverage/config.js +156 -0
- package/dist/core/coverage/index.d.ts +11 -0
- package/dist/core/coverage/index.js +15 -0
- package/dist/core/coverage/types.d.ts +267 -0
- package/dist/core/coverage/types.js +6 -0
- package/dist/core/coverage/vault.d.ts +95 -0
- package/dist/core/coverage/vault.js +405 -0
- package/dist/core/dashboard/assets.d.ts +6 -0
- package/dist/core/dashboard/assets.js +690 -0
- package/dist/core/dashboard/index.d.ts +6 -0
- package/dist/core/dashboard/index.js +5 -0
- package/dist/core/dashboard/server.d.ts +72 -0
- package/dist/core/dashboard/server.js +354 -0
- package/dist/core/dashboard/types.d.ts +70 -0
- package/dist/core/dashboard/types.js +5 -0
- package/dist/core/discoverer/index.d.ts +115 -0
- package/dist/core/discoverer/index.js +250 -0
- package/dist/core/flakiness/index.d.ts +228 -0
- package/dist/core/flakiness/index.js +384 -0
- package/dist/core/generation/code-formatter.d.ts +111 -0
- package/dist/core/generation/code-formatter.js +307 -0
- package/dist/core/generation/code-generator.d.ts +144 -0
- package/dist/core/generation/code-generator.js +293 -0
- package/dist/core/generation/generator.d.ts +40 -0
- package/dist/core/generation/generator.js +76 -0
- package/dist/core/generation/index.d.ts +30 -0
- package/dist/core/generation/index.js +28 -0
- package/dist/core/generation/pack-generator.d.ts +107 -0
- package/dist/core/generation/pack-generator.js +416 -0
- package/dist/core/generation/prompt-builder.d.ts +132 -0
- package/dist/core/generation/prompt-builder.js +672 -0
- package/dist/core/generation/source-analyzer.d.ts +213 -0
- package/dist/core/generation/source-analyzer.js +657 -0
- package/dist/core/generation/test-optimizer.d.ts +117 -0
- package/dist/core/generation/test-optimizer.js +328 -0
- package/dist/core/generation/types.d.ts +214 -0
- package/dist/core/generation/types.js +4 -0
- package/dist/core/index.d.ts +23 -1
- package/dist/core/index.js +39 -0
- package/dist/core/pack/validator.js +31 -1
- package/dist/core/pack-v2/index.d.ts +9 -0
- package/dist/core/pack-v2/index.js +8 -0
- package/dist/core/pack-v2/loader.d.ts +62 -0
- package/dist/core/pack-v2/loader.js +231 -0
- package/dist/core/pack-v2/migrator.d.ts +56 -0
- package/dist/core/pack-v2/migrator.js +455 -0
- package/dist/core/pack-v2/validator.d.ts +61 -0
- package/dist/core/pack-v2/validator.js +577 -0
- package/dist/core/regression/detector.d.ts +107 -0
- package/dist/core/regression/detector.js +497 -0
- package/dist/core/regression/index.d.ts +9 -0
- package/dist/core/regression/index.js +11 -0
- package/dist/core/regression/trend-analyzer.d.ts +102 -0
- package/dist/core/regression/trend-analyzer.js +345 -0
- package/dist/core/regression/types.d.ts +222 -0
- package/dist/core/regression/types.js +7 -0
- package/dist/core/regression/vault.d.ts +87 -0
- package/dist/core/regression/vault.js +289 -0
- package/dist/core/repair/engine/fixer.d.ts +24 -0
- package/dist/core/repair/engine/fixer.js +226 -0
- package/dist/core/repair/engine/suggestion-engine.d.ts +18 -0
- package/dist/core/repair/engine/suggestion-engine.js +187 -0
- package/dist/core/repair/index.d.ts +10 -0
- package/dist/core/repair/index.js +13 -0
- package/dist/core/repair/repairer.d.ts +90 -0
- package/dist/core/repair/repairer.js +284 -0
- package/dist/core/repair/types.d.ts +91 -0
- package/dist/core/repair/types.js +6 -0
- package/dist/core/repair/utils/error-analyzer.d.ts +28 -0
- package/dist/core/repair/utils/error-analyzer.js +264 -0
- package/dist/core/retry/flakiness-integration.d.ts +60 -0
- package/dist/core/retry/flakiness-integration.js +228 -0
- package/dist/core/retry/index.d.ts +14 -0
- package/dist/core/retry/index.js +16 -0
- package/dist/core/retry/retry-engine.d.ts +80 -0
- package/dist/core/retry/retry-engine.js +296 -0
- package/dist/core/retry/types.d.ts +178 -0
- package/dist/core/retry/types.js +52 -0
- package/dist/core/retry/vault.d.ts +77 -0
- package/dist/core/retry/vault.js +304 -0
- package/dist/core/runner/e2e-helpers.d.ts +102 -0
- package/dist/core/runner/e2e-helpers.js +153 -0
- package/dist/core/runner/phase3-runner.d.ts +101 -2
- package/dist/core/runner/phase3-runner.js +559 -24
- package/dist/core/self-healing/assertion-healer.d.ts +97 -0
- package/dist/core/self-healing/assertion-healer.js +371 -0
- package/dist/core/self-healing/engine.d.ts +122 -0
- package/dist/core/self-healing/engine.js +538 -0
- package/dist/core/self-healing/index.d.ts +10 -0
- package/dist/core/self-healing/index.js +11 -0
- package/dist/core/self-healing/selector-healer.d.ts +103 -0
- package/dist/core/self-healing/selector-healer.js +372 -0
- package/dist/core/self-healing/types.d.ts +152 -0
- package/dist/core/self-healing/types.js +6 -0
- package/dist/core/slo/config.d.ts +107 -0
- package/dist/core/slo/config.js +360 -0
- package/dist/core/slo/index.d.ts +11 -0
- package/dist/core/slo/index.js +15 -0
- package/dist/core/slo/sli-calculator.d.ts +92 -0
- package/dist/core/slo/sli-calculator.js +364 -0
- package/dist/core/slo/slo-tracker.d.ts +148 -0
- package/dist/core/slo/slo-tracker.js +379 -0
- package/dist/core/slo/types.d.ts +281 -0
- package/dist/core/slo/types.js +7 -0
- package/dist/core/slo/vault.d.ts +102 -0
- package/dist/core/slo/vault.js +427 -0
- package/dist/core/tui/index.d.ts +7 -0
- package/dist/core/tui/index.js +6 -0
- package/dist/core/tui/monitor.d.ts +92 -0
- package/dist/core/tui/monitor.js +271 -0
- package/dist/core/tui/renderer.d.ts +33 -0
- package/dist/core/tui/renderer.js +218 -0
- package/dist/core/tui/types.d.ts +63 -0
- package/dist/core/tui/types.js +5 -0
- package/dist/core/types/pack-v2.d.ts +425 -0
- package/dist/core/types/pack-v2.js +8 -0
- package/dist/core/vault/index.d.ts +116 -0
- package/dist/core/vault/index.js +400 -5
- package/dist/core/watch/index.d.ts +7 -0
- package/dist/core/watch/index.js +6 -0
- package/dist/core/watch/watch-mode.d.ts +213 -0
- package/dist/core/watch/watch-mode.js +389 -0
- package/dist/index.js +68 -68
- package/dist/utils/config.d.ts +5 -0
- package/dist/utils/config.js +136 -0
- package/package.json +5 -1
- package/dist/core/adapters/playwright-api.d.ts +0 -82
- package/dist/core/adapters/playwright-api.js +0 -264
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Login Authentication Provider
|
|
3
|
+
*
|
|
4
|
+
* Handles form-based UI login authentication using Playwright.
|
|
5
|
+
* Supports TOTP for 2FA and session persistence.
|
|
6
|
+
*/
|
|
7
|
+
import { authCache, createCacheKey } from './index.js';
|
|
8
|
+
import { chromium } from 'playwright';
|
|
9
|
+
export class UILoginProvider {
|
|
10
|
+
type = 'ui_login';
|
|
11
|
+
async authenticate(config) {
|
|
12
|
+
const { url, username, password, username_selector = 'input[name="username"], input[type="text"]', password_selector = 'input[name="password"], input[type="password"]', submit_selector = 'button[type="submit"], input[type="submit"]', totp_secret, totp_selector } = config;
|
|
13
|
+
if (!url) {
|
|
14
|
+
return {
|
|
15
|
+
success: false,
|
|
16
|
+
error: 'Login URL is required'
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (!username || !password) {
|
|
20
|
+
return {
|
|
21
|
+
success: false,
|
|
22
|
+
error: 'Username and password are required'
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const cacheKey = this.getCacheKey(config);
|
|
26
|
+
// Check cache first
|
|
27
|
+
if (config.cache?.enabled !== false) {
|
|
28
|
+
const cached = authCache.get(cacheKey);
|
|
29
|
+
if (cached) {
|
|
30
|
+
return { success: true, credentials: cached };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
let browser;
|
|
34
|
+
let context;
|
|
35
|
+
try {
|
|
36
|
+
// Launch browser
|
|
37
|
+
browser = await chromium.launch({ headless: true });
|
|
38
|
+
context = await browser.newContext();
|
|
39
|
+
const page = await context.newPage();
|
|
40
|
+
// Navigate to login page
|
|
41
|
+
await page.goto(url);
|
|
42
|
+
// Fill username
|
|
43
|
+
await page.fill(username_selector, username);
|
|
44
|
+
// Fill password
|
|
45
|
+
await page.fill(password_selector, password);
|
|
46
|
+
// Handle TOTP if provided
|
|
47
|
+
if (totp_secret && totp_selector) {
|
|
48
|
+
const totpCode = this.generateTOTP(totp_secret);
|
|
49
|
+
await page.fill(totp_selector, totpCode);
|
|
50
|
+
}
|
|
51
|
+
// Submit form and wait for navigation or network idle
|
|
52
|
+
// Use race to handle both traditional navigation and AJAX auth (Supabase, etc.)
|
|
53
|
+
await Promise.race([
|
|
54
|
+
page.waitForNavigation({ url: '*/*', timeout: 10000 }).catch(() => null),
|
|
55
|
+
page.waitForLoadState('networkidle', { timeout: 10000 }).catch(() => null),
|
|
56
|
+
page.waitForTimeout(5000) // Fallback: wait 5s max
|
|
57
|
+
]);
|
|
58
|
+
// Get cookies
|
|
59
|
+
const cookies = await context.cookies();
|
|
60
|
+
// Create credentials with cookies
|
|
61
|
+
const credentials = {
|
|
62
|
+
type: 'ui_login',
|
|
63
|
+
cookies: cookies.map(c => ({
|
|
64
|
+
name: c.name,
|
|
65
|
+
value: c.value,
|
|
66
|
+
domain: c.domain,
|
|
67
|
+
path: c.path,
|
|
68
|
+
expires: c.expires ? new Date(c.expires * 1000) : undefined,
|
|
69
|
+
httpOnly: c.httpOnly,
|
|
70
|
+
secure: c.secure
|
|
71
|
+
}))
|
|
72
|
+
};
|
|
73
|
+
// Save session to file if specified
|
|
74
|
+
if (config.session_file) {
|
|
75
|
+
await this.saveSession(config.session_file, cookies);
|
|
76
|
+
}
|
|
77
|
+
// Cache credentials (default 24 hours for UI sessions)
|
|
78
|
+
if (config.cache?.enabled !== false) {
|
|
79
|
+
const ttl = config.cache?.ttl || 86400;
|
|
80
|
+
authCache.set(cacheKey, credentials, ttl);
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
success: true,
|
|
84
|
+
credentials
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
return {
|
|
89
|
+
success: false,
|
|
90
|
+
error: `UI login failed: ${error.message}`
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
94
|
+
if (browser) {
|
|
95
|
+
await browser.close();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async clear(config) {
|
|
100
|
+
const key = this.getCacheKey(config);
|
|
101
|
+
authCache.clear(key);
|
|
102
|
+
// Clear session file if exists
|
|
103
|
+
if (config.session_file) {
|
|
104
|
+
try {
|
|
105
|
+
const fs = require('node:fs');
|
|
106
|
+
if (fs.existsSync(config.session_file)) {
|
|
107
|
+
fs.unlinkSync(config.session_file);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Ignore file errors
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return Promise.resolve();
|
|
115
|
+
}
|
|
116
|
+
async validate(config) {
|
|
117
|
+
const key = this.getCacheKey(config);
|
|
118
|
+
return authCache.has(key);
|
|
119
|
+
}
|
|
120
|
+
getCacheKey(config) {
|
|
121
|
+
const identifier = config.url || 'default';
|
|
122
|
+
return createCacheKey('ui_login', identifier);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Generate TOTP code (simplified version)
|
|
126
|
+
*/
|
|
127
|
+
generateTOTP(secret, digits = 6) {
|
|
128
|
+
// For a full implementation, this would use the TOTPProvider
|
|
129
|
+
// For now, provide a basic implementation
|
|
130
|
+
const crypto = require('node:crypto');
|
|
131
|
+
let time = Math.floor(Date.now() / 1000 / 30);
|
|
132
|
+
const timeBuffer = Buffer.alloc(8);
|
|
133
|
+
for (let i = 7; i >= 0; i--) {
|
|
134
|
+
timeBuffer[i] = time & 0xff;
|
|
135
|
+
time = time >> 8;
|
|
136
|
+
}
|
|
137
|
+
// Decode base32 secret
|
|
138
|
+
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
|
139
|
+
const bits = secret.toUpperCase().replace(/[^A-Z2-7]/g, '');
|
|
140
|
+
const keyBytes = [];
|
|
141
|
+
for (let i = 0; i < bits.length; i += 8) {
|
|
142
|
+
const chunk = bits.substring(i, i + 8);
|
|
143
|
+
let byte = 0;
|
|
144
|
+
for (let j = 0; j < 8; j++) {
|
|
145
|
+
const val = alphabet.indexOf(chunk[j]);
|
|
146
|
+
if (val === -1)
|
|
147
|
+
continue;
|
|
148
|
+
byte = (byte << 5) | val;
|
|
149
|
+
}
|
|
150
|
+
keyBytes.push((byte >> 16) & 0xff);
|
|
151
|
+
keyBytes.push((byte >> 8) & 0xff);
|
|
152
|
+
keyBytes.push(byte & 0xff);
|
|
153
|
+
}
|
|
154
|
+
const hmac = crypto.createHmac('sha1', Buffer.from(keyBytes));
|
|
155
|
+
hmac.update(timeBuffer);
|
|
156
|
+
const result = hmac.digest();
|
|
157
|
+
const offset = result[result.length - 1] & 0xf;
|
|
158
|
+
const binary = ((result[offset] & 0x7f) << 24) |
|
|
159
|
+
((result[offset + 1] & 0xff) << 16) |
|
|
160
|
+
((result[offset + 2] & 0xff) << 8) |
|
|
161
|
+
(result[offset + 3] & 0xff);
|
|
162
|
+
const otp = binary % Math.pow(10, digits);
|
|
163
|
+
return otp.toString().padStart(digits, '0');
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Save session cookies to file
|
|
167
|
+
*/
|
|
168
|
+
async saveSession(filepath, cookies) {
|
|
169
|
+
const fs = require('node:fs');
|
|
170
|
+
const path = require('node:path');
|
|
171
|
+
// Ensure directory exists
|
|
172
|
+
const dir = path.dirname(filepath);
|
|
173
|
+
if (!fs.existsSync(dir)) {
|
|
174
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
175
|
+
}
|
|
176
|
+
fs.writeFileSync(filepath, JSON.stringify(cookies, null, 2));
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Load session cookies from file
|
|
180
|
+
*/
|
|
181
|
+
async loadSession(filepath) {
|
|
182
|
+
const fs = require('node:fs');
|
|
183
|
+
if (!fs.existsSync(filepath)) {
|
|
184
|
+
return [];
|
|
185
|
+
}
|
|
186
|
+
const data = fs.readFileSync(filepath, 'utf-8');
|
|
187
|
+
const cookies = JSON.parse(data);
|
|
188
|
+
return cookies.map((c) => ({
|
|
189
|
+
name: c.name,
|
|
190
|
+
value: c.value,
|
|
191
|
+
domain: c.domain,
|
|
192
|
+
path: c.path,
|
|
193
|
+
expires: c.expires ? new Date(c.expires) : undefined,
|
|
194
|
+
httpOnly: c.httpOnly,
|
|
195
|
+
secure: c.secure
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA360 Cache Module
|
|
3
|
+
*
|
|
4
|
+
* Intelligent caching system for HTTP responses and test results.
|
|
5
|
+
*/
|
|
6
|
+
export { ResponseCache, generateCacheKey, createResponseCache, getDefaultCache, resetDefaultCache } from './lru-cache.js';
|
|
7
|
+
export type { CacheEntry, CacheOptions, CacheStats, CacheKeyOptions } from './lru-cache.js';
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA360 LRU Cache Module
|
|
3
|
+
*
|
|
4
|
+
* Intelligent caching system for HTTP responses to avoid redundant requests.
|
|
5
|
+
* Features:
|
|
6
|
+
* - LRU (Least Recently Used) eviction policy
|
|
7
|
+
* - TTL (Time To Live) expiration
|
|
8
|
+
* - Size-based limits
|
|
9
|
+
* - Cache key generation based on request parameters
|
|
10
|
+
* - Thread-safe operations (async-friendly)
|
|
11
|
+
* - Metrics and statistics
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const cache = new ResponseCache({
|
|
16
|
+
* maxSize: 100,
|
|
17
|
+
* ttl: 60000, // 1 minute
|
|
18
|
+
* maxSizeBytes: 10 * 1024 * 1024 // 10MB
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* const response = await cache.getOrFetch('GET:/api/users', async () => {
|
|
22
|
+
* return await fetch('/api/users');
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Cache entry containing response data and metadata
|
|
28
|
+
*/
|
|
29
|
+
export interface CacheEntry<T> {
|
|
30
|
+
/** Cached response data */
|
|
31
|
+
data: T;
|
|
32
|
+
/** Timestamp when entry was created (ms) */
|
|
33
|
+
createdAt: number;
|
|
34
|
+
/** Timestamp when entry was last accessed (ms) */
|
|
35
|
+
lastAccessed: number;
|
|
36
|
+
/** Number of times this entry was accessed */
|
|
37
|
+
hitCount: number;
|
|
38
|
+
/** Size of the cached data in bytes (approximate) */
|
|
39
|
+
size: number;
|
|
40
|
+
/** Optional cache key for this entry */
|
|
41
|
+
key?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Cache configuration options
|
|
45
|
+
*/
|
|
46
|
+
export interface CacheOptions {
|
|
47
|
+
/** Maximum number of entries in the cache (default: 100) */
|
|
48
|
+
maxSize?: number;
|
|
49
|
+
/** Time to live for entries in milliseconds (default: 300000 = 5 minutes) */
|
|
50
|
+
ttl?: number;
|
|
51
|
+
/** Maximum total size of cache in bytes (default: 10MB) */
|
|
52
|
+
maxSizeBytes?: number;
|
|
53
|
+
/** Whether to enable cache statistics (default: true) */
|
|
54
|
+
enableStats?: boolean;
|
|
55
|
+
/** Whether to log cache operations (default: false) */
|
|
56
|
+
verbose?: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Cache statistics
|
|
60
|
+
*/
|
|
61
|
+
export interface CacheStats {
|
|
62
|
+
/** Total number of cache hits */
|
|
63
|
+
hits: number;
|
|
64
|
+
/** Total number of cache misses */
|
|
65
|
+
misses: number;
|
|
66
|
+
/** Total number of entries added to cache */
|
|
67
|
+
additions: number;
|
|
68
|
+
/** Total number of entries evicted from cache */
|
|
69
|
+
evictions: number;
|
|
70
|
+
/** Current number of entries in cache */
|
|
71
|
+
size: number;
|
|
72
|
+
/** Current approximate size in bytes */
|
|
73
|
+
sizeBytes: number;
|
|
74
|
+
/** Cache hit rate (0-1) */
|
|
75
|
+
hitRate: number;
|
|
76
|
+
/** Average entry size in bytes */
|
|
77
|
+
avgEntrySize: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Cache key generation options
|
|
81
|
+
*/
|
|
82
|
+
export interface CacheKeyOptions {
|
|
83
|
+
/** HTTP method (GET, POST, etc.) */
|
|
84
|
+
method: string;
|
|
85
|
+
/** Request URL/endpoint */
|
|
86
|
+
url: string;
|
|
87
|
+
/** Request headers (for cache key variation) */
|
|
88
|
+
headers?: Record<string, string>;
|
|
89
|
+
/** Request body (for POST/PUT/PATCH) */
|
|
90
|
+
body?: string | Record<string, unknown>;
|
|
91
|
+
/** Query parameters */
|
|
92
|
+
params?: Record<string, string>;
|
|
93
|
+
/** Vary headers (headers that affect cacheability) */
|
|
94
|
+
varyHeaders?: string[];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* LRU Response Cache
|
|
98
|
+
*
|
|
99
|
+
* Thread-safe LRU cache with TTL and size-based eviction.
|
|
100
|
+
*/
|
|
101
|
+
export declare class ResponseCache<T = unknown> {
|
|
102
|
+
private cache;
|
|
103
|
+
private maxSize;
|
|
104
|
+
private ttl;
|
|
105
|
+
private maxSizeBytes;
|
|
106
|
+
private currentSizeBytes;
|
|
107
|
+
private enableStats;
|
|
108
|
+
private verbose;
|
|
109
|
+
private stats;
|
|
110
|
+
constructor(options?: CacheOptions);
|
|
111
|
+
/**
|
|
112
|
+
* Get a value from cache by key
|
|
113
|
+
* Returns undefined if not found or expired
|
|
114
|
+
*/
|
|
115
|
+
get(key: string): T | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* Set a value in cache by key
|
|
118
|
+
* If key exists, updates the entry
|
|
119
|
+
* If cache is full, evicts LRU entry
|
|
120
|
+
*/
|
|
121
|
+
set(key: string, data: T, size?: number): void;
|
|
122
|
+
/**
|
|
123
|
+
* Get a value from cache, or compute and cache it if not present
|
|
124
|
+
* This is the main method to use for caching operations
|
|
125
|
+
*/
|
|
126
|
+
getOrFetch(key: string, fetchFn: () => Promise<T>, size?: number): Promise<T>;
|
|
127
|
+
/**
|
|
128
|
+
* Check if a key exists in cache and is not expired
|
|
129
|
+
*/
|
|
130
|
+
has(key: string): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Delete a specific entry from cache
|
|
133
|
+
*/
|
|
134
|
+
delete(key: string): boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Clear all entries from cache
|
|
137
|
+
*/
|
|
138
|
+
clear(): void;
|
|
139
|
+
/**
|
|
140
|
+
* Remove expired entries from cache
|
|
141
|
+
* Returns the number of entries removed
|
|
142
|
+
*/
|
|
143
|
+
purgeExpired(): number;
|
|
144
|
+
/**
|
|
145
|
+
* Get cache statistics
|
|
146
|
+
*/
|
|
147
|
+
getStats(): CacheStats;
|
|
148
|
+
/**
|
|
149
|
+
* Reset cache statistics
|
|
150
|
+
*/
|
|
151
|
+
resetStats(): void;
|
|
152
|
+
/**
|
|
153
|
+
* Get all cache keys (useful for debugging)
|
|
154
|
+
*/
|
|
155
|
+
keys(): string[];
|
|
156
|
+
/**
|
|
157
|
+
* Get cache size
|
|
158
|
+
*/
|
|
159
|
+
get size(): number;
|
|
160
|
+
/**
|
|
161
|
+
* Check if cache is empty
|
|
162
|
+
*/
|
|
163
|
+
isEmpty(): boolean;
|
|
164
|
+
/**
|
|
165
|
+
* Evict least recently used entry (private method)
|
|
166
|
+
* Since we move accessed entries to the end, the first entry is the LRU
|
|
167
|
+
*/
|
|
168
|
+
private _evictLRU;
|
|
169
|
+
/**
|
|
170
|
+
* Remove entry and update size tracking (private method)
|
|
171
|
+
*/
|
|
172
|
+
private _remove;
|
|
173
|
+
/**
|
|
174
|
+
* Estimate size of data in bytes (private method)
|
|
175
|
+
*/
|
|
176
|
+
private _estimateSize;
|
|
177
|
+
private _recordHit;
|
|
178
|
+
private _recordMiss;
|
|
179
|
+
private _recordAddition;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Generate a cache key from request parameters
|
|
183
|
+
*
|
|
184
|
+
* The key is generated based on:
|
|
185
|
+
* - HTTP method
|
|
186
|
+
* - URL
|
|
187
|
+
* - Vary headers (Authorization, Content-Type, etc.)
|
|
188
|
+
* - Request body (for POST/PUT/PATCH)
|
|
189
|
+
* - Query parameters
|
|
190
|
+
*/
|
|
191
|
+
export declare function generateCacheKey(options: CacheKeyOptions): string;
|
|
192
|
+
/**
|
|
193
|
+
* Create a response cache with default options for HTTP caching
|
|
194
|
+
*/
|
|
195
|
+
export declare function createResponseCache<T = unknown>(options?: CacheOptions): ResponseCache<T>;
|
|
196
|
+
/**
|
|
197
|
+
* Get or create the default cache instance
|
|
198
|
+
*/
|
|
199
|
+
export declare function getDefaultCache<T = unknown>(): ResponseCache<T>;
|
|
200
|
+
/**
|
|
201
|
+
* Reset the default cache instance
|
|
202
|
+
*/
|
|
203
|
+
export declare function resetDefaultCache(): void;
|