@ucptools/validator 1.0.0 → 1.1.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 (330) hide show
  1. package/dist/auth/config.d.ts +20 -0
  2. package/dist/auth/config.d.ts.map +1 -0
  3. package/dist/auth/config.js +114 -0
  4. package/dist/auth/config.js.map +1 -0
  5. package/dist/auth/index.d.ts +5 -0
  6. package/dist/auth/index.d.ts.map +1 -0
  7. package/dist/auth/index.js +17 -0
  8. package/dist/auth/index.js.map +1 -0
  9. package/dist/auth/middleware.d.ts +45 -0
  10. package/dist/auth/middleware.d.ts.map +1 -0
  11. package/dist/auth/middleware.js +170 -0
  12. package/dist/auth/middleware.js.map +1 -0
  13. package/dist/auth/service.d.ts +80 -0
  14. package/dist/auth/service.d.ts.map +1 -0
  15. package/dist/auth/service.js +298 -0
  16. package/dist/auth/service.js.map +1 -0
  17. package/dist/cli/index.d.ts +6 -0
  18. package/dist/cli/index.d.ts.map +1 -0
  19. package/dist/cli/index.js +375 -0
  20. package/dist/cli/index.js.map +1 -0
  21. package/dist/cli/mock-server.d.ts +20 -0
  22. package/dist/cli/mock-server.d.ts.map +1 -0
  23. package/dist/cli/mock-server.js +261 -0
  24. package/dist/cli/mock-server.js.map +1 -0
  25. package/dist/compliance/compliance-generator.d.ts +34 -0
  26. package/dist/compliance/compliance-generator.d.ts.map +1 -0
  27. package/dist/compliance/compliance-generator.js +320 -0
  28. package/dist/compliance/compliance-generator.js.map +1 -0
  29. package/dist/compliance/index.d.ts +8 -0
  30. package/dist/compliance/index.d.ts.map +1 -0
  31. package/dist/compliance/index.js +17 -0
  32. package/dist/compliance/index.js.map +1 -0
  33. package/dist/compliance/templates.d.ts +34 -0
  34. package/dist/compliance/templates.d.ts.map +1 -0
  35. package/{src/compliance/templates.ts → dist/compliance/templates.js} +117 -155
  36. package/dist/compliance/templates.js.map +1 -0
  37. package/dist/compliance/types.d.ts +64 -0
  38. package/dist/compliance/types.d.ts.map +1 -0
  39. package/dist/compliance/types.js +64 -0
  40. package/dist/compliance/types.js.map +1 -0
  41. package/dist/db/index.d.ts +17 -0
  42. package/dist/db/index.d.ts.map +1 -0
  43. package/dist/db/index.js +80 -0
  44. package/dist/db/index.js.map +1 -0
  45. package/dist/db/schema.d.ts +3886 -0
  46. package/dist/db/schema.d.ts.map +1 -0
  47. package/dist/db/schema.js +425 -0
  48. package/dist/db/schema.js.map +1 -0
  49. package/dist/db/utils.d.ts +252 -0
  50. package/dist/db/utils.d.ts.map +1 -0
  51. package/dist/db/utils.js +295 -0
  52. package/dist/db/utils.js.map +1 -0
  53. package/dist/feed-analyzer/feed-analyzer.d.ts +26 -0
  54. package/dist/feed-analyzer/feed-analyzer.d.ts.map +1 -0
  55. package/{src/feed-analyzer/feed-analyzer.ts → dist/feed-analyzer/feed-analyzer.js} +856 -726
  56. package/dist/feed-analyzer/feed-analyzer.js.map +1 -0
  57. package/dist/feed-analyzer/index.d.ts +8 -0
  58. package/dist/feed-analyzer/index.d.ts.map +1 -0
  59. package/dist/feed-analyzer/index.js +19 -0
  60. package/dist/feed-analyzer/index.js.map +1 -0
  61. package/dist/feed-analyzer/types.d.ts +285 -0
  62. package/dist/feed-analyzer/types.d.ts.map +1 -0
  63. package/dist/feed-analyzer/types.js +175 -0
  64. package/dist/feed-analyzer/types.js.map +1 -0
  65. package/{src/generator/index.ts → dist/generator/index.d.ts} +1 -1
  66. package/dist/generator/index.d.ts.map +1 -0
  67. package/dist/generator/index.js +13 -0
  68. package/dist/generator/index.js.map +1 -0
  69. package/dist/generator/key-generator.d.ts +24 -0
  70. package/dist/generator/key-generator.d.ts.map +1 -0
  71. package/dist/generator/key-generator.js +144 -0
  72. package/dist/generator/key-generator.js.map +1 -0
  73. package/dist/generator/profile-builder.d.ts +15 -0
  74. package/dist/generator/profile-builder.d.ts.map +1 -0
  75. package/dist/generator/profile-builder.js +338 -0
  76. package/dist/generator/profile-builder.js.map +1 -0
  77. package/dist/hosting/artifacts-generator.d.ts +10 -0
  78. package/dist/hosting/artifacts-generator.d.ts.map +1 -0
  79. package/{src/hosting/artifacts-generator.ts → dist/hosting/artifacts-generator.js} +191 -241
  80. package/dist/hosting/artifacts-generator.js.map +1 -0
  81. package/{src/hosting/index.ts → dist/hosting/index.d.ts} +1 -1
  82. package/dist/hosting/index.d.ts.map +1 -0
  83. package/dist/hosting/index.js +10 -0
  84. package/dist/hosting/index.js.map +1 -0
  85. package/dist/index.d.ts +18 -0
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.js +78 -0
  88. package/dist/index.js.map +1 -0
  89. package/dist/lib/analytics.d.ts +337 -0
  90. package/dist/lib/analytics.d.ts.map +1 -0
  91. package/dist/lib/analytics.js +188 -0
  92. package/dist/lib/analytics.js.map +1 -0
  93. package/{src/security/index.ts → dist/security/index.d.ts} +8 -15
  94. package/dist/security/index.d.ts.map +1 -0
  95. package/dist/security/index.js +12 -0
  96. package/dist/security/index.js.map +1 -0
  97. package/dist/security/security-scanner.d.ts +10 -0
  98. package/dist/security/security-scanner.d.ts.map +1 -0
  99. package/dist/security/security-scanner.js +669 -0
  100. package/dist/security/security-scanner.js.map +1 -0
  101. package/dist/security/types.d.ts +80 -0
  102. package/dist/security/types.d.ts.map +1 -0
  103. package/dist/security/types.js +21 -0
  104. package/dist/security/types.js.map +1 -0
  105. package/dist/services/analytics.d.ts +114 -0
  106. package/dist/services/analytics.d.ts.map +1 -0
  107. package/dist/services/analytics.js +862 -0
  108. package/dist/services/analytics.js.map +1 -0
  109. package/dist/services/badge.d.ts +31 -0
  110. package/dist/services/badge.d.ts.map +1 -0
  111. package/dist/services/badge.js +152 -0
  112. package/dist/services/badge.js.map +1 -0
  113. package/dist/services/cron.d.ts +125 -0
  114. package/dist/services/cron.d.ts.map +1 -0
  115. package/dist/services/cron.js +613 -0
  116. package/dist/services/cron.js.map +1 -0
  117. package/dist/services/directory.d.ts +106 -0
  118. package/dist/services/directory.d.ts.map +1 -0
  119. package/dist/services/directory.js +351 -0
  120. package/dist/services/directory.js.map +1 -0
  121. package/dist/services/email.d.ts +112 -0
  122. package/dist/services/email.d.ts.map +1 -0
  123. package/dist/services/email.js +772 -0
  124. package/dist/services/email.js.map +1 -0
  125. package/dist/services/hosted-profiles.d.ts +77 -0
  126. package/dist/services/hosted-profiles.d.ts.map +1 -0
  127. package/dist/services/hosted-profiles.js +433 -0
  128. package/dist/services/hosted-profiles.js.map +1 -0
  129. package/dist/services/latency.d.ts +67 -0
  130. package/dist/services/latency.d.ts.map +1 -0
  131. package/dist/services/latency.js +274 -0
  132. package/dist/services/latency.js.map +1 -0
  133. package/dist/services/manifest-compliance.d.ts +64 -0
  134. package/dist/services/manifest-compliance.d.ts.map +1 -0
  135. package/dist/services/manifest-compliance.js +271 -0
  136. package/dist/services/manifest-compliance.js.map +1 -0
  137. package/dist/services/monitoring-diff.d.ts +31 -0
  138. package/dist/services/monitoring-diff.d.ts.map +1 -0
  139. package/dist/services/monitoring-diff.js +189 -0
  140. package/dist/services/monitoring-diff.js.map +1 -0
  141. package/dist/services/notifications.d.ts +46 -0
  142. package/dist/services/notifications.d.ts.map +1 -0
  143. package/dist/services/notifications.js +88 -0
  144. package/dist/services/notifications.js.map +1 -0
  145. package/dist/services/stripe.d.ts +93 -0
  146. package/dist/services/stripe.d.ts.map +1 -0
  147. package/dist/services/stripe.js +490 -0
  148. package/dist/services/stripe.js.map +1 -0
  149. package/dist/services/validation-history.d.ts +99 -0
  150. package/dist/services/validation-history.d.ts.map +1 -0
  151. package/dist/services/validation-history.js +344 -0
  152. package/dist/services/validation-history.js.map +1 -0
  153. package/dist/services/validation-logging.d.ts +103 -0
  154. package/dist/services/validation-logging.d.ts.map +1 -0
  155. package/dist/services/validation-logging.js +210 -0
  156. package/dist/services/validation-logging.js.map +1 -0
  157. package/dist/services/validation.d.ts +119 -0
  158. package/dist/services/validation.d.ts.map +1 -0
  159. package/dist/services/validation.js +1185 -0
  160. package/dist/services/validation.js.map +1 -0
  161. package/dist/simulator/agent-simulator.d.ts +69 -0
  162. package/dist/simulator/agent-simulator.d.ts.map +1 -0
  163. package/dist/simulator/agent-simulator.js +870 -0
  164. package/dist/simulator/agent-simulator.js.map +1 -0
  165. package/{src/simulator/index.ts → dist/simulator/index.d.ts} +7 -7
  166. package/dist/simulator/index.d.ts.map +1 -0
  167. package/dist/simulator/index.js +23 -0
  168. package/dist/simulator/index.js.map +1 -0
  169. package/{src/simulator/types.ts → dist/simulator/types.d.ts} +171 -170
  170. package/dist/simulator/types.d.ts.map +1 -0
  171. package/dist/simulator/types.js +18 -0
  172. package/dist/simulator/types.js.map +1 -0
  173. package/dist/types/acp-validation.d.ts +87 -0
  174. package/dist/types/acp-validation.d.ts.map +1 -0
  175. package/dist/types/acp-validation.js +40 -0
  176. package/dist/types/acp-validation.js.map +1 -0
  177. package/dist/types/analytics.d.ts +182 -0
  178. package/dist/types/analytics.d.ts.map +1 -0
  179. package/dist/types/analytics.js +7 -0
  180. package/dist/types/analytics.js.map +1 -0
  181. package/dist/types/generator.d.ts +106 -0
  182. package/dist/types/generator.d.ts.map +1 -0
  183. package/dist/types/generator.js +6 -0
  184. package/dist/types/generator.js.map +1 -0
  185. package/{src/types/index.ts → dist/types/index.d.ts} +1 -1
  186. package/dist/types/index.d.ts.map +1 -0
  187. package/dist/types/index.js +23 -0
  188. package/dist/types/index.js.map +1 -0
  189. package/dist/types/ucp-profile.d.ts +111 -0
  190. package/dist/types/ucp-profile.d.ts.map +1 -0
  191. package/dist/types/ucp-profile.js +45 -0
  192. package/dist/types/ucp-profile.js.map +1 -0
  193. package/dist/types/validation.d.ts +76 -0
  194. package/dist/types/validation.d.ts.map +1 -0
  195. package/dist/types/validation.js +42 -0
  196. package/dist/types/validation.js.map +1 -0
  197. package/dist/validator/acp/index.d.ts +31 -0
  198. package/dist/validator/acp/index.d.ts.map +1 -0
  199. package/dist/validator/acp/index.js +574 -0
  200. package/dist/validator/acp/index.js.map +1 -0
  201. package/dist/validator/index.d.ts +26 -0
  202. package/dist/validator/index.d.ts.map +1 -0
  203. package/dist/validator/index.js +161 -0
  204. package/dist/validator/index.js.map +1 -0
  205. package/dist/validator/network-validator.d.ts +28 -0
  206. package/dist/validator/network-validator.d.ts.map +1 -0
  207. package/dist/validator/network-validator.js +319 -0
  208. package/dist/validator/network-validator.js.map +1 -0
  209. package/dist/validator/rules-validator.d.ts +19 -0
  210. package/dist/validator/rules-validator.d.ts.map +1 -0
  211. package/dist/validator/rules-validator.js +306 -0
  212. package/dist/validator/rules-validator.js.map +1 -0
  213. package/dist/validator/sdk-validator.d.ts +58 -0
  214. package/dist/validator/sdk-validator.d.ts.map +1 -0
  215. package/{src/validator/sdk-validator.ts → dist/validator/sdk-validator.js} +273 -330
  216. package/dist/validator/sdk-validator.js.map +1 -0
  217. package/dist/validator/structural-validator.d.ts +11 -0
  218. package/dist/validator/structural-validator.d.ts.map +1 -0
  219. package/dist/validator/structural-validator.js +549 -0
  220. package/dist/validator/structural-validator.js.map +1 -0
  221. package/dist/validator/utils.d.ts +51 -0
  222. package/dist/validator/utils.d.ts.map +1 -0
  223. package/dist/validator/utils.js +132 -0
  224. package/dist/validator/utils.js.map +1 -0
  225. package/package.json +44 -12
  226. package/CLAUDE.md +0 -109
  227. package/api/analyze-feed.js +0 -140
  228. package/api/badge.js +0 -185
  229. package/api/benchmark.js +0 -177
  230. package/api/directory-stats.ts +0 -29
  231. package/api/directory.ts +0 -73
  232. package/api/generate-compliance.js +0 -143
  233. package/api/generate-schema.js +0 -457
  234. package/api/generate.js +0 -132
  235. package/api/security-scan.js +0 -133
  236. package/api/simulate.js +0 -187
  237. package/api/tsconfig.json +0 -10
  238. package/api/validate.js +0 -1351
  239. package/apify-actor/.actor/actor.json +0 -68
  240. package/apify-actor/.actor/input_schema.json +0 -32
  241. package/apify-actor/APIFY-STORE-LISTING.md +0 -412
  242. package/apify-actor/Dockerfile +0 -8
  243. package/apify-actor/README.md +0 -166
  244. package/apify-actor/main.ts +0 -111
  245. package/apify-actor/package.json +0 -17
  246. package/apify-actor/src/main.js +0 -199
  247. package/docs/BRAND-IDENTITY.md +0 -238
  248. package/docs/BRAND-STYLE-GUIDE.md +0 -356
  249. package/drizzle/0000_black_king_cobra.sql +0 -39
  250. package/drizzle/meta/0000_snapshot.json +0 -309
  251. package/drizzle/meta/_journal.json +0 -13
  252. package/drizzle.config.ts +0 -10
  253. package/public/.well-known/ucp +0 -25
  254. package/public/android-chrome-192x192.png +0 -0
  255. package/public/android-chrome-512x512.png +0 -0
  256. package/public/apple-touch-icon.png +0 -0
  257. package/public/brand.css +0 -321
  258. package/public/directory.html +0 -701
  259. package/public/favicon-16x16.png +0 -0
  260. package/public/favicon-32x32.png +0 -0
  261. package/public/favicon.ico +0 -0
  262. package/public/guides/bigcommerce.html +0 -743
  263. package/public/guides/fastucp.html +0 -838
  264. package/public/guides/magento.html +0 -779
  265. package/public/guides/shopify.html +0 -726
  266. package/public/guides/squarespace.html +0 -749
  267. package/public/guides/wix.html +0 -747
  268. package/public/guides/woocommerce.html +0 -733
  269. package/public/index.html +0 -3835
  270. package/public/learn.html +0 -396
  271. package/public/logo.jpeg +0 -0
  272. package/public/og-image-icon.png +0 -0
  273. package/public/og-image.png +0 -0
  274. package/public/robots.txt +0 -6
  275. package/public/site.webmanifest +0 -31
  276. package/public/sitemap.xml +0 -69
  277. package/public/social/linkedin-banner-1128x191.png +0 -0
  278. package/public/social/temp.PNG +0 -0
  279. package/public/social/x-header-1500x500.png +0 -0
  280. package/public/verify.html +0 -410
  281. package/scripts/generate-favicons.js +0 -44
  282. package/scripts/generate-ico.js +0 -23
  283. package/scripts/generate-og-image.js +0 -45
  284. package/scripts/reset-db.ts +0 -77
  285. package/scripts/seed-db.ts +0 -71
  286. package/scripts/setup-benchmark-db.js +0 -70
  287. package/src/api/server.ts +0 -266
  288. package/src/cli/index.ts +0 -302
  289. package/src/compliance/compliance-generator.ts +0 -452
  290. package/src/compliance/index.ts +0 -28
  291. package/src/compliance/types.ts +0 -170
  292. package/src/db/index.ts +0 -28
  293. package/src/db/schema.ts +0 -84
  294. package/src/feed-analyzer/index.ts +0 -34
  295. package/src/feed-analyzer/types.ts +0 -354
  296. package/src/generator/key-generator.ts +0 -124
  297. package/src/generator/profile-builder.ts +0 -402
  298. package/src/index.ts +0 -105
  299. package/src/security/security-scanner.ts +0 -604
  300. package/src/security/types.ts +0 -55
  301. package/src/services/directory.ts +0 -434
  302. package/src/simulator/agent-simulator.ts +0 -941
  303. package/src/types/generator.ts +0 -140
  304. package/src/types/ucp-profile.ts +0 -140
  305. package/src/types/validation.ts +0 -89
  306. package/src/validator/index.ts +0 -194
  307. package/src/validator/network-validator.ts +0 -417
  308. package/src/validator/rules-validator.ts +0 -297
  309. package/src/validator/structural-validator.ts +0 -476
  310. package/tests/fixtures/non-compliant-profile.json +0 -25
  311. package/tests/fixtures/official-sample-profile.json +0 -75
  312. package/tests/integration/benchmark.test.ts +0 -207
  313. package/tests/integration/database.test.ts +0 -163
  314. package/tests/integration/directory-api.test.ts +0 -268
  315. package/tests/integration/simulate-api.test.ts +0 -230
  316. package/tests/integration/validate-api.test.ts +0 -269
  317. package/tests/setup.ts +0 -15
  318. package/tests/unit/agent-simulator.test.ts +0 -575
  319. package/tests/unit/compliance-generator.test.ts +0 -374
  320. package/tests/unit/directory-service.test.ts +0 -272
  321. package/tests/unit/feed-analyzer.test.ts +0 -517
  322. package/tests/unit/lint-suggestions.test.ts +0 -423
  323. package/tests/unit/official-samples.test.ts +0 -211
  324. package/tests/unit/pdf-report.test.ts +0 -390
  325. package/tests/unit/sdk-validator.test.ts +0 -531
  326. package/tests/unit/security-scanner.test.ts +0 -410
  327. package/tests/unit/validation.test.ts +0 -390
  328. package/tsconfig.json +0 -20
  329. package/vercel.json +0 -34
  330. package/vitest.config.ts +0 -22
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ /**
3
+ * Latency Testing Service
4
+ *
5
+ * Measures response times for UCP endpoints and API performance.
6
+ * Part of Issue #47: Latency & Performance Testing
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.THRESHOLDS = void 0;
10
+ exports.measureDomainLatency = measureDomainLatency;
11
+ exports.quickLatencyCheck = quickLatencyCheck;
12
+ exports.calculatePerformanceGrade = calculatePerformanceGrade;
13
+ exports.calculatePerformanceScore = calculatePerformanceScore;
14
+ // Performance thresholds (in milliseconds)
15
+ const THRESHOLDS = {
16
+ excellent: 200, // < 200ms = excellent
17
+ good: 500, // < 500ms = good
18
+ acceptable: 1000, // < 1000ms = acceptable
19
+ slow: 2000, // < 2000ms = slow
20
+ // > 2000ms = very_slow
21
+ };
22
+ exports.THRESHOLDS = THRESHOLDS;
23
+ // Timeout for requests
24
+ const DEFAULT_TIMEOUT_MS = 10000;
25
+ const SAMPLE_COUNT = 3; // Number of samples for averaging
26
+ /**
27
+ * Measure latency for a single request
28
+ */
29
+ async function measureLatency(url, method = 'GET', timeoutMs = DEFAULT_TIMEOUT_MS) {
30
+ const controller = new AbortController();
31
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
32
+ const startTime = performance.now();
33
+ const timestamp = new Date();
34
+ try {
35
+ const response = await fetch(url, {
36
+ method,
37
+ signal: controller.signal,
38
+ headers: {
39
+ 'Accept': method === 'HEAD' ? '*/*' : 'application/json',
40
+ 'User-Agent': 'UCP-Validator/1.0 (https://ucptools.dev)',
41
+ },
42
+ });
43
+ clearTimeout(timeoutId);
44
+ const endTime = performance.now();
45
+ const responseTimeMs = Math.round(endTime - startTime);
46
+ return {
47
+ url,
48
+ method,
49
+ responseTimeMs,
50
+ statusCode: response.status,
51
+ success: response.ok,
52
+ timestamp,
53
+ };
54
+ }
55
+ catch (error) {
56
+ clearTimeout(timeoutId);
57
+ const endTime = performance.now();
58
+ const responseTimeMs = Math.round(endTime - startTime);
59
+ let errorMessage = 'Unknown error';
60
+ if (error instanceof Error) {
61
+ if (error.name === 'AbortError') {
62
+ errorMessage = `Request timed out after ${timeoutMs}ms`;
63
+ }
64
+ else {
65
+ errorMessage = error.message;
66
+ }
67
+ }
68
+ return {
69
+ url,
70
+ method,
71
+ responseTimeMs,
72
+ statusCode: null,
73
+ success: false,
74
+ error: errorMessage,
75
+ timestamp,
76
+ };
77
+ }
78
+ }
79
+ /**
80
+ * Measure latency with multiple samples for reliability
81
+ */
82
+ async function measureEndpointLatency(url, method = 'GET', sampleCount = SAMPLE_COUNT, timeoutMs = DEFAULT_TIMEOUT_MS) {
83
+ const measurements = [];
84
+ for (let i = 0; i < sampleCount; i++) {
85
+ const measurement = await measureLatency(url, method, timeoutMs);
86
+ measurements.push(measurement);
87
+ // Small delay between samples to avoid rate limiting
88
+ if (i < sampleCount - 1) {
89
+ await new Promise(resolve => setTimeout(resolve, 100));
90
+ }
91
+ }
92
+ const successfulMeasurements = measurements.filter(m => m.success);
93
+ const responseTimes = successfulMeasurements.map(m => m.responseTimeMs);
94
+ const avgResponseTimeMs = responseTimes.length > 0
95
+ ? Math.round(responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length)
96
+ : 0;
97
+ const minResponseTimeMs = responseTimes.length > 0
98
+ ? Math.min(...responseTimes)
99
+ : 0;
100
+ const maxResponseTimeMs = responseTimes.length > 0
101
+ ? Math.max(...responseTimes)
102
+ : 0;
103
+ const successRate = measurements.length > 0
104
+ ? Math.round((successfulMeasurements.length / measurements.length) * 100)
105
+ : 0;
106
+ return {
107
+ endpoint: url,
108
+ measurements,
109
+ avgResponseTimeMs,
110
+ minResponseTimeMs,
111
+ maxResponseTimeMs,
112
+ successRate,
113
+ };
114
+ }
115
+ /**
116
+ * Calculate performance grade from average latency
117
+ */
118
+ function calculatePerformanceGrade(avgMs) {
119
+ if (avgMs < THRESHOLDS.excellent)
120
+ return 'excellent';
121
+ if (avgMs < THRESHOLDS.good)
122
+ return 'good';
123
+ if (avgMs < THRESHOLDS.acceptable)
124
+ return 'acceptable';
125
+ if (avgMs < THRESHOLDS.slow)
126
+ return 'slow';
127
+ return 'very_slow';
128
+ }
129
+ /**
130
+ * Calculate performance score (0-100) from latency
131
+ */
132
+ function calculatePerformanceScore(avgMs) {
133
+ // Score decreases as latency increases
134
+ // < 200ms = 100, 500ms = 80, 1000ms = 60, 2000ms = 40, > 3000ms = 20
135
+ if (avgMs <= THRESHOLDS.excellent) {
136
+ return 100;
137
+ }
138
+ if (avgMs <= THRESHOLDS.good) {
139
+ // Linear interpolation between 100 and 80
140
+ const ratio = (avgMs - THRESHOLDS.excellent) / (THRESHOLDS.good - THRESHOLDS.excellent);
141
+ return Math.round(100 - (ratio * 20));
142
+ }
143
+ if (avgMs <= THRESHOLDS.acceptable) {
144
+ // Linear interpolation between 80 and 60
145
+ const ratio = (avgMs - THRESHOLDS.good) / (THRESHOLDS.acceptable - THRESHOLDS.good);
146
+ return Math.round(80 - (ratio * 20));
147
+ }
148
+ if (avgMs <= THRESHOLDS.slow) {
149
+ // Linear interpolation between 60 and 40
150
+ const ratio = (avgMs - THRESHOLDS.acceptable) / (THRESHOLDS.slow - THRESHOLDS.acceptable);
151
+ return Math.round(60 - (ratio * 20));
152
+ }
153
+ // > 2000ms: interpolate from 40 down to minimum of 20
154
+ const ratio = Math.min((avgMs - THRESHOLDS.slow) / 1000, 1);
155
+ return Math.round(40 - (ratio * 20));
156
+ }
157
+ /**
158
+ * Extract API endpoint from UCP profile
159
+ */
160
+ function extractApiEndpoint(profile) {
161
+ // Try to find REST endpoint in services
162
+ if (profile?.ucp?.services) {
163
+ for (const [, service] of Object.entries(profile.ucp.services)) {
164
+ if (service?.rest?.endpoint) {
165
+ return service.rest.endpoint;
166
+ }
167
+ }
168
+ }
169
+ // Try legacy transport.rest.endpoint format
170
+ if (profile?.transport?.rest?.endpoint) {
171
+ return profile.transport.rest.endpoint;
172
+ }
173
+ return null;
174
+ }
175
+ /**
176
+ * Measure latency for a domain's UCP endpoints
177
+ */
178
+ async function measureDomainLatency(domain, profile, options = {}) {
179
+ const cleanDomain = domain.replace(/^https?:\/\//, '').replace(/\/$/, '').split('/')[0];
180
+ const sampleCount = options.sampleCount ?? 1; // Default to 1 for free tier
181
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
182
+ const measureHomepage = options.measureHomepage ?? true;
183
+ const measureApi = options.measureApi ?? true;
184
+ const testedAt = new Date();
185
+ const latencyResults = [];
186
+ // Measure UCP profile endpoint
187
+ const ucpUrls = [
188
+ `https://${cleanDomain}/.well-known/ucp`,
189
+ `https://${cleanDomain}/.well-known/ucp.json`,
190
+ ];
191
+ let ucpProfile = null;
192
+ for (const url of ucpUrls) {
193
+ const result = await measureEndpointLatency(url, 'GET', sampleCount, timeoutMs);
194
+ if (result.successRate > 0) {
195
+ ucpProfile = result;
196
+ latencyResults.push(result);
197
+ break;
198
+ }
199
+ }
200
+ // Measure API endpoint if available
201
+ let apiEndpoint = null;
202
+ if (measureApi && profile) {
203
+ const apiUrl = extractApiEndpoint(profile);
204
+ if (apiUrl) {
205
+ // Use HEAD request to avoid triggering actual API operations
206
+ apiEndpoint = await measureEndpointLatency(apiUrl, 'HEAD', sampleCount, timeoutMs);
207
+ if (apiEndpoint.successRate > 0) {
208
+ latencyResults.push(apiEndpoint);
209
+ }
210
+ }
211
+ }
212
+ // Measure homepage
213
+ let homepage = null;
214
+ if (measureHomepage) {
215
+ homepage = await measureEndpointLatency(`https://${cleanDomain}`, 'GET', sampleCount, timeoutMs);
216
+ if (homepage.successRate > 0) {
217
+ latencyResults.push(homepage);
218
+ }
219
+ }
220
+ // Calculate overall metrics
221
+ const successfulResults = latencyResults.filter(r => r.successRate > 0);
222
+ const overallAvgMs = successfulResults.length > 0
223
+ ? Math.round(successfulResults.reduce((sum, r) => sum + r.avgResponseTimeMs, 0) / successfulResults.length)
224
+ : 0;
225
+ // Weight UCP profile latency more heavily (it's the critical endpoint for AI agents)
226
+ const weightedAvgMs = ucpProfile && ucpProfile.successRate > 0
227
+ ? Math.round((ucpProfile.avgResponseTimeMs * 2 + (overallAvgMs || ucpProfile.avgResponseTimeMs)) / 3)
228
+ : overallAvgMs;
229
+ const performanceScore = calculatePerformanceScore(weightedAvgMs);
230
+ const performanceGrade = calculatePerformanceGrade(weightedAvgMs);
231
+ return {
232
+ domain: cleanDomain,
233
+ ucpProfile,
234
+ apiEndpoint,
235
+ homepage,
236
+ overallAvgMs: weightedAvgMs,
237
+ performanceScore,
238
+ performanceGrade,
239
+ testedAt,
240
+ };
241
+ }
242
+ /**
243
+ * Quick latency check (single sample) for free tier
244
+ */
245
+ async function quickLatencyCheck(domain) {
246
+ const cleanDomain = domain.replace(/^https?:\/\//, '').replace(/\/$/, '').split('/')[0];
247
+ // Single measurement for UCP profile
248
+ let ucpLatencyMs = null;
249
+ const ucpUrls = [
250
+ `https://${cleanDomain}/.well-known/ucp`,
251
+ `https://${cleanDomain}/.well-known/ucp.json`,
252
+ ];
253
+ for (const url of ucpUrls) {
254
+ const result = await measureLatency(url, 'GET', DEFAULT_TIMEOUT_MS);
255
+ if (result.success) {
256
+ ucpLatencyMs = result.responseTimeMs;
257
+ break;
258
+ }
259
+ }
260
+ // Single measurement for homepage
261
+ const homepageResult = await measureLatency(`https://${cleanDomain}`, 'GET', DEFAULT_TIMEOUT_MS);
262
+ const homepageLatencyMs = homepageResult.success ? homepageResult.responseTimeMs : null;
263
+ // Calculate score based on UCP latency (primary) or homepage (fallback)
264
+ const primaryLatency = ucpLatencyMs ?? homepageLatencyMs ?? 5000;
265
+ const performanceScore = calculatePerformanceScore(primaryLatency);
266
+ const performanceGrade = calculatePerformanceGrade(primaryLatency);
267
+ return {
268
+ ucpLatencyMs,
269
+ homepageLatencyMs,
270
+ performanceScore,
271
+ performanceGrade,
272
+ };
273
+ }
274
+ //# sourceMappingURL=latency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"latency.js","sourceRoot":"","sources":["../../src/services/latency.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Manifest Compliance Service
3
+ * Deep compliance check for UCP manifests — structured report format
4
+ * Addresses GH #100: .well-known/ucp manifest compliance check
5
+ */
6
+ export interface ManifestComplianceReport {
7
+ compliant: boolean;
8
+ version: {
9
+ found: boolean;
10
+ valid: boolean;
11
+ value: string | null;
12
+ format: string | null;
13
+ };
14
+ services: {
15
+ found: boolean;
16
+ count: number;
17
+ hasShoppingSvc: boolean;
18
+ transports: string[];
19
+ issues: string[];
20
+ };
21
+ capabilities: {
22
+ found: boolean;
23
+ count: number;
24
+ list: string[];
25
+ hasCheckout: boolean;
26
+ issues: string[];
27
+ };
28
+ endpoints: {
29
+ count: number;
30
+ allHttps: boolean;
31
+ noTrailingSlash: boolean;
32
+ issues: string[];
33
+ };
34
+ signingKeys: {
35
+ present: boolean;
36
+ count: number;
37
+ issues: string[];
38
+ };
39
+ wellKnown?: {
40
+ path: string;
41
+ contentType: string | null;
42
+ corsHeaders: boolean;
43
+ cacheHeaders: string | null;
44
+ responseTimeMs: number;
45
+ };
46
+ score: number;
47
+ grade: string;
48
+ issuesSummary: {
49
+ errors: number;
50
+ warnings: number;
51
+ info: number;
52
+ };
53
+ }
54
+ /**
55
+ * Check compliance of a UCP profile JSON object.
56
+ * Returns a structured compliance report.
57
+ */
58
+ export declare function checkProfileCompliance(profileJson: string): ManifestComplianceReport;
59
+ /**
60
+ * Check compliance of a remote domain's .well-known/ucp manifest.
61
+ * Fetches the manifest and then runs compliance checks.
62
+ */
63
+ export declare function checkManifestCompliance(domain: string): Promise<ManifestComplianceReport>;
64
+ //# sourceMappingURL=manifest-compliance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-compliance.d.ts","sourceRoot":"","sources":["../../src/services/manifest-compliance.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE;QACP,KAAK,EAAE,OAAO,CAAC;QACf,KAAK,EAAE,OAAO,CAAC;QACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;IACF,QAAQ,EAAE;QACR,KAAK,EAAE,OAAO,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,OAAO,CAAC;QACxB,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,WAAW,EAAE,OAAO,CAAC;QACrB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,SAAS,EAAE;QACT,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,OAAO,CAAC;QAClB,eAAe,EAAE,OAAO,CAAC;QACzB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,WAAW,EAAE;QACX,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE;QACb,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAMD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,wBAAwB,CAoBpF;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,CA8E/F"}
@@ -0,0 +1,271 @@
1
+ "use strict";
2
+ /**
3
+ * Manifest Compliance Service
4
+ * Deep compliance check for UCP manifests — structured report format
5
+ * Addresses GH #100: .well-known/ucp manifest compliance check
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.checkProfileCompliance = checkProfileCompliance;
9
+ exports.checkManifestCompliance = checkManifestCompliance;
10
+ const structural_validator_js_1 = require("../validator/structural-validator.js");
11
+ const rules_validator_js_1 = require("../validator/rules-validator.js");
12
+ // ============================================================================
13
+ // Core compliance check
14
+ // ============================================================================
15
+ /**
16
+ * Check compliance of a UCP profile JSON object.
17
+ * Returns a structured compliance report.
18
+ */
19
+ function checkProfileCompliance(profileJson) {
20
+ let parsed;
21
+ try {
22
+ parsed = JSON.parse(profileJson);
23
+ }
24
+ catch {
25
+ return buildFailedReport('Invalid JSON');
26
+ }
27
+ // Run structural + rules validation
28
+ const structuralIssues = (0, structural_validator_js_1.validateStructure)(parsed);
29
+ const hasStructuralErrors = structuralIssues.some((i) => i.severity === 'error');
30
+ let rulesIssues = [];
31
+ if (!hasStructuralErrors) {
32
+ rulesIssues = (0, rules_validator_js_1.validateRules)(parsed);
33
+ }
34
+ const allIssues = [...structuralIssues, ...rulesIssues];
35
+ return buildReport(parsed, allIssues);
36
+ }
37
+ /**
38
+ * Check compliance of a remote domain's .well-known/ucp manifest.
39
+ * Fetches the manifest and then runs compliance checks.
40
+ */
41
+ async function checkManifestCompliance(domain) {
42
+ const cleanDomain = domain.replace(/^https?:\/\//, '').replace(/\/$/, '').split('/')[0];
43
+ const url = `https://${cleanDomain}/.well-known/ucp`;
44
+ const startTime = Date.now();
45
+ let responseTimeMs = 0;
46
+ let contentType = null;
47
+ let corsHeaders = false;
48
+ let cacheHeaders = null;
49
+ let body;
50
+ try {
51
+ const controller = new AbortController();
52
+ const timeout = setTimeout(() => controller.abort(), 10000);
53
+ const response = await fetch(url, {
54
+ signal: controller.signal,
55
+ headers: { 'User-Agent': 'UCPtools-Compliance-Checker/1.0' },
56
+ });
57
+ clearTimeout(timeout);
58
+ responseTimeMs = Date.now() - startTime;
59
+ contentType = response.headers.get('content-type');
60
+ corsHeaders = response.headers.get('access-control-allow-origin') === '*';
61
+ cacheHeaders = response.headers.get('cache-control');
62
+ if (!response.ok) {
63
+ const report = buildFailedReport(`HTTP ${response.status} from ${url}`);
64
+ report.wellKnown = {
65
+ path: '/.well-known/ucp',
66
+ contentType,
67
+ corsHeaders,
68
+ cacheHeaders,
69
+ responseTimeMs,
70
+ };
71
+ return report;
72
+ }
73
+ body = await response.text();
74
+ }
75
+ catch (error) {
76
+ responseTimeMs = Date.now() - startTime;
77
+ const report = buildFailedReport(`Failed to fetch: ${error.message || 'unknown error'}`);
78
+ report.wellKnown = {
79
+ path: '/.well-known/ucp',
80
+ contentType: null,
81
+ corsHeaders: false,
82
+ cacheHeaders: null,
83
+ responseTimeMs,
84
+ };
85
+ return report;
86
+ }
87
+ // Parse and check
88
+ const report = checkProfileCompliance(body);
89
+ // Add well-known metadata
90
+ report.wellKnown = {
91
+ path: '/.well-known/ucp',
92
+ contentType,
93
+ corsHeaders,
94
+ cacheHeaders,
95
+ responseTimeMs,
96
+ };
97
+ // Add well-known-specific issues
98
+ if (!contentType?.includes('application/json')) {
99
+ report.endpoints.issues.push(`Content-Type should be application/json, got: ${contentType || 'none'}`);
100
+ }
101
+ if (!corsHeaders) {
102
+ report.endpoints.issues.push('Missing Access-Control-Allow-Origin: * header (required for cross-origin agent access)');
103
+ }
104
+ return report;
105
+ }
106
+ // ============================================================================
107
+ // Report builders
108
+ // ============================================================================
109
+ function buildReport(parsed, issues) {
110
+ const errors = issues.filter((i) => i.severity === 'error').length;
111
+ const warnings = issues.filter((i) => i.severity === 'warn').length;
112
+ const info = issues.filter((i) => i.severity === 'info').length;
113
+ const score = Math.max(0, 100 - errors * 15 - warnings * 5);
114
+ const grade = gradeFromScore(score);
115
+ const ucp = parsed?.ucp;
116
+ // Version
117
+ const version = {
118
+ found: !!ucp?.version,
119
+ valid: typeof ucp?.version === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(ucp.version),
120
+ value: ucp?.version || null,
121
+ format: ucp?.version ? ((/^\d{4}-\d{2}-\d{2}$/.test(ucp.version)) ? 'YYYY-MM-DD' : 'unknown') : null,
122
+ };
123
+ // Services
124
+ const services = analyzeServices(ucp?.services);
125
+ // Capabilities
126
+ const capabilities = analyzeCapabilities(ucp?.capabilities);
127
+ // Endpoints
128
+ const endpoints = analyzeEndpoints(ucp?.services, issues);
129
+ // Signing keys
130
+ const signingKeys = analyzeSigningKeys(ucp?.signing_keys);
131
+ return {
132
+ compliant: errors === 0,
133
+ version,
134
+ services,
135
+ capabilities,
136
+ endpoints,
137
+ signingKeys,
138
+ score,
139
+ grade,
140
+ issuesSummary: { errors, warnings, info },
141
+ };
142
+ }
143
+ function buildFailedReport(reason) {
144
+ return {
145
+ compliant: false,
146
+ version: { found: false, valid: false, value: null, format: null },
147
+ services: { found: false, count: 0, hasShoppingSvc: false, transports: [], issues: [reason] },
148
+ capabilities: { found: false, count: 0, list: [], hasCheckout: false, issues: [] },
149
+ endpoints: { count: 0, allHttps: true, noTrailingSlash: true, issues: [] },
150
+ signingKeys: { present: false, count: 0, issues: [] },
151
+ score: 0,
152
+ grade: 'F',
153
+ issuesSummary: { errors: 1, warnings: 0, info: 0 },
154
+ };
155
+ }
156
+ function gradeFromScore(score) {
157
+ if (score >= 90)
158
+ return 'A';
159
+ if (score >= 75)
160
+ return 'B';
161
+ if (score >= 60)
162
+ return 'C';
163
+ if (score >= 40)
164
+ return 'D';
165
+ return 'F';
166
+ }
167
+ // ============================================================================
168
+ // Analyzers
169
+ // ============================================================================
170
+ function analyzeServices(services) {
171
+ if (!services || typeof services !== 'object') {
172
+ return { found: false, count: 0, hasShoppingSvc: false, transports: [], issues: ['No services defined'] };
173
+ }
174
+ const svcEntries = Object.entries(services);
175
+ const transports = new Set();
176
+ let hasShoppingSvc = false;
177
+ for (const [name, svc] of svcEntries) {
178
+ if (typeof svc !== 'object' || !svc)
179
+ continue;
180
+ const s = svc;
181
+ if (s.rest)
182
+ transports.add('REST');
183
+ if (s.mcp)
184
+ transports.add('MCP');
185
+ if (s.a2a)
186
+ transports.add('A2A');
187
+ if (s.embedded)
188
+ transports.add('Embedded');
189
+ if (name.toLowerCase().includes('shop') || name.toLowerCase().includes('commerce')) {
190
+ hasShoppingSvc = true;
191
+ }
192
+ }
193
+ return {
194
+ found: true,
195
+ count: svcEntries.length,
196
+ hasShoppingSvc,
197
+ transports: Array.from(transports),
198
+ issues: [],
199
+ };
200
+ }
201
+ function analyzeCapabilities(capabilities) {
202
+ if (!Array.isArray(capabilities)) {
203
+ return { found: false, count: 0, list: [], hasCheckout: false, issues: ['No capabilities defined'] };
204
+ }
205
+ const names = capabilities
206
+ .filter((c) => c && typeof c === 'object')
207
+ .map((c) => c.name || c.type || 'unknown');
208
+ const hasCheckout = names.some((n) => n.toLowerCase().includes('checkout') || n.toLowerCase().includes('payment'));
209
+ return {
210
+ found: true,
211
+ count: capabilities.length,
212
+ list: names,
213
+ hasCheckout,
214
+ issues: [],
215
+ };
216
+ }
217
+ function analyzeEndpoints(services, issues) {
218
+ const endpointUrls = [];
219
+ if (services && typeof services === 'object') {
220
+ for (const svc of Object.values(services)) {
221
+ if (!svc || typeof svc !== 'object')
222
+ continue;
223
+ const s = svc;
224
+ // Extract endpoints from each transport
225
+ for (const transport of ['rest', 'mcp', 'a2a', 'embedded']) {
226
+ const t = s[transport];
227
+ if (t?.endpoint && typeof t.endpoint === 'string') {
228
+ endpointUrls.push(t.endpoint);
229
+ }
230
+ }
231
+ }
232
+ }
233
+ const allHttps = endpointUrls.every((u) => u.startsWith('https://'));
234
+ const noTrailingSlash = endpointUrls.every((u) => !u.endsWith('/'));
235
+ const endpointIssues = [];
236
+ const httpIssues = issues.filter((i) => i.code === 'UCP_ENDPOINT_NOT_HTTPS');
237
+ const slashIssues = issues.filter((i) => i.code === 'UCP_ENDPOINT_TRAILING_SLASH');
238
+ if (httpIssues.length > 0)
239
+ endpointIssues.push(`${httpIssues.length} endpoint(s) not using HTTPS`);
240
+ if (slashIssues.length > 0)
241
+ endpointIssues.push(`${slashIssues.length} endpoint(s) have trailing slash`);
242
+ return {
243
+ count: endpointUrls.length,
244
+ allHttps,
245
+ noTrailingSlash,
246
+ issues: endpointIssues,
247
+ };
248
+ }
249
+ function analyzeSigningKeys(signingKeys) {
250
+ if (!Array.isArray(signingKeys) || signingKeys.length === 0) {
251
+ return { present: false, count: 0, issues: ['No signing keys defined'] };
252
+ }
253
+ const keyIssues = [];
254
+ for (const key of signingKeys) {
255
+ if (!key || typeof key !== 'object') {
256
+ keyIssues.push('Invalid signing key entry');
257
+ continue;
258
+ }
259
+ const k = key;
260
+ if (!k.algorithm)
261
+ keyIssues.push('Signing key missing algorithm');
262
+ if (!k.publicKey && !k.public_key)
263
+ keyIssues.push('Signing key missing public key');
264
+ }
265
+ return {
266
+ present: true,
267
+ count: signingKeys.length,
268
+ issues: keyIssues,
269
+ };
270
+ }
271
+ //# sourceMappingURL=manifest-compliance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-compliance.js","sourceRoot":"","sources":["../../src/services/manifest-compliance.ts"],"names":[],"mappings":"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"}