guardrail-core 1.0.0
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/dist/__tests__/autopilot.test.d.ts +7 -0
- package/dist/__tests__/autopilot.test.d.ts.map +1 -0
- package/dist/__tests__/autopilot.test.js +156 -0
- package/dist/__tests__/tier-config.test.d.ts +9 -0
- package/dist/__tests__/tier-config.test.d.ts.map +1 -0
- package/dist/__tests__/tier-config.test.js +230 -0
- package/dist/__tests__/utils/hash-inline.test.d.ts +2 -0
- package/dist/__tests__/utils/hash-inline.test.d.ts.map +1 -0
- package/dist/__tests__/utils/hash-inline.test.js +62 -0
- package/dist/__tests__/utils/hash.test.d.ts +3 -0
- package/dist/__tests__/utils/hash.test.d.ts.map +1 -0
- package/dist/__tests__/utils/hash.test.js +95 -0
- package/dist/__tests__/utils/simple.test.d.ts +1 -0
- package/dist/__tests__/utils/simple.test.d.ts.map +1 -0
- package/dist/__tests__/utils/simple.test.js +10 -0
- package/dist/__tests__/utils/utils-simple.test.d.ts +1 -0
- package/dist/__tests__/utils/utils-simple.test.d.ts.map +1 -0
- package/dist/__tests__/utils/utils-simple.test.js +6 -0
- package/dist/__tests__/utils/utils.test.d.ts +15 -0
- package/dist/__tests__/utils/utils.test.d.ts.map +1 -0
- package/dist/__tests__/utils/utils.test.js +172 -0
- package/dist/autopilot/autopilot-runner.d.ts +33 -0
- package/dist/autopilot/autopilot-runner.d.ts.map +1 -0
- package/dist/autopilot/autopilot-runner.js +479 -0
- package/dist/autopilot/index.d.ts +6 -0
- package/dist/autopilot/index.d.ts.map +1 -0
- package/dist/autopilot/index.js +25 -0
- package/dist/autopilot/types.d.ts +102 -0
- package/dist/autopilot/types.d.ts.map +1 -0
- package/dist/autopilot/types.js +18 -0
- package/dist/cache/index.d.ts +7 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +22 -0
- package/dist/cache/redis-cache.d.ts +145 -0
- package/dist/cache/redis-cache.d.ts.map +1 -0
- package/dist/cache/redis-cache.js +459 -0
- package/dist/ci/github-actions.d.ts +77 -0
- package/dist/ci/github-actions.d.ts.map +1 -0
- package/dist/ci/github-actions.js +277 -0
- package/dist/ci/index.d.ts +12 -0
- package/dist/ci/index.d.ts.map +1 -0
- package/dist/ci/index.js +27 -0
- package/dist/ci/pre-commit.d.ts +65 -0
- package/dist/ci/pre-commit.d.ts.map +1 -0
- package/dist/ci/pre-commit.js +286 -0
- package/dist/entitlements.d.ts +149 -0
- package/dist/entitlements.d.ts.map +1 -0
- package/dist/entitlements.js +464 -0
- package/dist/env.d.ts +113 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +204 -0
- package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts +7 -0
- package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts.map +1 -0
- package/dist/fix-packs/__tests__/generate-fix-packs.test.js +250 -0
- package/dist/fix-packs/generate-fix-packs.d.ts +15 -0
- package/dist/fix-packs/generate-fix-packs.d.ts.map +1 -0
- package/dist/fix-packs/generate-fix-packs.js +505 -0
- package/dist/fix-packs/index.d.ts +8 -0
- package/dist/fix-packs/index.d.ts.map +1 -0
- package/dist/fix-packs/index.js +23 -0
- package/dist/fix-packs/types.d.ts +113 -0
- package/dist/fix-packs/types.d.ts.map +1 -0
- package/dist/fix-packs/types.js +71 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/metrics/prometheus.d.ts +99 -0
- package/dist/metrics/prometheus.d.ts.map +1 -0
- package/dist/metrics/prometheus.js +306 -0
- package/dist/quota-ledger.d.ts +119 -0
- package/dist/quota-ledger.d.ts.map +1 -0
- package/dist/quota-ledger.js +462 -0
- package/dist/rbac/__tests__/permissions.test.d.ts +8 -0
- package/dist/rbac/__tests__/permissions.test.d.ts.map +1 -0
- package/dist/rbac/__tests__/permissions.test.js +350 -0
- package/dist/rbac/index.d.ts +9 -0
- package/dist/rbac/index.d.ts.map +1 -0
- package/dist/rbac/index.js +32 -0
- package/dist/rbac/permissions.d.ts +71 -0
- package/dist/rbac/permissions.d.ts.map +1 -0
- package/dist/rbac/permissions.js +247 -0
- package/dist/rbac/types.d.ts +69 -0
- package/dist/rbac/types.d.ts.map +1 -0
- package/dist/rbac/types.js +213 -0
- package/dist/tier-config.d.ts +203 -0
- package/dist/tier-config.d.ts.map +1 -0
- package/dist/tier-config.js +675 -0
- package/dist/types.d.ts +365 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/utils.d.ts +36 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +127 -0
- package/dist/verified-autofix/__tests__/format-validator.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/format-validator.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/format-validator.test.js +285 -0
- package/dist/verified-autofix/__tests__/pipeline.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/pipeline.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/pipeline.test.js +389 -0
- package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/repo-fingerprint.test.js +236 -0
- package/dist/verified-autofix/__tests__/workspace.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/workspace.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/workspace.test.js +314 -0
- package/dist/verified-autofix/format-validator.d.ts +101 -0
- package/dist/verified-autofix/format-validator.d.ts.map +1 -0
- package/dist/verified-autofix/format-validator.js +446 -0
- package/dist/verified-autofix/index.d.ts +14 -0
- package/dist/verified-autofix/index.d.ts.map +1 -0
- package/dist/verified-autofix/index.js +39 -0
- package/dist/verified-autofix/pipeline.d.ts +68 -0
- package/dist/verified-autofix/pipeline.d.ts.map +1 -0
- package/dist/verified-autofix/pipeline.js +330 -0
- package/dist/verified-autofix/repo-fingerprint.d.ts +56 -0
- package/dist/verified-autofix/repo-fingerprint.d.ts.map +1 -0
- package/dist/verified-autofix/repo-fingerprint.js +396 -0
- package/dist/verified-autofix/workspace.d.ts +83 -0
- package/dist/verified-autofix/workspace.d.ts.map +1 -0
- package/dist/verified-autofix/workspace.js +454 -0
- package/dist/verified-autofix.d.ts +182 -0
- package/dist/verified-autofix.d.ts.map +1 -0
- package/dist/verified-autofix.js +1021 -0
- package/dist/visualization/dependency-graph.d.ts +79 -0
- package/dist/visualization/dependency-graph.d.ts.map +1 -0
- package/dist/visualization/dependency-graph.js +399 -0
- package/dist/visualization/index.d.ts +5 -0
- package/dist/visualization/index.d.ts.map +1 -0
- package/dist/visualization/index.js +20 -0
- package/package.json +29 -0
- package/src/__tests__/autopilot.test.ts +196 -0
- package/src/__tests__/tier-config.test.ts +289 -0
- package/src/__tests__/utils/hash-inline.test.ts +76 -0
- package/src/__tests__/utils/hash.test.ts +119 -0
- package/src/__tests__/utils/simple.test.ts +10 -0
- package/src/__tests__/utils/utils-simple.test.ts +5 -0
- package/src/__tests__/utils/utils.test.ts +203 -0
- package/src/autopilot/autopilot-runner.ts +503 -0
- package/src/autopilot/index.ts +6 -0
- package/src/autopilot/types.ts +119 -0
- package/src/cache/index.ts +7 -0
- package/src/cache/redis-cache.d.ts +155 -0
- package/src/cache/redis-cache.d.ts.map +1 -0
- package/src/cache/redis-cache.ts +517 -0
- package/src/ci/github-actions.ts +335 -0
- package/src/ci/index.ts +12 -0
- package/src/ci/pre-commit.ts +338 -0
- package/src/db/usage-schema.prisma +114 -0
- package/src/entitlements.ts +570 -0
- package/src/env.d.ts +68 -0
- package/src/env.d.ts.map +1 -0
- package/src/env.ts +247 -0
- package/src/fix-packs/__tests__/generate-fix-packs.test.ts +317 -0
- package/src/fix-packs/generate-fix-packs.ts +577 -0
- package/src/fix-packs/index.ts +8 -0
- package/src/fix-packs/types.ts +206 -0
- package/src/index.d.ts +7 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.ts +12 -0
- package/src/metrics/prometheus.d.ts +104 -0
- package/src/metrics/prometheus.d.ts.map +1 -0
- package/src/metrics/prometheus.ts +446 -0
- package/src/quota-ledger.ts +548 -0
- package/src/rbac/__tests__/permissions.test.ts +446 -0
- package/src/rbac/index.ts +46 -0
- package/src/rbac/permissions.ts +301 -0
- package/src/rbac/types.ts +298 -0
- package/src/tier-config.json +157 -0
- package/src/tier-config.ts +815 -0
- package/src/types.d.ts +365 -0
- package/src/types.d.ts.map +1 -0
- package/src/types.ts +441 -0
- package/src/utils.d.ts +36 -0
- package/src/utils.d.ts.map +1 -0
- package/src/utils.ts +140 -0
- package/src/verified-autofix/__tests__/format-validator.test.ts +335 -0
- package/src/verified-autofix/__tests__/pipeline.test.ts +419 -0
- package/src/verified-autofix/__tests__/repo-fingerprint.test.ts +241 -0
- package/src/verified-autofix/__tests__/workspace.test.ts +373 -0
- package/src/verified-autofix/format-validator.ts +517 -0
- package/src/verified-autofix/index.ts +63 -0
- package/src/verified-autofix/pipeline.ts +403 -0
- package/src/verified-autofix/repo-fingerprint.ts +459 -0
- package/src/verified-autofix/workspace.ts +531 -0
- package/src/verified-autofix.ts +1187 -0
- package/src/visualization/dependency-graph.d.ts +85 -0
- package/src/visualization/dependency-graph.d.ts.map +1 -0
- package/src/visualization/dependency-graph.ts +495 -0
- package/src/visualization/index.ts +5 -0
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Redis Caching Layer
|
|
4
|
+
*
|
|
5
|
+
* Production-ready caching implementation with:
|
|
6
|
+
* - Connection pooling
|
|
7
|
+
* - Automatic serialization/deserialization
|
|
8
|
+
* - TTL management
|
|
9
|
+
* - Cache invalidation patterns
|
|
10
|
+
* - Metrics tracking
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.cache = exports.CacheTTL = exports.CacheKeys = exports.RedisCache = void 0;
|
|
47
|
+
class RedisCache {
|
|
48
|
+
client = null;
|
|
49
|
+
config;
|
|
50
|
+
stats = {
|
|
51
|
+
hits: 0,
|
|
52
|
+
misses: 0,
|
|
53
|
+
sets: 0,
|
|
54
|
+
deletes: 0,
|
|
55
|
+
errors: 0,
|
|
56
|
+
hitRate: 0,
|
|
57
|
+
avgLatency: 0,
|
|
58
|
+
};
|
|
59
|
+
latencies = [];
|
|
60
|
+
connected = false;
|
|
61
|
+
memoryFallback = new Map();
|
|
62
|
+
constructor(config = {}) {
|
|
63
|
+
this.config = {
|
|
64
|
+
host: config.host || process.env["REDIS_HOST"] || "localhost",
|
|
65
|
+
port: config.port || parseInt(process.env["REDIS_PORT"] || "6379"),
|
|
66
|
+
password: config.password || process.env["REDIS_PASSWORD"],
|
|
67
|
+
db: config.db || 0,
|
|
68
|
+
keyPrefix: config.keyPrefix || "Guardrail:",
|
|
69
|
+
defaultTTL: config.defaultTTL || 3600, // 1 hour
|
|
70
|
+
maxRetries: config.maxRetries || 3,
|
|
71
|
+
retryDelay: config.retryDelay || 1000,
|
|
72
|
+
enableMetrics: config.enableMetrics ?? true,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Connect to Redis
|
|
77
|
+
*/
|
|
78
|
+
async connect() {
|
|
79
|
+
try {
|
|
80
|
+
// Dynamic import to avoid errors if redis is not installed
|
|
81
|
+
// @ts-ignore
|
|
82
|
+
const { createClient } = await Promise.resolve().then(() => __importStar(require("redis")));
|
|
83
|
+
this.client = createClient({
|
|
84
|
+
socket: {
|
|
85
|
+
host: this.config.host,
|
|
86
|
+
port: this.config.port,
|
|
87
|
+
},
|
|
88
|
+
password: this.config.password,
|
|
89
|
+
database: this.config.db,
|
|
90
|
+
});
|
|
91
|
+
await this.client.connect();
|
|
92
|
+
this.connected = true;
|
|
93
|
+
console.log("Redis cache connected");
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.warn("Redis connection failed, using in-memory fallback:", error);
|
|
97
|
+
this.connected = false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Disconnect from Redis
|
|
102
|
+
*/
|
|
103
|
+
async disconnect() {
|
|
104
|
+
if (this.client && this.connected) {
|
|
105
|
+
await this.client.quit();
|
|
106
|
+
this.connected = false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get prefixed key
|
|
111
|
+
*/
|
|
112
|
+
getKey(key) {
|
|
113
|
+
return `${this.config.keyPrefix}${key}`;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get value from cache
|
|
117
|
+
*/
|
|
118
|
+
async get(key) {
|
|
119
|
+
const startTime = Date.now();
|
|
120
|
+
const prefixedKey = this.getKey(key);
|
|
121
|
+
try {
|
|
122
|
+
let data = null;
|
|
123
|
+
if (this.connected && this.client) {
|
|
124
|
+
data = await this.client.get(prefixedKey);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
const entry = this.memoryFallback.get(prefixedKey);
|
|
128
|
+
if (entry && entry.expiresAt > Date.now()) {
|
|
129
|
+
data = entry.value;
|
|
130
|
+
}
|
|
131
|
+
else if (entry) {
|
|
132
|
+
this.memoryFallback.delete(prefixedKey);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
this.recordLatency(Date.now() - startTime);
|
|
136
|
+
if (data) {
|
|
137
|
+
this.stats.hits++;
|
|
138
|
+
this.updateHitRate();
|
|
139
|
+
const entry = JSON.parse(data);
|
|
140
|
+
return entry.value;
|
|
141
|
+
}
|
|
142
|
+
this.stats.misses++;
|
|
143
|
+
this.updateHitRate();
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
this.stats.errors++;
|
|
148
|
+
console.error("Cache get error:", error);
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Set value in cache
|
|
154
|
+
*/
|
|
155
|
+
async set(key, value, ttl, tags) {
|
|
156
|
+
const startTime = Date.now();
|
|
157
|
+
const prefixedKey = this.getKey(key);
|
|
158
|
+
const expiresIn = ttl || this.config.defaultTTL || 3600;
|
|
159
|
+
try {
|
|
160
|
+
const entry = {
|
|
161
|
+
value,
|
|
162
|
+
createdAt: Date.now(),
|
|
163
|
+
expiresAt: Date.now() + expiresIn * 1000,
|
|
164
|
+
tags,
|
|
165
|
+
};
|
|
166
|
+
const serialized = JSON.stringify(entry);
|
|
167
|
+
if (this.connected && this.client) {
|
|
168
|
+
await this.client.set(prefixedKey, serialized, { EX: expiresIn });
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
this.memoryFallback.set(prefixedKey, {
|
|
172
|
+
value: serialized,
|
|
173
|
+
expiresAt: Date.now() + expiresIn * 1000,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
// Store tag mappings for invalidation
|
|
177
|
+
if (tags && tags.length > 0) {
|
|
178
|
+
for (const tag of tags) {
|
|
179
|
+
await this.addKeyToTag(tag, prefixedKey);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
this.stats.sets++;
|
|
183
|
+
this.recordLatency(Date.now() - startTime);
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
this.stats.errors++;
|
|
188
|
+
console.error("Cache set error:", error);
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Delete value from cache
|
|
194
|
+
*/
|
|
195
|
+
async delete(key) {
|
|
196
|
+
const prefixedKey = this.getKey(key);
|
|
197
|
+
try {
|
|
198
|
+
if (this.connected && this.client) {
|
|
199
|
+
await this.client.del(prefixedKey);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
this.memoryFallback.delete(prefixedKey);
|
|
203
|
+
}
|
|
204
|
+
this.stats.deletes++;
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
this.stats.errors++;
|
|
209
|
+
console.error("Cache delete error:", error);
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Delete multiple keys by pattern
|
|
215
|
+
*/
|
|
216
|
+
async deletePattern(pattern) {
|
|
217
|
+
const prefixedPattern = this.getKey(pattern);
|
|
218
|
+
try {
|
|
219
|
+
if (this.connected && this.client) {
|
|
220
|
+
const keys = await this.client.keys(prefixedPattern);
|
|
221
|
+
if (keys.length > 0) {
|
|
222
|
+
await this.client.del(keys);
|
|
223
|
+
this.stats.deletes += keys.length;
|
|
224
|
+
return keys.length;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
const regex = new RegExp(prefixedPattern.replace(/\*/g, ".*"));
|
|
229
|
+
let count = 0;
|
|
230
|
+
for (const key of this.memoryFallback.keys()) {
|
|
231
|
+
if (regex.test(key)) {
|
|
232
|
+
this.memoryFallback.delete(key);
|
|
233
|
+
count++;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
this.stats.deletes += count;
|
|
237
|
+
return count;
|
|
238
|
+
}
|
|
239
|
+
return 0;
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
this.stats.errors++;
|
|
243
|
+
console.error("Cache deletePattern error:", error);
|
|
244
|
+
return 0;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Invalidate cache by tag
|
|
249
|
+
*/
|
|
250
|
+
async invalidateByTag(tag) {
|
|
251
|
+
const tagKey = this.getKey(`tag:${tag}`);
|
|
252
|
+
try {
|
|
253
|
+
if (this.connected && this.client) {
|
|
254
|
+
const keysData = await this.client.get(tagKey);
|
|
255
|
+
if (keysData) {
|
|
256
|
+
const keys = JSON.parse(keysData);
|
|
257
|
+
if (keys.length > 0) {
|
|
258
|
+
await this.client.del(keys);
|
|
259
|
+
await this.client.del(tagKey);
|
|
260
|
+
this.stats.deletes += keys.length;
|
|
261
|
+
return keys.length;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return 0;
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
this.stats.errors++;
|
|
269
|
+
console.error("Cache invalidateByTag error:", error);
|
|
270
|
+
return 0;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Add key to tag set
|
|
275
|
+
*/
|
|
276
|
+
async addKeyToTag(tag, key) {
|
|
277
|
+
const tagKey = this.getKey(`tag:${tag}`);
|
|
278
|
+
try {
|
|
279
|
+
if (this.connected && this.client) {
|
|
280
|
+
const existing = await this.client.get(tagKey);
|
|
281
|
+
const keys = existing ? JSON.parse(existing) : [];
|
|
282
|
+
if (!keys.includes(key)) {
|
|
283
|
+
keys.push(key);
|
|
284
|
+
await this.client.set(tagKey, JSON.stringify(keys), { EX: 86400 }); // 24 hour TTL for tags
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
console.error("Cache addKeyToTag error:", error);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Check if key exists
|
|
294
|
+
*/
|
|
295
|
+
async exists(key) {
|
|
296
|
+
const prefixedKey = this.getKey(key);
|
|
297
|
+
try {
|
|
298
|
+
if (this.connected && this.client) {
|
|
299
|
+
const result = await this.client.exists(prefixedKey);
|
|
300
|
+
return result === 1;
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
const entry = this.memoryFallback.get(prefixedKey);
|
|
304
|
+
return entry !== undefined && entry.expiresAt > Date.now();
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Get remaining TTL
|
|
313
|
+
*/
|
|
314
|
+
async getTTL(key) {
|
|
315
|
+
const prefixedKey = this.getKey(key);
|
|
316
|
+
try {
|
|
317
|
+
if (this.connected && this.client) {
|
|
318
|
+
return await this.client.ttl(prefixedKey);
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
const entry = this.memoryFallback.get(prefixedKey);
|
|
322
|
+
if (entry) {
|
|
323
|
+
return Math.max(0, Math.floor((entry.expiresAt - Date.now()) / 1000));
|
|
324
|
+
}
|
|
325
|
+
return -2;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
return -1;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Get or set (cache-aside pattern)
|
|
334
|
+
*/
|
|
335
|
+
async getOrSet(key, factory, ttl, tags) {
|
|
336
|
+
const cached = await this.get(key);
|
|
337
|
+
if (cached !== null) {
|
|
338
|
+
return cached;
|
|
339
|
+
}
|
|
340
|
+
const value = await factory();
|
|
341
|
+
await this.set(key, value, ttl, tags);
|
|
342
|
+
return value;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Flush all cache
|
|
346
|
+
*/
|
|
347
|
+
async flush() {
|
|
348
|
+
try {
|
|
349
|
+
if (this.connected && this.client) {
|
|
350
|
+
await this.client.flushdb();
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
this.memoryFallback.clear();
|
|
354
|
+
}
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
this.stats.errors++;
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Health check
|
|
364
|
+
*/
|
|
365
|
+
async ping() {
|
|
366
|
+
try {
|
|
367
|
+
if (this.connected && this.client) {
|
|
368
|
+
const result = await this.client.ping();
|
|
369
|
+
return result === "PONG";
|
|
370
|
+
}
|
|
371
|
+
return true; // Memory fallback always available
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Get cache statistics
|
|
379
|
+
*/
|
|
380
|
+
getStats() {
|
|
381
|
+
return { ...this.stats };
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Reset statistics
|
|
385
|
+
*/
|
|
386
|
+
resetStats() {
|
|
387
|
+
this.stats = {
|
|
388
|
+
hits: 0,
|
|
389
|
+
misses: 0,
|
|
390
|
+
sets: 0,
|
|
391
|
+
deletes: 0,
|
|
392
|
+
errors: 0,
|
|
393
|
+
hitRate: 0,
|
|
394
|
+
avgLatency: 0,
|
|
395
|
+
};
|
|
396
|
+
this.latencies = [];
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Record latency for metrics
|
|
400
|
+
*/
|
|
401
|
+
recordLatency(ms) {
|
|
402
|
+
if (!this.config.enableMetrics)
|
|
403
|
+
return;
|
|
404
|
+
this.latencies.push(ms);
|
|
405
|
+
if (this.latencies.length > 1000) {
|
|
406
|
+
this.latencies.shift();
|
|
407
|
+
}
|
|
408
|
+
this.stats.avgLatency =
|
|
409
|
+
this.latencies.reduce((a, b) => a + b, 0) / this.latencies.length;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Update hit rate
|
|
413
|
+
*/
|
|
414
|
+
updateHitRate() {
|
|
415
|
+
const total = this.stats.hits + this.stats.misses;
|
|
416
|
+
this.stats.hitRate = total > 0 ? this.stats.hits / total : 0;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Check if connected to Redis
|
|
420
|
+
*/
|
|
421
|
+
isConnected() {
|
|
422
|
+
return this.connected;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
exports.RedisCache = RedisCache;
|
|
426
|
+
// Cache key generators for common use cases
|
|
427
|
+
exports.CacheKeys = {
|
|
428
|
+
// Scan results
|
|
429
|
+
scanResult: (projectId, scanType) => `scan:${projectId}:${scanType}`,
|
|
430
|
+
// Knowledge base
|
|
431
|
+
knowledgeBase: (projectPath) => `knowledge:${Buffer.from(projectPath).toString("base64").slice(0, 32)}`,
|
|
432
|
+
// Embeddings
|
|
433
|
+
embedding: (contentHash) => `embedding:${contentHash}`,
|
|
434
|
+
// Vulnerability data
|
|
435
|
+
vulnerability: (packageName, version) => `vuln:${packageName}:${version}`,
|
|
436
|
+
// License data
|
|
437
|
+
license: (packageName) => `license:${packageName}`,
|
|
438
|
+
// Compliance assessment
|
|
439
|
+
compliance: (projectId, framework) => `compliance:${projectId}:${framework}`,
|
|
440
|
+
// User session
|
|
441
|
+
session: (sessionId) => `session:${sessionId}`,
|
|
442
|
+
// Rate limiting
|
|
443
|
+
rateLimit: (identifier, action) => `ratelimit:${identifier}:${action}`,
|
|
444
|
+
};
|
|
445
|
+
// Cache TTL presets (in seconds)
|
|
446
|
+
exports.CacheTTL = {
|
|
447
|
+
SHORT: 300, // 5 minutes
|
|
448
|
+
MEDIUM: 3600, // 1 hour
|
|
449
|
+
LONG: 86400, // 24 hours
|
|
450
|
+
WEEK: 604800, // 7 days
|
|
451
|
+
SCAN_RESULT: 1800, // 30 minutes
|
|
452
|
+
KNOWLEDGE: 3600, // 1 hour
|
|
453
|
+
EMBEDDING: 604800, // 7 days
|
|
454
|
+
VULNERABILITY: 21600, // 6 hours
|
|
455
|
+
LICENSE: 604800, // 7 days
|
|
456
|
+
SESSION: 86400, // 24 hours
|
|
457
|
+
};
|
|
458
|
+
// Export singleton
|
|
459
|
+
exports.cache = new RedisCache();
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Actions Integration
|
|
3
|
+
*
|
|
4
|
+
* Provides integration with GitHub Actions for automated security scanning
|
|
5
|
+
*/
|
|
6
|
+
export interface GitHubActionsConfig {
|
|
7
|
+
workflowName: string;
|
|
8
|
+
triggers: {
|
|
9
|
+
push?: {
|
|
10
|
+
branches: string[];
|
|
11
|
+
};
|
|
12
|
+
pullRequest?: {
|
|
13
|
+
branches: string[];
|
|
14
|
+
};
|
|
15
|
+
schedule?: {
|
|
16
|
+
cron: string;
|
|
17
|
+
}[];
|
|
18
|
+
workflowDispatch?: boolean;
|
|
19
|
+
};
|
|
20
|
+
scanTypes: ('security' | 'secrets' | 'vulnerabilities' | 'compliance' | 'sbom')[];
|
|
21
|
+
failOnCritical: boolean;
|
|
22
|
+
failOnHigh: boolean;
|
|
23
|
+
uploadArtifacts: boolean;
|
|
24
|
+
createPRComments: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface WorkflowStep {
|
|
27
|
+
name: string;
|
|
28
|
+
uses?: string;
|
|
29
|
+
run?: string;
|
|
30
|
+
with?: Record<string, string | boolean | number>;
|
|
31
|
+
env?: Record<string, string>;
|
|
32
|
+
if?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface WorkflowJob {
|
|
35
|
+
name: string;
|
|
36
|
+
runsOn: string;
|
|
37
|
+
permissions?: Record<string, string>;
|
|
38
|
+
steps: WorkflowStep[];
|
|
39
|
+
}
|
|
40
|
+
export interface GitHubWorkflow {
|
|
41
|
+
name: string;
|
|
42
|
+
on: Record<string, any>;
|
|
43
|
+
permissions?: Record<string, string>;
|
|
44
|
+
jobs: Record<string, WorkflowJob>;
|
|
45
|
+
}
|
|
46
|
+
export declare class GitHubActionsGenerator {
|
|
47
|
+
/**
|
|
48
|
+
* Generate a complete GitHub Actions workflow
|
|
49
|
+
*/
|
|
50
|
+
generateWorkflow(config: GitHubActionsConfig): string;
|
|
51
|
+
/**
|
|
52
|
+
* Build workflow triggers
|
|
53
|
+
*/
|
|
54
|
+
private buildTriggers;
|
|
55
|
+
/**
|
|
56
|
+
* Build the main scan job
|
|
57
|
+
*/
|
|
58
|
+
private buildScanJob;
|
|
59
|
+
/**
|
|
60
|
+
* Build result check script
|
|
61
|
+
*/
|
|
62
|
+
private buildCheckScript;
|
|
63
|
+
/**
|
|
64
|
+
* Convert workflow object to YAML
|
|
65
|
+
*/
|
|
66
|
+
private toYAML;
|
|
67
|
+
/**
|
|
68
|
+
* Convert object to YAML with indentation
|
|
69
|
+
*/
|
|
70
|
+
private objectToYAML;
|
|
71
|
+
/**
|
|
72
|
+
* Generate default workflow for quick setup
|
|
73
|
+
*/
|
|
74
|
+
generateDefaultWorkflow(): string;
|
|
75
|
+
}
|
|
76
|
+
export declare const githubActionsGenerator: GitHubActionsGenerator;
|
|
77
|
+
//# sourceMappingURL=github-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-actions.d.ts","sourceRoot":"","sources":["../../src/ci/github-actions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE;QACR,IAAI,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QAC9B,WAAW,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QACrC,QAAQ,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;IACF,SAAS,EAAE,CAAC,UAAU,GAAG,SAAS,GAAG,iBAAiB,GAAG,YAAY,GAAG,MAAM,CAAC,EAAE,CAAC;IAClF,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACnC;AAED,qBAAa,sBAAsB;IACjC;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM;IAiBrD;;OAEG;IACH,OAAO,CAAC,aAAa;IAsBrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAqGpB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;OAEG;IACH,OAAO,CAAC,MAAM;IAmEd;;OAEG;IACH,OAAO,CAAC,YAAY;IAkCpB;;OAEG;IACH,uBAAuB,IAAI,MAAM;CAgBlC;AAGD,eAAO,MAAM,sBAAsB,wBAA+B,CAAC"}
|