@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.
- package/dist/auth/config.d.ts +20 -0
- package/dist/auth/config.d.ts.map +1 -0
- package/dist/auth/config.js +114 -0
- package/dist/auth/config.js.map +1 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +17 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/middleware.d.ts +45 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +170 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/service.d.ts +80 -0
- package/dist/auth/service.d.ts.map +1 -0
- package/dist/auth/service.js +298 -0
- package/dist/auth/service.js.map +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +375 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/mock-server.d.ts +20 -0
- package/dist/cli/mock-server.d.ts.map +1 -0
- package/dist/cli/mock-server.js +261 -0
- package/dist/cli/mock-server.js.map +1 -0
- package/dist/compliance/compliance-generator.d.ts +34 -0
- package/dist/compliance/compliance-generator.d.ts.map +1 -0
- package/dist/compliance/compliance-generator.js +320 -0
- package/dist/compliance/compliance-generator.js.map +1 -0
- package/dist/compliance/index.d.ts +8 -0
- package/dist/compliance/index.d.ts.map +1 -0
- package/dist/compliance/index.js +17 -0
- package/dist/compliance/index.js.map +1 -0
- package/dist/compliance/templates.d.ts +34 -0
- package/dist/compliance/templates.d.ts.map +1 -0
- package/{src/compliance/templates.ts → dist/compliance/templates.js} +117 -155
- package/dist/compliance/templates.js.map +1 -0
- package/dist/compliance/types.d.ts +64 -0
- package/dist/compliance/types.d.ts.map +1 -0
- package/dist/compliance/types.js +64 -0
- package/dist/compliance/types.js.map +1 -0
- package/dist/db/index.d.ts +17 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +80 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.d.ts +3886 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +425 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/utils.d.ts +252 -0
- package/dist/db/utils.d.ts.map +1 -0
- package/dist/db/utils.js +295 -0
- package/dist/db/utils.js.map +1 -0
- package/dist/feed-analyzer/feed-analyzer.d.ts +26 -0
- package/dist/feed-analyzer/feed-analyzer.d.ts.map +1 -0
- package/{src/feed-analyzer/feed-analyzer.ts → dist/feed-analyzer/feed-analyzer.js} +856 -726
- package/dist/feed-analyzer/feed-analyzer.js.map +1 -0
- package/dist/feed-analyzer/index.d.ts +8 -0
- package/dist/feed-analyzer/index.d.ts.map +1 -0
- package/dist/feed-analyzer/index.js +19 -0
- package/dist/feed-analyzer/index.js.map +1 -0
- package/dist/feed-analyzer/types.d.ts +285 -0
- package/dist/feed-analyzer/types.d.ts.map +1 -0
- package/dist/feed-analyzer/types.js +175 -0
- package/dist/feed-analyzer/types.js.map +1 -0
- package/{src/generator/index.ts → dist/generator/index.d.ts} +1 -1
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +13 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/key-generator.d.ts +24 -0
- package/dist/generator/key-generator.d.ts.map +1 -0
- package/dist/generator/key-generator.js +144 -0
- package/dist/generator/key-generator.js.map +1 -0
- package/dist/generator/profile-builder.d.ts +15 -0
- package/dist/generator/profile-builder.d.ts.map +1 -0
- package/dist/generator/profile-builder.js +338 -0
- package/dist/generator/profile-builder.js.map +1 -0
- package/dist/hosting/artifacts-generator.d.ts +10 -0
- package/dist/hosting/artifacts-generator.d.ts.map +1 -0
- package/{src/hosting/artifacts-generator.ts → dist/hosting/artifacts-generator.js} +191 -241
- package/dist/hosting/artifacts-generator.js.map +1 -0
- package/{src/hosting/index.ts → dist/hosting/index.d.ts} +1 -1
- package/dist/hosting/index.d.ts.map +1 -0
- package/dist/hosting/index.js +10 -0
- package/dist/hosting/index.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/analytics.d.ts +337 -0
- package/dist/lib/analytics.d.ts.map +1 -0
- package/dist/lib/analytics.js +188 -0
- package/dist/lib/analytics.js.map +1 -0
- package/{src/security/index.ts → dist/security/index.d.ts} +8 -15
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +12 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/security-scanner.d.ts +10 -0
- package/dist/security/security-scanner.d.ts.map +1 -0
- package/dist/security/security-scanner.js +669 -0
- package/dist/security/security-scanner.js.map +1 -0
- package/dist/security/types.d.ts +80 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security/types.js +21 -0
- package/dist/security/types.js.map +1 -0
- package/dist/services/analytics.d.ts +114 -0
- package/dist/services/analytics.d.ts.map +1 -0
- package/dist/services/analytics.js +862 -0
- package/dist/services/analytics.js.map +1 -0
- package/dist/services/badge.d.ts +31 -0
- package/dist/services/badge.d.ts.map +1 -0
- package/dist/services/badge.js +152 -0
- package/dist/services/badge.js.map +1 -0
- package/dist/services/cron.d.ts +125 -0
- package/dist/services/cron.d.ts.map +1 -0
- package/dist/services/cron.js +613 -0
- package/dist/services/cron.js.map +1 -0
- package/dist/services/directory.d.ts +106 -0
- package/dist/services/directory.d.ts.map +1 -0
- package/dist/services/directory.js +351 -0
- package/dist/services/directory.js.map +1 -0
- package/dist/services/email.d.ts +112 -0
- package/dist/services/email.d.ts.map +1 -0
- package/dist/services/email.js +772 -0
- package/dist/services/email.js.map +1 -0
- package/dist/services/hosted-profiles.d.ts +77 -0
- package/dist/services/hosted-profiles.d.ts.map +1 -0
- package/dist/services/hosted-profiles.js +433 -0
- package/dist/services/hosted-profiles.js.map +1 -0
- package/dist/services/latency.d.ts +67 -0
- package/dist/services/latency.d.ts.map +1 -0
- package/dist/services/latency.js +274 -0
- package/dist/services/latency.js.map +1 -0
- package/dist/services/manifest-compliance.d.ts +64 -0
- package/dist/services/manifest-compliance.d.ts.map +1 -0
- package/dist/services/manifest-compliance.js +271 -0
- package/dist/services/manifest-compliance.js.map +1 -0
- package/dist/services/monitoring-diff.d.ts +31 -0
- package/dist/services/monitoring-diff.d.ts.map +1 -0
- package/dist/services/monitoring-diff.js +189 -0
- package/dist/services/monitoring-diff.js.map +1 -0
- package/dist/services/notifications.d.ts +46 -0
- package/dist/services/notifications.d.ts.map +1 -0
- package/dist/services/notifications.js +88 -0
- package/dist/services/notifications.js.map +1 -0
- package/dist/services/stripe.d.ts +93 -0
- package/dist/services/stripe.d.ts.map +1 -0
- package/dist/services/stripe.js +490 -0
- package/dist/services/stripe.js.map +1 -0
- package/dist/services/validation-history.d.ts +99 -0
- package/dist/services/validation-history.d.ts.map +1 -0
- package/dist/services/validation-history.js +344 -0
- package/dist/services/validation-history.js.map +1 -0
- package/dist/services/validation-logging.d.ts +103 -0
- package/dist/services/validation-logging.d.ts.map +1 -0
- package/dist/services/validation-logging.js +210 -0
- package/dist/services/validation-logging.js.map +1 -0
- package/dist/services/validation.d.ts +119 -0
- package/dist/services/validation.d.ts.map +1 -0
- package/dist/services/validation.js +1185 -0
- package/dist/services/validation.js.map +1 -0
- package/dist/simulator/agent-simulator.d.ts +69 -0
- package/dist/simulator/agent-simulator.d.ts.map +1 -0
- package/dist/simulator/agent-simulator.js +870 -0
- package/dist/simulator/agent-simulator.js.map +1 -0
- package/{src/simulator/index.ts → dist/simulator/index.d.ts} +7 -7
- package/dist/simulator/index.d.ts.map +1 -0
- package/dist/simulator/index.js +23 -0
- package/dist/simulator/index.js.map +1 -0
- package/{src/simulator/types.ts → dist/simulator/types.d.ts} +171 -170
- package/dist/simulator/types.d.ts.map +1 -0
- package/dist/simulator/types.js +18 -0
- package/dist/simulator/types.js.map +1 -0
- package/dist/types/acp-validation.d.ts +87 -0
- package/dist/types/acp-validation.d.ts.map +1 -0
- package/dist/types/acp-validation.js +40 -0
- package/dist/types/acp-validation.js.map +1 -0
- package/dist/types/analytics.d.ts +182 -0
- package/dist/types/analytics.d.ts.map +1 -0
- package/dist/types/analytics.js +7 -0
- package/dist/types/analytics.js.map +1 -0
- package/dist/types/generator.d.ts +106 -0
- package/dist/types/generator.d.ts.map +1 -0
- package/dist/types/generator.js +6 -0
- package/dist/types/generator.js.map +1 -0
- package/{src/types/index.ts → dist/types/index.d.ts} +1 -1
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +23 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/ucp-profile.d.ts +111 -0
- package/dist/types/ucp-profile.d.ts.map +1 -0
- package/dist/types/ucp-profile.js +45 -0
- package/dist/types/ucp-profile.js.map +1 -0
- package/dist/types/validation.d.ts +76 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +42 -0
- package/dist/types/validation.js.map +1 -0
- package/dist/validator/acp/index.d.ts +31 -0
- package/dist/validator/acp/index.d.ts.map +1 -0
- package/dist/validator/acp/index.js +574 -0
- package/dist/validator/acp/index.js.map +1 -0
- package/dist/validator/index.d.ts +26 -0
- package/dist/validator/index.d.ts.map +1 -0
- package/dist/validator/index.js +161 -0
- package/dist/validator/index.js.map +1 -0
- package/dist/validator/network-validator.d.ts +28 -0
- package/dist/validator/network-validator.d.ts.map +1 -0
- package/dist/validator/network-validator.js +319 -0
- package/dist/validator/network-validator.js.map +1 -0
- package/dist/validator/rules-validator.d.ts +19 -0
- package/dist/validator/rules-validator.d.ts.map +1 -0
- package/dist/validator/rules-validator.js +306 -0
- package/dist/validator/rules-validator.js.map +1 -0
- package/dist/validator/sdk-validator.d.ts +58 -0
- package/dist/validator/sdk-validator.d.ts.map +1 -0
- package/{src/validator/sdk-validator.ts → dist/validator/sdk-validator.js} +273 -330
- package/dist/validator/sdk-validator.js.map +1 -0
- package/dist/validator/structural-validator.d.ts +11 -0
- package/dist/validator/structural-validator.d.ts.map +1 -0
- package/dist/validator/structural-validator.js +549 -0
- package/dist/validator/structural-validator.js.map +1 -0
- package/dist/validator/utils.d.ts +51 -0
- package/dist/validator/utils.d.ts.map +1 -0
- package/dist/validator/utils.js +132 -0
- package/dist/validator/utils.js.map +1 -0
- package/package.json +44 -12
- package/CLAUDE.md +0 -109
- package/api/analyze-feed.js +0 -140
- package/api/badge.js +0 -185
- package/api/benchmark.js +0 -177
- package/api/directory-stats.ts +0 -29
- package/api/directory.ts +0 -73
- package/api/generate-compliance.js +0 -143
- package/api/generate-schema.js +0 -457
- package/api/generate.js +0 -132
- package/api/security-scan.js +0 -133
- package/api/simulate.js +0 -187
- package/api/tsconfig.json +0 -10
- package/api/validate.js +0 -1351
- package/apify-actor/.actor/actor.json +0 -68
- package/apify-actor/.actor/input_schema.json +0 -32
- package/apify-actor/APIFY-STORE-LISTING.md +0 -412
- package/apify-actor/Dockerfile +0 -8
- package/apify-actor/README.md +0 -166
- package/apify-actor/main.ts +0 -111
- package/apify-actor/package.json +0 -17
- package/apify-actor/src/main.js +0 -199
- package/docs/BRAND-IDENTITY.md +0 -238
- package/docs/BRAND-STYLE-GUIDE.md +0 -356
- package/drizzle/0000_black_king_cobra.sql +0 -39
- package/drizzle/meta/0000_snapshot.json +0 -309
- package/drizzle/meta/_journal.json +0 -13
- package/drizzle.config.ts +0 -10
- package/public/.well-known/ucp +0 -25
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/brand.css +0 -321
- package/public/directory.html +0 -701
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/guides/bigcommerce.html +0 -743
- package/public/guides/fastucp.html +0 -838
- package/public/guides/magento.html +0 -779
- package/public/guides/shopify.html +0 -726
- package/public/guides/squarespace.html +0 -749
- package/public/guides/wix.html +0 -747
- package/public/guides/woocommerce.html +0 -733
- package/public/index.html +0 -3835
- package/public/learn.html +0 -396
- package/public/logo.jpeg +0 -0
- package/public/og-image-icon.png +0 -0
- package/public/og-image.png +0 -0
- package/public/robots.txt +0 -6
- package/public/site.webmanifest +0 -31
- package/public/sitemap.xml +0 -69
- package/public/social/linkedin-banner-1128x191.png +0 -0
- package/public/social/temp.PNG +0 -0
- package/public/social/x-header-1500x500.png +0 -0
- package/public/verify.html +0 -410
- package/scripts/generate-favicons.js +0 -44
- package/scripts/generate-ico.js +0 -23
- package/scripts/generate-og-image.js +0 -45
- package/scripts/reset-db.ts +0 -77
- package/scripts/seed-db.ts +0 -71
- package/scripts/setup-benchmark-db.js +0 -70
- package/src/api/server.ts +0 -266
- package/src/cli/index.ts +0 -302
- package/src/compliance/compliance-generator.ts +0 -452
- package/src/compliance/index.ts +0 -28
- package/src/compliance/types.ts +0 -170
- package/src/db/index.ts +0 -28
- package/src/db/schema.ts +0 -84
- package/src/feed-analyzer/index.ts +0 -34
- package/src/feed-analyzer/types.ts +0 -354
- package/src/generator/key-generator.ts +0 -124
- package/src/generator/profile-builder.ts +0 -402
- package/src/index.ts +0 -105
- package/src/security/security-scanner.ts +0 -604
- package/src/security/types.ts +0 -55
- package/src/services/directory.ts +0 -434
- package/src/simulator/agent-simulator.ts +0 -941
- package/src/types/generator.ts +0 -140
- package/src/types/ucp-profile.ts +0 -140
- package/src/types/validation.ts +0 -89
- package/src/validator/index.ts +0 -194
- package/src/validator/network-validator.ts +0 -417
- package/src/validator/rules-validator.ts +0 -297
- package/src/validator/structural-validator.ts +0 -476
- package/tests/fixtures/non-compliant-profile.json +0 -25
- package/tests/fixtures/official-sample-profile.json +0 -75
- package/tests/integration/benchmark.test.ts +0 -207
- package/tests/integration/database.test.ts +0 -163
- package/tests/integration/directory-api.test.ts +0 -268
- package/tests/integration/simulate-api.test.ts +0 -230
- package/tests/integration/validate-api.test.ts +0 -269
- package/tests/setup.ts +0 -15
- package/tests/unit/agent-simulator.test.ts +0 -575
- package/tests/unit/compliance-generator.test.ts +0 -374
- package/tests/unit/directory-service.test.ts +0 -272
- package/tests/unit/feed-analyzer.test.ts +0 -517
- package/tests/unit/lint-suggestions.test.ts +0 -423
- package/tests/unit/official-samples.test.ts +0 -211
- package/tests/unit/pdf-report.test.ts +0 -390
- package/tests/unit/sdk-validator.test.ts +0 -531
- package/tests/unit/security-scanner.test.ts +0 -410
- package/tests/unit/validation.test.ts +0 -390
- package/tsconfig.json +0 -20
- package/vercel.json +0 -34
- 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":";AAAA;;;;GAIG;;AAoEH,wDAoBC;AAMD,0DA8EC;AA1KD,kFAAyE;AACzE,wEAAgE;AAyDhE,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E;;;GAGG;AACH,SAAgB,sBAAsB,CAAC,WAAmB;IACxD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAC3C,CAAC;IAED,oCAAoC;IACpC,MAAM,gBAAgB,GAAG,IAAA,2CAAiB,EAAC,MAAM,CAAC,CAAC;IACnD,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAEjF,IAAI,WAAW,GAAsB,EAAE,CAAC;IACxC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzB,WAAW,GAAG,IAAA,kCAAa,EAAC,MAAoB,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,SAAS,GAAG,CAAC,GAAG,gBAAgB,EAAE,GAAG,WAAW,CAAC,CAAC;IAExD,OAAO,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,uBAAuB,CAAC,MAAc;IAC1D,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxF,MAAM,GAAG,GAAG,WAAW,WAAW,kBAAkB,CAAC;IAErD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,YAAY,GAAkB,IAAI,CAAC;IACvC,IAAI,IAAY,CAAC;IAEjB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;QAE5D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,OAAO,EAAE,EAAE,YAAY,EAAE,iCAAiC,EAAE;SAC7D,CAAC,CAAC;QAEH,YAAY,CAAC,OAAO,CAAC,CAAC;QACtB,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAExC,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACnD,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,KAAK,GAAG,CAAC;QAC1E,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAErD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,QAAQ,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC;YACxE,MAAM,CAAC,SAAS,GAAG;gBACjB,IAAI,EAAE,kBAAkB;gBACxB,WAAW;gBACX,WAAW;gBACX,YAAY;gBACZ,cAAc;aACf,CAAC;YACF,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QACxC,MAAM,MAAM,GAAG,iBAAiB,CAAC,oBAAoB,KAAK,CAAC,OAAO,IAAI,eAAe,EAAE,CAAC,CAAC;QACzF,MAAM,CAAC,SAAS,GAAG;YACjB,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,IAAI;YACjB,WAAW,EAAE,KAAK;YAClB,YAAY,EAAE,IAAI;YAClB,cAAc;SACf,CAAC;QACF,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,kBAAkB;IAClB,MAAM,MAAM,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAE5C,0BAA0B;IAC1B,MAAM,CAAC,SAAS,GAAG;QACjB,IAAI,EAAE,kBAAkB;QACxB,WAAW;QACX,WAAW;QACX,YAAY;QACZ,cAAc;KACf,CAAC;IAEF,iCAAiC;IACjC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC/C,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAC1B,iDAAiD,WAAW,IAAI,MAAM,EAAE,CACzE,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAC1B,wFAAwF,CACzF,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+EAA+E;AAC/E,kBAAkB;AAClB,+EAA+E;AAE/E,SAAS,WAAW,CAAC,MAAe,EAAE,MAAyB;IAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IACnE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACpE,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAEhE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM,GAAG,EAAE,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAEpC,MAAM,GAAG,GAAI,MAAc,EAAE,GAAG,CAAC;IAEjC,UAAU;IACV,MAAM,OAAO,GAAG;QACd,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO;QACrB,KAAK,EAAE,OAAO,GAAG,EAAE,OAAO,KAAK,QAAQ,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;QAClF,KAAK,EAAE,GAAG,EAAE,OAAO,IAAI,IAAI;QAC3B,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;KACrG,CAAC;IAEF,WAAW;IACX,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAEhD,eAAe;IACf,MAAM,YAAY,GAAG,mBAAmB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAE5D,YAAY;IACZ,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE1D,eAAe;IACf,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAE1D,OAAO;QACL,SAAS,EAAE,MAAM,KAAK,CAAC;QACvB,OAAO;QACP,QAAQ;QACR,YAAY;QACZ,SAAS;QACT,WAAW;QACX,KAAK;QACL,KAAK;QACL,aAAa,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;KAC1C,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAc;IACvC,OAAO;QACL,SAAS,EAAE,KAAK;QAChB,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QAClE,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE;QAC7F,YAAY,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;QAClF,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QAC1E,WAAW,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;QACrD,KAAK,EAAE,CAAC;QACR,KAAK,EAAE,GAAG;QACV,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;KACnD,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,GAAG,CAAC;IAC5B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,GAAG,CAAC;IAC5B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,GAAG,CAAC;IAC5B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,GAAG,CAAC;IAC5B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,SAAS,eAAe,CAAC,QAAiB;IACxC,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC9C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC;IAC5G,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,QAAmC,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,IAAI,cAAc,GAAG,KAAK,CAAC;IAE3B,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,UAAU,EAAE,CAAC;QACrC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG;YAAE,SAAS;QAC9C,MAAM,CAAC,GAAG,GAA8B,CAAC;QACzC,IAAI,CAAC,CAAC,IAAI;YAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,CAAC,GAAG;YAAE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,CAAC,GAAG;YAAE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,CAAC,QAAQ;YAAE,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAE3C,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACnF,cAAc,GAAG,IAAI,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,UAAU,CAAC,MAAM;QACxB,cAAc;QACd,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;QAClC,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,YAAqB;IAChD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,yBAAyB,CAAC,EAAE,CAAC;IACvG,CAAC;IAED,MAAM,KAAK,GAAG,YAAY;SACvB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC;SACzC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAC5B,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAC3F,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,YAAY,CAAC,MAAM;QAC1B,IAAI,EAAE,KAAK;QACX,WAAW;QACX,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAiB,EAAE,MAAyB;IACpE,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC7C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,QAAmC,CAAC,EAAE,CAAC;YACrE,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;gBAAE,SAAS;YAC9C,MAAM,CAAC,GAAG,GAA8B,CAAC;YAEzC,wCAAwC;YACxC,KAAK,MAAM,SAAS,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAU,EAAE,CAAC;gBACpE,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAwC,CAAC;gBAC9D,IAAI,CAAC,EAAE,QAAQ,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBAClD,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IACrE,MAAM,eAAe,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAEpE,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,wBAAwB,CAAC,CAAC;IAC7E,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,6BAA6B,CAAC,CAAC;IACnF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,cAAc,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,MAAM,8BAA8B,CAAC,CAAC;IACnG,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QAAE,cAAc,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,MAAM,kCAAkC,CAAC,CAAC;IAEzG,OAAO;QACL,KAAK,EAAE,YAAY,CAAC,MAAM;QAC1B,QAAQ;QACR,eAAe;QACf,MAAM,EAAE,cAAc;KACvB,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,WAAoB;IAC9C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,yBAAyB,CAAC,EAAE,CAAC;IAC3E,CAAC;IAED,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACpC,SAAS,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YAC5C,SAAS;QACX,CAAC;QACD,MAAM,CAAC,GAAG,GAA8B,CAAC;QACzC,IAAI,CAAC,CAAC,CAAC,SAAS;YAAE,SAAS,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QAClE,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,UAAU;YAAE,SAAS,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IACtF,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,WAAW,CAAC,MAAM;QACzB,MAAM,EAAE,SAAS;KAClB,CAAC;AACJ,CAAC"}
|