vaspera 2.10.0 → 2.11.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.
Files changed (206) hide show
  1. package/dist/__tests__/scanners/ai-code/ai-detector.test.d.ts +2 -0
  2. package/dist/__tests__/scanners/ai-code/ai-detector.test.d.ts.map +1 -0
  3. package/dist/__tests__/scanners/ai-code/ai-detector.test.js +188 -0
  4. package/dist/__tests__/scanners/ai-code/ai-detector.test.js.map +1 -0
  5. package/dist/__tests__/scanners/ai-code/confidence-scorer.test.d.ts +2 -0
  6. package/dist/__tests__/scanners/ai-code/confidence-scorer.test.d.ts.map +1 -0
  7. package/dist/__tests__/scanners/ai-code/confidence-scorer.test.js +363 -0
  8. package/dist/__tests__/scanners/ai-code/confidence-scorer.test.js.map +1 -0
  9. package/dist/__tests__/scanners/ai-code/hallucination-checker.test.d.ts +2 -0
  10. package/dist/__tests__/scanners/ai-code/hallucination-checker.test.d.ts.map +1 -0
  11. package/dist/__tests__/scanners/ai-code/hallucination-checker.test.js +226 -0
  12. package/dist/__tests__/scanners/ai-code/hallucination-checker.test.js.map +1 -0
  13. package/dist/__tests__/scanners/ai-code/index.test.d.ts +2 -0
  14. package/dist/__tests__/scanners/ai-code/index.test.d.ts.map +1 -0
  15. package/dist/__tests__/scanners/ai-code/index.test.js +214 -0
  16. package/dist/__tests__/scanners/ai-code/index.test.js.map +1 -0
  17. package/dist/__tests__/scanners/deploy/health-checker.test.d.ts +2 -0
  18. package/dist/__tests__/scanners/deploy/health-checker.test.d.ts.map +1 -0
  19. package/dist/__tests__/scanners/deploy/health-checker.test.js +67 -0
  20. package/dist/__tests__/scanners/deploy/health-checker.test.js.map +1 -0
  21. package/dist/__tests__/scanners/deploy/index.test.d.ts +2 -0
  22. package/dist/__tests__/scanners/deploy/index.test.d.ts.map +1 -0
  23. package/dist/__tests__/scanners/deploy/index.test.js +84 -0
  24. package/dist/__tests__/scanners/deploy/index.test.js.map +1 -0
  25. package/dist/__tests__/scanners/deploy/provider-detector.test.d.ts +2 -0
  26. package/dist/__tests__/scanners/deploy/provider-detector.test.d.ts.map +1 -0
  27. package/dist/__tests__/scanners/deploy/provider-detector.test.js +88 -0
  28. package/dist/__tests__/scanners/deploy/provider-detector.test.js.map +1 -0
  29. package/dist/__tests__/scanners/deploy/types.test.d.ts +2 -0
  30. package/dist/__tests__/scanners/deploy/types.test.d.ts.map +1 -0
  31. package/dist/__tests__/scanners/deploy/types.test.js +126 -0
  32. package/dist/__tests__/scanners/deploy/types.test.js.map +1 -0
  33. package/dist/__tests__/scanners/fp-feedback.test.js +1 -1
  34. package/dist/__tests__/scanners/fp-feedback.test.js.map +1 -1
  35. package/dist/__tests__/scanners/fp-tracker.test.js +1 -1
  36. package/dist/__tests__/scanners/fp-tracker.test.js.map +1 -1
  37. package/dist/__tests__/scanners/runtime/app-launcher.test.d.ts +2 -0
  38. package/dist/__tests__/scanners/runtime/app-launcher.test.d.ts.map +1 -0
  39. package/dist/__tests__/scanners/runtime/app-launcher.test.js +94 -0
  40. package/dist/__tests__/scanners/runtime/app-launcher.test.js.map +1 -0
  41. package/dist/__tests__/scanners/runtime/golden-path-runner.test.d.ts +2 -0
  42. package/dist/__tests__/scanners/runtime/golden-path-runner.test.d.ts.map +1 -0
  43. package/dist/__tests__/scanners/runtime/golden-path-runner.test.js +195 -0
  44. package/dist/__tests__/scanners/runtime/golden-path-runner.test.js.map +1 -0
  45. package/dist/__tests__/scanners/runtime/index.test.d.ts +2 -0
  46. package/dist/__tests__/scanners/runtime/index.test.d.ts.map +1 -0
  47. package/dist/__tests__/scanners/runtime/index.test.js +120 -0
  48. package/dist/__tests__/scanners/runtime/index.test.js.map +1 -0
  49. package/dist/__tests__/scanners/runtime/types.test.d.ts +2 -0
  50. package/dist/__tests__/scanners/runtime/types.test.d.ts.map +1 -0
  51. package/dist/__tests__/scanners/runtime/types.test.js +126 -0
  52. package/dist/__tests__/scanners/runtime/types.test.js.map +1 -0
  53. package/dist/__tests__/scanners/scale/bottleneck-detector.test.d.ts +2 -0
  54. package/dist/__tests__/scanners/scale/bottleneck-detector.test.d.ts.map +1 -0
  55. package/dist/__tests__/scanners/scale/bottleneck-detector.test.js +187 -0
  56. package/dist/__tests__/scanners/scale/bottleneck-detector.test.js.map +1 -0
  57. package/dist/__tests__/scanners/scale/index.test.d.ts +2 -0
  58. package/dist/__tests__/scanners/scale/index.test.d.ts.map +1 -0
  59. package/dist/__tests__/scanners/scale/index.test.js +87 -0
  60. package/dist/__tests__/scanners/scale/index.test.js.map +1 -0
  61. package/dist/__tests__/scanners/scale/load-profiler.test.d.ts +2 -0
  62. package/dist/__tests__/scanners/scale/load-profiler.test.d.ts.map +1 -0
  63. package/dist/__tests__/scanners/scale/load-profiler.test.js +122 -0
  64. package/dist/__tests__/scanners/scale/load-profiler.test.js.map +1 -0
  65. package/dist/__tests__/scanners/scale/types.test.d.ts +2 -0
  66. package/dist/__tests__/scanners/scale/types.test.d.ts.map +1 -0
  67. package/dist/__tests__/scanners/scale/types.test.js +129 -0
  68. package/dist/__tests__/scanners/scale/types.test.js.map +1 -0
  69. package/dist/action/pr-comment.test.js +8 -0
  70. package/dist/action/pr-comment.test.js.map +1 -1
  71. package/dist/action/sarif-upload.test.js +8 -0
  72. package/dist/action/sarif-upload.test.js.map +1 -1
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +874 -0
  75. package/dist/index.js.map +1 -1
  76. package/dist/install-skills.d.ts +11 -0
  77. package/dist/install-skills.d.ts.map +1 -0
  78. package/dist/install-skills.js +81 -0
  79. package/dist/install-skills.js.map +1 -0
  80. package/dist/scanners/ai-code/ai-detector.d.ts +25 -0
  81. package/dist/scanners/ai-code/ai-detector.d.ts.map +1 -0
  82. package/dist/scanners/ai-code/ai-detector.js +192 -0
  83. package/dist/scanners/ai-code/ai-detector.js.map +1 -0
  84. package/dist/scanners/ai-code/confidence-scorer.d.ts +40 -0
  85. package/dist/scanners/ai-code/confidence-scorer.d.ts.map +1 -0
  86. package/dist/scanners/ai-code/confidence-scorer.js +148 -0
  87. package/dist/scanners/ai-code/confidence-scorer.js.map +1 -0
  88. package/dist/scanners/ai-code/hallucination-checker.d.ts +36 -0
  89. package/dist/scanners/ai-code/hallucination-checker.d.ts.map +1 -0
  90. package/dist/scanners/ai-code/hallucination-checker.js +298 -0
  91. package/dist/scanners/ai-code/hallucination-checker.js.map +1 -0
  92. package/dist/scanners/ai-code/index.d.ts +30 -0
  93. package/dist/scanners/ai-code/index.d.ts.map +1 -0
  94. package/dist/scanners/ai-code/index.js +224 -0
  95. package/dist/scanners/ai-code/index.js.map +1 -0
  96. package/dist/scanners/ai-code/types.d.ts +192 -0
  97. package/dist/scanners/ai-code/types.d.ts.map +1 -0
  98. package/dist/scanners/ai-code/types.js +37 -0
  99. package/dist/scanners/ai-code/types.js.map +1 -0
  100. package/dist/scanners/cache.d.ts.map +1 -1
  101. package/dist/scanners/cache.js +8 -0
  102. package/dist/scanners/cache.js.map +1 -1
  103. package/dist/scanners/dast.d.ts +40 -0
  104. package/dist/scanners/dast.d.ts.map +1 -0
  105. package/dist/scanners/dast.js +228 -0
  106. package/dist/scanners/dast.js.map +1 -0
  107. package/dist/scanners/deploy/health-checker.d.ts +38 -0
  108. package/dist/scanners/deploy/health-checker.d.ts.map +1 -0
  109. package/dist/scanners/deploy/health-checker.js +272 -0
  110. package/dist/scanners/deploy/health-checker.js.map +1 -0
  111. package/dist/scanners/deploy/index.d.ts +44 -0
  112. package/dist/scanners/deploy/index.d.ts.map +1 -0
  113. package/dist/scanners/deploy/index.js +208 -0
  114. package/dist/scanners/deploy/index.js.map +1 -0
  115. package/dist/scanners/deploy/provider-detector.d.ts +25 -0
  116. package/dist/scanners/deploy/provider-detector.d.ts.map +1 -0
  117. package/dist/scanners/deploy/provider-detector.js +177 -0
  118. package/dist/scanners/deploy/provider-detector.js.map +1 -0
  119. package/dist/scanners/deploy/types.d.ts +406 -0
  120. package/dist/scanners/deploy/types.d.ts.map +1 -0
  121. package/dist/scanners/deploy/types.js +58 -0
  122. package/dist/scanners/deploy/types.js.map +1 -0
  123. package/dist/scanners/deploy/vercel-integration.d.ts +52 -0
  124. package/dist/scanners/deploy/vercel-integration.d.ts.map +1 -0
  125. package/dist/scanners/deploy/vercel-integration.js +280 -0
  126. package/dist/scanners/deploy/vercel-integration.js.map +1 -0
  127. package/dist/scanners/index.d.ts +4 -4
  128. package/dist/scanners/index.d.ts.map +1 -1
  129. package/dist/scanners/index.js +133 -15
  130. package/dist/scanners/index.js.map +1 -1
  131. package/dist/scanners/index.test.js +6 -6
  132. package/dist/scanners/index.test.js.map +1 -1
  133. package/dist/scanners/openapi.d.ts +20 -0
  134. package/dist/scanners/openapi.d.ts.map +1 -0
  135. package/dist/scanners/openapi.js +226 -0
  136. package/dist/scanners/openapi.js.map +1 -0
  137. package/dist/scanners/runtime/app-launcher.d.ts +33 -0
  138. package/dist/scanners/runtime/app-launcher.d.ts.map +1 -0
  139. package/dist/scanners/runtime/app-launcher.js +419 -0
  140. package/dist/scanners/runtime/app-launcher.js.map +1 -0
  141. package/dist/scanners/runtime/golden-path-runner.d.ts +48 -0
  142. package/dist/scanners/runtime/golden-path-runner.d.ts.map +1 -0
  143. package/dist/scanners/runtime/golden-path-runner.js +373 -0
  144. package/dist/scanners/runtime/golden-path-runner.js.map +1 -0
  145. package/dist/scanners/runtime/index.d.ts +41 -0
  146. package/dist/scanners/runtime/index.d.ts.map +1 -0
  147. package/dist/scanners/runtime/index.js +164 -0
  148. package/dist/scanners/runtime/index.js.map +1 -0
  149. package/dist/scanners/runtime/playwright-executor.d.ts +50 -0
  150. package/dist/scanners/runtime/playwright-executor.d.ts.map +1 -0
  151. package/dist/scanners/runtime/playwright-executor.js +387 -0
  152. package/dist/scanners/runtime/playwright-executor.js.map +1 -0
  153. package/dist/scanners/runtime/types.d.ts +215 -0
  154. package/dist/scanners/runtime/types.d.ts.map +1 -0
  155. package/dist/scanners/runtime/types.js +40 -0
  156. package/dist/scanners/runtime/types.js.map +1 -0
  157. package/dist/scanners/rust.d.ts +22 -0
  158. package/dist/scanners/rust.d.ts.map +1 -0
  159. package/dist/scanners/rust.js +239 -0
  160. package/dist/scanners/rust.js.map +1 -0
  161. package/dist/scanners/scale/bottleneck-detector.d.ts +17 -0
  162. package/dist/scanners/scale/bottleneck-detector.d.ts.map +1 -0
  163. package/dist/scanners/scale/bottleneck-detector.js +250 -0
  164. package/dist/scanners/scale/bottleneck-detector.js.map +1 -0
  165. package/dist/scanners/scale/capacity-estimator.d.ts +17 -0
  166. package/dist/scanners/scale/capacity-estimator.d.ts.map +1 -0
  167. package/dist/scanners/scale/capacity-estimator.js +197 -0
  168. package/dist/scanners/scale/capacity-estimator.js.map +1 -0
  169. package/dist/scanners/scale/index.d.ts +37 -0
  170. package/dist/scanners/scale/index.d.ts.map +1 -0
  171. package/dist/scanners/scale/index.js +101 -0
  172. package/dist/scanners/scale/index.js.map +1 -0
  173. package/dist/scanners/scale/load-profiler.d.ts +48 -0
  174. package/dist/scanners/scale/load-profiler.d.ts.map +1 -0
  175. package/dist/scanners/scale/load-profiler.js +377 -0
  176. package/dist/scanners/scale/load-profiler.js.map +1 -0
  177. package/dist/scanners/scale/types.d.ts +529 -0
  178. package/dist/scanners/scale/types.d.ts.map +1 -0
  179. package/dist/scanners/scale/types.js +57 -0
  180. package/dist/scanners/scale/types.js.map +1 -0
  181. package/dist/scanners/secrets.d.ts.map +1 -1
  182. package/dist/scanners/secrets.js +13 -2
  183. package/dist/scanners/secrets.js.map +1 -1
  184. package/dist/scanners/terraform.d.ts +23 -0
  185. package/dist/scanners/terraform.d.ts.map +1 -0
  186. package/dist/scanners/terraform.js +207 -0
  187. package/dist/scanners/terraform.js.map +1 -0
  188. package/dist/scanners/types.d.ts +1 -1
  189. package/dist/scanners/types.d.ts.map +1 -1
  190. package/dist/scanners/types.js +8 -0
  191. package/dist/scanners/types.js.map +1 -1
  192. package/package.json +4 -2
  193. package/skills/vaspera-add-tests/SKILL.md +102 -0
  194. package/skills/vaspera-ai-verify/SKILL.md +166 -0
  195. package/skills/vaspera-audit/SKILL.md +67 -0
  196. package/skills/vaspera-certify/SKILL.md +130 -0
  197. package/skills/vaspera-deploy/SKILL.md +152 -0
  198. package/skills/vaspera-fix-critical/SKILL.md +52 -0
  199. package/skills/vaspera-fix-high/SKILL.md +81 -0
  200. package/skills/vaspera-fix-medium/SKILL.md +56 -0
  201. package/skills/vaspera-fix-rls/SKILL.md +85 -0
  202. package/skills/vaspera-harden/SKILL.md +102 -0
  203. package/skills/vaspera-help/SKILL.md +61 -0
  204. package/skills/vaspera-load-test/SKILL.md +167 -0
  205. package/skills/vaspera-verify/SKILL.md +70 -0
  206. package/skills/vaspera-verify-e2e/SKILL.md +117 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-checker.d.ts","sourceRoot":"","sources":["../../../src/scanners/deploy/health-checker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAKhF;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACjC,OAAO,CAAC,iBAAiB,CAAC,CA2C5B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAM,EAA6B,EAC9C,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACrD,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA+B9B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,eAAe,CAAC,CAwF1B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,EAAE,GACjB,OAAO,CAAC,eAAe,EAAE,CAAC,CA4B5B;AAkDD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAsBzE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAK1E"}
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Health Checker
3
+ *
4
+ * Performs health checks against deployed endpoints.
5
+ *
6
+ * @module scanners/deploy/health-checker
7
+ */
8
+ import { logger } from "../../logger.js";
9
+ const DEFAULT_TIMEOUT = 10000;
10
+ const DEFAULT_HEALTH_ENDPOINTS = ["/", "/api/health", "/health", "/healthz"];
11
+ /**
12
+ * Check a single health endpoint
13
+ */
14
+ export async function checkHealth(baseUrl, endpoint, options = {}) {
15
+ const url = endpoint.startsWith("http") ? endpoint : `${baseUrl}${endpoint}`;
16
+ const startTime = Date.now();
17
+ try {
18
+ const response = await fetch(url, {
19
+ method: "GET",
20
+ signal: AbortSignal.timeout(options.timeout || DEFAULT_TIMEOUT),
21
+ headers: {
22
+ "User-Agent": "Vaspera-Health-Check/1.0",
23
+ },
24
+ });
25
+ const responseTime = Date.now() - startTime;
26
+ let status;
27
+ if (response.ok) {
28
+ status = responseTime < 500 ? "healthy" : "degraded";
29
+ }
30
+ else if (response.status >= 500) {
31
+ status = "unhealthy";
32
+ }
33
+ else {
34
+ status = "degraded";
35
+ }
36
+ return {
37
+ endpoint,
38
+ status,
39
+ statusCode: response.status,
40
+ responseTime,
41
+ checkedAt: new Date().toISOString(),
42
+ };
43
+ }
44
+ catch (error) {
45
+ const responseTime = Date.now() - startTime;
46
+ const errorMessage = error.message;
47
+ return {
48
+ endpoint,
49
+ status: errorMessage.includes("timeout") ? "timeout" : "unhealthy",
50
+ responseTime,
51
+ error: errorMessage,
52
+ checkedAt: new Date().toISOString(),
53
+ };
54
+ }
55
+ }
56
+ /**
57
+ * Check multiple health endpoints
58
+ */
59
+ export async function checkAllHealth(baseUrl, endpoints = DEFAULT_HEALTH_ENDPOINTS, options = {}) {
60
+ logger.info("deploy.health_check_started", {
61
+ baseUrl,
62
+ endpoints: endpoints.length,
63
+ });
64
+ let results;
65
+ if (options.parallel !== false) {
66
+ results = await Promise.all(endpoints.map((endpoint) => checkHealth(baseUrl, endpoint, options)));
67
+ }
68
+ else {
69
+ results = [];
70
+ for (const endpoint of endpoints) {
71
+ results.push(await checkHealth(baseUrl, endpoint, options));
72
+ }
73
+ }
74
+ const healthy = results.filter((r) => r.status === "healthy").length;
75
+ const degraded = results.filter((r) => r.status === "degraded").length;
76
+ const unhealthy = results.filter((r) => r.status === "unhealthy" || r.status === "timeout").length;
77
+ logger.info("deploy.health_check_completed", {
78
+ healthy,
79
+ degraded,
80
+ unhealthy,
81
+ total: results.length,
82
+ });
83
+ return results;
84
+ }
85
+ /**
86
+ * Run a smoke test
87
+ */
88
+ export async function runSmokeTest(baseUrl, test) {
89
+ const url = test.endpoint.startsWith("http")
90
+ ? test.endpoint
91
+ : `${baseUrl}${test.endpoint}`;
92
+ const startTime = Date.now();
93
+ try {
94
+ const response = await fetch(url, {
95
+ method: test.method || "GET",
96
+ headers: {
97
+ "Content-Type": "application/json",
98
+ "User-Agent": "Vaspera-Smoke-Test/1.0",
99
+ ...test.headers,
100
+ },
101
+ body: test.body ? JSON.stringify(test.body) : undefined,
102
+ signal: AbortSignal.timeout(test.timeout || DEFAULT_TIMEOUT),
103
+ });
104
+ const responseTime = Date.now() - startTime;
105
+ const responseBody = await response.text();
106
+ let responseJson;
107
+ try {
108
+ responseJson = JSON.parse(responseBody);
109
+ }
110
+ catch {
111
+ responseJson = responseBody;
112
+ }
113
+ // Check assertions
114
+ const assertionResults = [];
115
+ let allPassed = response.status === (test.expectedStatus || 200);
116
+ if (test.assertions) {
117
+ for (const assertion of test.assertions) {
118
+ let actual;
119
+ let passed = false;
120
+ switch (assertion.type) {
121
+ case "status":
122
+ actual = response.status;
123
+ passed = evaluateAssertion(actual, assertion.operator, assertion.value);
124
+ break;
125
+ case "latency":
126
+ actual = responseTime;
127
+ passed = evaluateAssertion(actual, assertion.operator, assertion.value);
128
+ break;
129
+ case "header":
130
+ actual = response.headers.get(assertion.path || "") || "";
131
+ passed = evaluateAssertion(actual, assertion.operator, assertion.value);
132
+ break;
133
+ case "body":
134
+ actual = getJsonPath(responseJson, assertion.path || "");
135
+ passed = evaluateAssertion(actual, assertion.operator, assertion.value);
136
+ break;
137
+ }
138
+ assertionResults.push({
139
+ type: assertion.type,
140
+ expected: assertion.value,
141
+ actual,
142
+ passed,
143
+ });
144
+ if (!passed)
145
+ allPassed = false;
146
+ }
147
+ }
148
+ return {
149
+ name: test.name,
150
+ endpoint: test.endpoint,
151
+ passed: allPassed,
152
+ statusCode: response.status,
153
+ responseTime,
154
+ assertions: assertionResults,
155
+ };
156
+ }
157
+ catch (error) {
158
+ return {
159
+ name: test.name,
160
+ endpoint: test.endpoint,
161
+ passed: false,
162
+ statusCode: 0,
163
+ responseTime: Date.now() - startTime,
164
+ assertions: [],
165
+ error: error.message,
166
+ };
167
+ }
168
+ }
169
+ /**
170
+ * Run all smoke tests
171
+ */
172
+ export async function runAllSmokeTests(baseUrl, tests) {
173
+ logger.info("deploy.smoke_tests_started", {
174
+ baseUrl,
175
+ tests: tests.length,
176
+ });
177
+ const results = [];
178
+ for (const test of tests) {
179
+ const result = await runSmokeTest(baseUrl, test);
180
+ results.push(result);
181
+ logger.debug("deploy.smoke_test_result", {
182
+ name: test.name,
183
+ passed: result.passed,
184
+ responseTime: result.responseTime,
185
+ });
186
+ }
187
+ const passed = results.filter((r) => r.passed).length;
188
+ logger.info("deploy.smoke_tests_completed", {
189
+ passed,
190
+ failed: results.length - passed,
191
+ total: results.length,
192
+ });
193
+ return results;
194
+ }
195
+ /**
196
+ * Evaluate an assertion
197
+ */
198
+ function evaluateAssertion(actual, operator, expected) {
199
+ switch (operator) {
200
+ case "eq":
201
+ return actual === expected;
202
+ case "ne":
203
+ return actual !== expected;
204
+ case "gt":
205
+ return Number(actual) > Number(expected);
206
+ case "lt":
207
+ return Number(actual) < Number(expected);
208
+ case "contains":
209
+ return String(actual).includes(String(expected));
210
+ case "matches":
211
+ return new RegExp(String(expected)).test(String(actual));
212
+ default:
213
+ return false;
214
+ }
215
+ }
216
+ /**
217
+ * Get value from JSON path
218
+ */
219
+ function getJsonPath(obj, path) {
220
+ if (!path)
221
+ return String(obj);
222
+ const parts = path.split(".");
223
+ let current = obj;
224
+ for (const part of parts) {
225
+ if (current === null || current === undefined)
226
+ return "";
227
+ if (typeof current === "object") {
228
+ current = current[part];
229
+ }
230
+ else {
231
+ return "";
232
+ }
233
+ }
234
+ if (typeof current === "number")
235
+ return current;
236
+ return String(current ?? "");
237
+ }
238
+ /**
239
+ * Calculate health score (0-100)
240
+ */
241
+ export function calculateHealthScore(results) {
242
+ if (results.length === 0)
243
+ return 50; // Neutral if no endpoints
244
+ let score = 0;
245
+ for (const result of results) {
246
+ switch (result.status) {
247
+ case "healthy":
248
+ score += 100;
249
+ break;
250
+ case "degraded":
251
+ score += 60;
252
+ break;
253
+ case "unhealthy":
254
+ score += 20;
255
+ break;
256
+ case "timeout":
257
+ score += 0;
258
+ break;
259
+ }
260
+ }
261
+ return Math.round(score / results.length);
262
+ }
263
+ /**
264
+ * Calculate smoke test score (0-100)
265
+ */
266
+ export function calculateSmokeTestScore(results) {
267
+ if (results.length === 0)
268
+ return 50; // Neutral if no tests
269
+ const passed = results.filter((r) => r.passed).length;
270
+ return Math.round((passed / results.length) * 100);
271
+ }
272
+ //# sourceMappingURL=health-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-checker.js","sourceRoot":"","sources":["../../../src/scanners/deploy/health-checker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Deployment Verification Scanner
3
+ *
4
+ * Orchestrates deployment verification including health checks,
5
+ * smoke tests, and canary analysis.
6
+ *
7
+ * @module scanners/deploy
8
+ */
9
+ import { checkAllHealth } from "./health-checker.js";
10
+ import { type DeployConfig, type DeployVerificationResult, type DeployProvider, type SmokeTest } from "./types.js";
11
+ export * from "./types.js";
12
+ export { detectProvider, isDeploymentEnvironment, } from "./provider-detector.js";
13
+ export { checkAllHealth, runAllSmokeTests, calculateHealthScore, calculateSmokeTestScore, } from "./health-checker.js";
14
+ export { isVercelAvailable, getLatestDeployment, getDeployment, listDeployments, promoteToProduction, rollback, analyzeCanary, } from "./vercel-integration.js";
15
+ /**
16
+ * Load deployment config
17
+ */
18
+ export declare function loadDeployConfig(projectPath: string): Promise<DeployConfig | null>;
19
+ /**
20
+ * Generate sample deploy config
21
+ */
22
+ export declare function generateDeployConfig(projectPath: string, provider?: DeployProvider): Promise<string>;
23
+ /**
24
+ * Run deployment verification
25
+ */
26
+ export declare function runDeployVerification(projectPath: string, deploymentUrl: string, options?: {
27
+ skipHealthCheck?: boolean;
28
+ skipSmokeTests?: boolean;
29
+ runCanary?: boolean;
30
+ canaryDuration?: number;
31
+ }): Promise<DeployVerificationResult>;
32
+ /**
33
+ * Quick health check (no smoke tests or canary)
34
+ */
35
+ export declare function quickDeployCheck(deploymentUrl: string, endpoints?: string[]): Promise<{
36
+ healthy: boolean;
37
+ score: number;
38
+ checks: Awaited<ReturnType<typeof checkAllHealth>>;
39
+ }>;
40
+ /**
41
+ * Create default smoke tests from OpenAPI/routes
42
+ */
43
+ export declare function createDefaultSmokeTests(): SmokeTest[];
44
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scanners/deploy/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EACL,cAAc,EAIf,MAAM,qBAAqB,CAAC;AAU7B,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,YAAY,CAAC;AAEpB,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,cAAc,EACd,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,QAAQ,EACR,aAAa,GACd,MAAM,yBAAyB,CAAC;AAIjC;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CASxF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,MAAM,CAAC,CAoEjB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE;IACP,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACpB,GACL,OAAO,CAAC,wBAAwB,CAAC,CA8EnC;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,SAAS,GAAE,MAAM,EAAyB,GACzC,OAAO,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC;CACpD,CAAC,CASD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,SAAS,EAAE,CAoBrD"}
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Deployment Verification Scanner
3
+ *
4
+ * Orchestrates deployment verification including health checks,
5
+ * smoke tests, and canary analysis.
6
+ *
7
+ * @module scanners/deploy
8
+ */
9
+ import { readFile, mkdir, writeFile } from "fs/promises";
10
+ import { join } from "path";
11
+ import { parse as parseYaml } from "yaml";
12
+ import { logger } from "../../logger.js";
13
+ import { detectProvider } from "./provider-detector.js";
14
+ import { checkAllHealth, runAllSmokeTests, calculateHealthScore, calculateSmokeTestScore, } from "./health-checker.js";
15
+ import { isVercelAvailable, getLatestDeployment, analyzeCanary, } from "./vercel-integration.js";
16
+ import { DeployConfigSchema, } from "./types.js";
17
+ export * from "./types.js";
18
+ export { detectProvider, isDeploymentEnvironment, } from "./provider-detector.js";
19
+ export { checkAllHealth, runAllSmokeTests, calculateHealthScore, calculateSmokeTestScore, } from "./health-checker.js";
20
+ export { isVercelAvailable, getLatestDeployment, getDeployment, listDeployments, promoteToProduction, rollback, analyzeCanary, } from "./vercel-integration.js";
21
+ const CONFIG_PATH = ".vaspera/deploy.yaml";
22
+ /**
23
+ * Load deployment config
24
+ */
25
+ export async function loadDeployConfig(projectPath) {
26
+ try {
27
+ const configPath = join(projectPath, CONFIG_PATH);
28
+ const content = await readFile(configPath, "utf-8");
29
+ const parsed = parseYaml(content);
30
+ return DeployConfigSchema.parse(parsed);
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
36
+ /**
37
+ * Generate sample deploy config
38
+ */
39
+ export async function generateDeployConfig(projectPath, provider) {
40
+ const configDir = join(projectPath, ".vaspera");
41
+ await mkdir(configDir, { recursive: true });
42
+ const config = `# Deployment Verification Configuration
43
+ # This file configures health checks, smoke tests, and canary deployment
44
+
45
+ ${provider ? `provider: ${provider}` : "# provider: vercel # Auto-detected if not specified"}
46
+
47
+ # Endpoints to check for health
48
+ healthEndpoints:
49
+ - /
50
+ - /api/health
51
+
52
+ # Smoke tests to run after deployment
53
+ smokeTests:
54
+ - name: "Homepage loads"
55
+ endpoint: "/"
56
+ method: GET
57
+ expectedStatus: 200
58
+
59
+ - name: "API health check"
60
+ endpoint: "/api/health"
61
+ method: GET
62
+ expectedStatus: 200
63
+ assertions:
64
+ - type: latency
65
+ operator: lt
66
+ value: 500
67
+
68
+ # Add your critical path tests:
69
+ # - name: "User can login"
70
+ # endpoint: "/api/auth/login"
71
+ # method: POST
72
+ # expectedStatus: 200
73
+ # body:
74
+ # email: "test@example.com"
75
+ # password: "testpass"
76
+
77
+ # Canary deployment settings (for supported providers)
78
+ canary:
79
+ enabled: false
80
+ trafficPercent: 10
81
+ duration: "10m"
82
+ thresholds:
83
+ errorRate: 0.01
84
+ p95Latency: 500
85
+ healthCheckFailures: 2
86
+ rollbackOnFailure: true
87
+
88
+ # Rollback settings
89
+ rollback:
90
+ autoRollback: true
91
+ retainVersions: 5
92
+
93
+ # Optional notifications
94
+ # notifications:
95
+ # slack: "https://hooks.slack.com/..."
96
+ # email:
97
+ # - team@example.com
98
+ `;
99
+ const configPath = join(configDir, "deploy.yaml");
100
+ await writeFile(configPath, config, "utf-8");
101
+ logger.info("deploy.config_generated", { path: configPath });
102
+ return configPath;
103
+ }
104
+ /**
105
+ * Run deployment verification
106
+ */
107
+ export async function runDeployVerification(projectPath, deploymentUrl, options = {}) {
108
+ const startTime = Date.now();
109
+ logger.info("deploy.verification_started", { projectPath, deploymentUrl });
110
+ // Detect provider
111
+ const providerDetection = await detectProvider(projectPath);
112
+ // Load config
113
+ const config = await loadDeployConfig(projectPath);
114
+ const healthEndpoints = config?.healthEndpoints || ["/", "/api/health"];
115
+ const smokeTests = config?.smokeTests || [];
116
+ // Run health checks
117
+ let healthResults = [];
118
+ if (!options.skipHealthCheck) {
119
+ healthResults = await checkAllHealth(deploymentUrl, healthEndpoints);
120
+ }
121
+ // Run smoke tests
122
+ let smokeTestResults = [];
123
+ if (!options.skipSmokeTests && smokeTests.length > 0) {
124
+ smokeTestResults = await runAllSmokeTests(deploymentUrl, smokeTests);
125
+ }
126
+ // Run canary analysis if requested
127
+ let canaryResult;
128
+ if (options.runCanary) {
129
+ canaryResult = await analyzeCanary(deploymentUrl, {
130
+ duration: options.canaryDuration || 60000,
131
+ });
132
+ }
133
+ // Calculate scores
134
+ const healthScore = calculateHealthScore(healthResults);
135
+ const smokeTestScore = smokeTests.length > 0
136
+ ? calculateSmokeTestScore(smokeTestResults)
137
+ : 50; // Neutral if no tests
138
+ const canaryScore = canaryResult
139
+ ? (canaryResult.thresholdsPassed ? 100 : 30)
140
+ : 50; // Neutral if no canary
141
+ const overallScore = Math.round((healthScore * 0.4) + (smokeTestScore * 0.4) + (canaryScore * 0.2));
142
+ // Get deployment info if Vercel
143
+ let deployment;
144
+ if (providerDetection.provider === "vercel" && isVercelAvailable() && providerDetection.projectId) {
145
+ deployment = await getLatestDeployment(providerDetection.projectId) || undefined;
146
+ }
147
+ const result = {
148
+ success: overallScore >= 70,
149
+ provider: providerDetection.provider,
150
+ deployment,
151
+ healthChecks: healthResults,
152
+ smokeTests: smokeTestResults,
153
+ canary: canaryResult,
154
+ score: {
155
+ healthScore,
156
+ smokeTestScore,
157
+ canaryScore,
158
+ overallScore,
159
+ },
160
+ duration: Date.now() - startTime,
161
+ };
162
+ logger.info("deploy.verification_completed", {
163
+ success: result.success,
164
+ overallScore,
165
+ healthScore,
166
+ smokeTestScore,
167
+ canaryScore,
168
+ duration: result.duration,
169
+ });
170
+ return result;
171
+ }
172
+ /**
173
+ * Quick health check (no smoke tests or canary)
174
+ */
175
+ export async function quickDeployCheck(deploymentUrl, endpoints = ["/", "/api/health"]) {
176
+ const checks = await checkAllHealth(deploymentUrl, endpoints);
177
+ const score = calculateHealthScore(checks);
178
+ return {
179
+ healthy: score >= 70,
180
+ score,
181
+ checks,
182
+ };
183
+ }
184
+ /**
185
+ * Create default smoke tests from OpenAPI/routes
186
+ */
187
+ export function createDefaultSmokeTests() {
188
+ return [
189
+ {
190
+ name: "Homepage loads",
191
+ endpoint: "/",
192
+ method: "GET",
193
+ expectedStatus: 200,
194
+ timeout: 10000,
195
+ },
196
+ {
197
+ name: "Health endpoint",
198
+ endpoint: "/api/health",
199
+ method: "GET",
200
+ expectedStatus: 200,
201
+ timeout: 10000,
202
+ assertions: [
203
+ { type: "latency", operator: "lt", value: 500 },
204
+ ],
205
+ },
206
+ ];
207
+ }
208
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/scanners/deploy/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Provider Detector
3
+ *
4
+ * Detects deployment provider from project configuration.
5
+ *
6
+ * @module scanners/deploy/provider-detector
7
+ */
8
+ import type { DeployProvider, ProviderDetection } from "./types.js";
9
+ /**
10
+ * Detect deployment provider from project
11
+ */
12
+ export declare function detectProvider(projectPath: string): Promise<ProviderDetection>;
13
+ /**
14
+ * Get provider-specific deployment URL pattern
15
+ */
16
+ export declare function getDeploymentUrlPattern(provider: DeployProvider): RegExp | null;
17
+ /**
18
+ * Check if running in a deployment environment
19
+ */
20
+ export declare function isDeploymentEnvironment(): boolean;
21
+ /**
22
+ * Get current environment from provider
23
+ */
24
+ export declare function getCurrentEnvironment(provider: DeployProvider): string;
25
+ //# sourceMappingURL=provider-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-detector.d.ts","sourceRoot":"","sources":["../../../src/scanners/deploy/provider-detector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAiDpE;;GAEG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAwFpF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAa/E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CASjD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAWtE"}