@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
@@ -1,531 +0,0 @@
1
- /**
2
- * Tests for SDK-based Validator
3
- * Tests validation using the official @ucp-js/sdk Zod schemas
4
- */
5
-
6
- import { describe, it, expect } from 'vitest';
7
- import { readFileSync } from 'fs';
8
- import { join } from 'path';
9
- import {
10
- validateWithSdk,
11
- safeValidateWithSdk,
12
- validateUcpObject,
13
- validateServiceWithSdk,
14
- validateCapabilityWithSdk,
15
- validateSigningKeysWithSdk,
16
- isSdkCompliant,
17
- getSdkVersion,
18
- } from '../../src/validator/sdk-validator.js';
19
-
20
- // Load test fixtures
21
- const fixturesDir = join(process.cwd(), 'tests', 'fixtures');
22
- const officialSampleProfile = JSON.parse(
23
- readFileSync(join(fixturesDir, 'official-sample-profile.json'), 'utf-8')
24
- );
25
- const nonCompliantProfile = JSON.parse(
26
- readFileSync(join(fixturesDir, 'non-compliant-profile.json'), 'utf-8')
27
- );
28
-
29
- describe('SDK Validator', () => {
30
- describe('getSdkVersion', () => {
31
- it('should return the SDK version', () => {
32
- const version = getSdkVersion();
33
- expect(version).toBe('0.1.0');
34
- });
35
- });
36
-
37
- describe('isSdkCompliant', () => {
38
- it('should return true for official sample profile', () => {
39
- expect(isSdkCompliant(officialSampleProfile)).toBe(true);
40
- });
41
-
42
- it('should return false for non-compliant profile', () => {
43
- expect(isSdkCompliant(nonCompliantProfile)).toBe(false);
44
- });
45
-
46
- it('should return false for empty object', () => {
47
- expect(isSdkCompliant({})).toBe(false);
48
- });
49
-
50
- it('should return false for null', () => {
51
- expect(isSdkCompliant(null)).toBe(false);
52
- });
53
- });
54
-
55
- describe('validateWithSdk', () => {
56
- it('should validate official sample profile successfully', () => {
57
- const result = validateWithSdk(officialSampleProfile);
58
-
59
- expect(result.valid).toBe(true);
60
- expect(result.issues).toHaveLength(0);
61
- expect(result.sdkVersion).toBe('0.1.0');
62
- expect(result.parsedProfile).toBeDefined();
63
- });
64
-
65
- it('should return issues for non-compliant profile', () => {
66
- const result = validateWithSdk(nonCompliantProfile);
67
-
68
- expect(result.valid).toBe(false);
69
- expect(result.issues.length).toBeGreaterThan(0);
70
- expect(result.sdkVersion).toBe('0.1.0');
71
- });
72
-
73
- it('should validate profile with all optional fields', () => {
74
- const fullProfile = {
75
- ucp: {
76
- version: '2026-01-15',
77
- services: {
78
- 'dev.ucp.shopping': {
79
- version: '2026-01-15',
80
- spec: 'https://ucp.dev/specs/shopping',
81
- rest: {
82
- endpoint: 'https://example.com/api',
83
- schema: 'https://ucp.dev/schemas/shopping.json',
84
- },
85
- },
86
- },
87
- capabilities: [
88
- {
89
- name: 'dev.ucp.shopping.checkout',
90
- version: '2026-01-15',
91
- spec: 'https://ucp.dev/specs/shopping/checkout',
92
- schema: 'https://ucp.dev/schemas/shopping/checkout.json',
93
- },
94
- ],
95
- },
96
- signing_keys: [
97
- {
98
- kty: 'EC',
99
- kid: 'key-1',
100
- crv: 'P-256',
101
- x: 'test-x',
102
- y: 'test-y',
103
- use: 'sig',
104
- },
105
- ],
106
- };
107
-
108
- const result = validateWithSdk(fullProfile);
109
- expect(result.valid).toBe(true);
110
- });
111
- });
112
-
113
- describe('safeValidateWithSdk', () => {
114
- it('should not throw for invalid input', () => {
115
- expect(() => safeValidateWithSdk(null)).not.toThrow();
116
- expect(() => safeValidateWithSdk(undefined)).not.toThrow();
117
- expect(() => safeValidateWithSdk('string')).not.toThrow();
118
- expect(() => safeValidateWithSdk(123)).not.toThrow();
119
- });
120
-
121
- it('should return valid: false for invalid profiles', () => {
122
- const result = safeValidateWithSdk({ invalid: true });
123
- expect(result.valid).toBe(false);
124
- expect(result.issues.length).toBeGreaterThan(0);
125
- });
126
- });
127
-
128
- describe('validateUcpObject', () => {
129
- it('should validate ucp object from official sample', () => {
130
- const result = validateUcpObject(officialSampleProfile.ucp);
131
- expect(result.valid).toBe(true);
132
- expect(result.issues).toHaveLength(0);
133
- });
134
-
135
- it('should fail for ucp object from non-compliant profile', () => {
136
- const result = validateUcpObject(nonCompliantProfile.ucp);
137
- expect(result.valid).toBe(false);
138
- expect(result.issues.length).toBeGreaterThan(0);
139
- });
140
-
141
- it('should validate minimal ucp object', () => {
142
- const minimalUcp = {
143
- version: '2026-01-15',
144
- services: {
145
- 'dev.ucp.shopping': {
146
- version: '2026-01-15',
147
- spec: 'https://ucp.dev/specs/shopping',
148
- rest: {
149
- endpoint: 'https://example.com/api',
150
- schema: 'https://ucp.dev/schemas/shopping.json',
151
- },
152
- },
153
- },
154
- capabilities: [
155
- {
156
- name: 'dev.ucp.shopping.checkout',
157
- version: '2026-01-15',
158
- spec: 'https://ucp.dev/specs/checkout',
159
- schema: 'https://ucp.dev/schemas/checkout.json',
160
- },
161
- ],
162
- };
163
-
164
- const result = validateUcpObject(minimalUcp);
165
- expect(result.valid).toBe(true);
166
- });
167
- });
168
-
169
- describe('validateServiceWithSdk', () => {
170
- it('should validate a properly structured service', () => {
171
- const service = {
172
- version: '2026-01-15',
173
- spec: 'https://ucp.dev/specs/shopping',
174
- rest: {
175
- endpoint: 'https://example.com/api',
176
- schema: 'https://ucp.dev/schemas/shopping.json',
177
- },
178
- };
179
-
180
- const result = validateServiceWithSdk('dev.ucp.shopping', service);
181
- expect(result.valid).toBe(true);
182
- });
183
-
184
- it('should fail for service missing version', () => {
185
- const service = {
186
- spec: 'https://ucp.dev/specs/shopping',
187
- rest: {
188
- endpoint: 'https://example.com/api',
189
- schema: 'https://ucp.dev/schemas/shopping.json',
190
- },
191
- };
192
-
193
- const result = validateServiceWithSdk('dev.ucp.shopping', service);
194
- expect(result.valid).toBe(false);
195
- expect(result.issues.some(i => i.path.includes('version'))).toBe(true);
196
- });
197
-
198
- it('should fail for service missing spec', () => {
199
- const service = {
200
- version: '2026-01-15',
201
- rest: {
202
- endpoint: 'https://example.com/api',
203
- schema: 'https://ucp.dev/schemas/shopping.json',
204
- },
205
- };
206
-
207
- const result = validateServiceWithSdk('dev.ucp.shopping', service);
208
- expect(result.valid).toBe(false);
209
- expect(result.issues.some(i => i.path.includes('spec'))).toBe(true);
210
- });
211
-
212
- it('should validate service with MCP transport', () => {
213
- const service = {
214
- version: '2026-01-15',
215
- spec: 'https://ucp.dev/specs/shopping',
216
- mcp: {
217
- endpoint: 'https://example.com/mcp',
218
- schema: 'https://ucp.dev/schemas/shopping.json',
219
- },
220
- };
221
-
222
- const result = validateServiceWithSdk('dev.ucp.shopping', service);
223
- expect(result.valid).toBe(true);
224
- });
225
-
226
- it('should validate service with A2A transport', () => {
227
- const service = {
228
- version: '2026-01-15',
229
- spec: 'https://ucp.dev/specs/shopping',
230
- a2a: {
231
- endpoint: 'https://example.com/a2a',
232
- },
233
- };
234
-
235
- const result = validateServiceWithSdk('dev.ucp.shopping', service);
236
- expect(result.valid).toBe(true);
237
- });
238
- });
239
-
240
- describe('validateCapabilityWithSdk', () => {
241
- it('should validate a properly structured capability', () => {
242
- const capability = {
243
- name: 'dev.ucp.shopping.checkout',
244
- version: '2026-01-15',
245
- spec: 'https://ucp.dev/specs/checkout',
246
- schema: 'https://ucp.dev/schemas/checkout.json',
247
- };
248
-
249
- const result = validateCapabilityWithSdk(0, capability);
250
- expect(result.valid).toBe(true);
251
- });
252
-
253
- it('should fail for capability missing name', () => {
254
- const capability = {
255
- version: '2026-01-15',
256
- spec: 'https://ucp.dev/specs/checkout',
257
- schema: 'https://ucp.dev/schemas/checkout.json',
258
- };
259
-
260
- const result = validateCapabilityWithSdk(0, capability);
261
- expect(result.valid).toBe(false);
262
- });
263
-
264
- it('should validate capability with extends field', () => {
265
- const capability = {
266
- name: 'dev.ucp.shopping.fulfillment',
267
- version: '2026-01-15',
268
- spec: 'https://ucp.dev/specs/fulfillment',
269
- schema: 'https://ucp.dev/schemas/fulfillment.json',
270
- extends: 'dev.ucp.shopping.order',
271
- };
272
-
273
- const result = validateCapabilityWithSdk(0, capability);
274
- expect(result.valid).toBe(true);
275
- });
276
-
277
- it('should validate capability with config field', () => {
278
- const capability = {
279
- name: 'dev.ucp.shopping.checkout',
280
- version: '2026-01-15',
281
- spec: 'https://ucp.dev/specs/checkout',
282
- schema: 'https://ucp.dev/schemas/checkout.json',
283
- config: {
284
- supported_currencies: ['USD', 'EUR'],
285
- max_items: 100,
286
- },
287
- };
288
-
289
- const result = validateCapabilityWithSdk(0, capability);
290
- expect(result.valid).toBe(true);
291
- });
292
- });
293
-
294
- describe('validateSigningKeysWithSdk', () => {
295
- it('should validate properly structured signing keys', () => {
296
- const signingKeys = [
297
- {
298
- kty: 'EC',
299
- kid: 'key-1',
300
- crv: 'P-256',
301
- x: 'test-x-coordinate',
302
- y: 'test-y-coordinate',
303
- use: 'sig',
304
- },
305
- ];
306
-
307
- const result = validateSigningKeysWithSdk(signingKeys);
308
- expect(result.valid).toBe(true);
309
- });
310
-
311
- it('should validate RSA signing keys', () => {
312
- const signingKeys = [
313
- {
314
- kty: 'RSA',
315
- kid: 'rsa-key-1',
316
- n: 'test-modulus',
317
- e: 'AQAB',
318
- use: 'sig',
319
- },
320
- ];
321
-
322
- const result = validateSigningKeysWithSdk(signingKeys);
323
- expect(result.valid).toBe(true);
324
- });
325
-
326
- it('should fail for signing keys missing kty', () => {
327
- const signingKeys = [
328
- {
329
- kid: 'key-1',
330
- crv: 'P-256',
331
- x: 'test-x',
332
- y: 'test-y',
333
- },
334
- ];
335
-
336
- const result = validateSigningKeysWithSdk(signingKeys);
337
- expect(result.valid).toBe(false);
338
- });
339
-
340
- it('should fail for signing keys missing kid', () => {
341
- const signingKeys = [
342
- {
343
- kty: 'EC',
344
- crv: 'P-256',
345
- x: 'test-x',
346
- y: 'test-y',
347
- },
348
- ];
349
-
350
- const result = validateSigningKeysWithSdk(signingKeys);
351
- expect(result.valid).toBe(false);
352
- });
353
-
354
- it('should validate empty signing keys array', () => {
355
- const result = validateSigningKeysWithSdk([]);
356
- expect(result.valid).toBe(true);
357
- });
358
-
359
- it('should fail for non-array signing keys', () => {
360
- const result = validateSigningKeysWithSdk({ keys: [] });
361
- expect(result.valid).toBe(false);
362
- });
363
- });
364
-
365
- describe('Error Path Mapping', () => {
366
- it('should correctly map nested paths', () => {
367
- const invalidProfile = {
368
- ucp: {
369
- version: '2026-01-15',
370
- services: {
371
- 'dev.ucp.shopping': {
372
- version: 123, // Should be string
373
- spec: 'https://ucp.dev/specs/shopping',
374
- rest: {
375
- endpoint: 'https://example.com/api',
376
- schema: 'https://ucp.dev/schemas/shopping.json',
377
- },
378
- },
379
- },
380
- capabilities: [
381
- {
382
- name: 'dev.ucp.shopping.checkout',
383
- version: '2026-01-15',
384
- spec: 'https://ucp.dev/specs/checkout',
385
- schema: 'https://ucp.dev/schemas/checkout.json',
386
- },
387
- ],
388
- },
389
- };
390
-
391
- const result = safeValidateWithSdk(invalidProfile);
392
- expect(result.valid).toBe(false);
393
- // Should have path like $.ucp.services.dev.ucp.shopping.version
394
- const versionIssue = result.issues.find(i => i.path.includes('version'));
395
- expect(versionIssue).toBeDefined();
396
- });
397
-
398
- it('should map array paths correctly', () => {
399
- const invalidProfile = {
400
- ucp: {
401
- version: '2026-01-15',
402
- services: {},
403
- capabilities: [
404
- null, // Invalid capability
405
- ],
406
- },
407
- };
408
-
409
- const result = safeValidateWithSdk(invalidProfile);
410
- expect(result.valid).toBe(false);
411
- // Should have path like $.ucp.capabilities[0]
412
- const capIssue = result.issues.find(i => i.path.includes('capabilities'));
413
- expect(capIssue).toBeDefined();
414
- });
415
- });
416
-
417
- describe('SDK Compliant Profile Variations', () => {
418
- it('should validate profile with multiple services', () => {
419
- const profile = {
420
- ucp: {
421
- version: '2026-01-15',
422
- services: {
423
- 'dev.ucp.shopping': {
424
- version: '2026-01-15',
425
- spec: 'https://ucp.dev/specs/shopping',
426
- rest: {
427
- endpoint: 'https://example.com/api/shopping',
428
- schema: 'https://ucp.dev/schemas/shopping.json',
429
- },
430
- },
431
- 'com.example.custom': {
432
- version: '2026-01-15',
433
- spec: 'https://example.com/specs/custom',
434
- rest: {
435
- endpoint: 'https://example.com/api/custom',
436
- schema: 'https://example.com/schemas/custom.json',
437
- },
438
- },
439
- },
440
- capabilities: [
441
- {
442
- name: 'dev.ucp.shopping.checkout',
443
- version: '2026-01-15',
444
- spec: 'https://ucp.dev/specs/checkout',
445
- schema: 'https://ucp.dev/schemas/checkout.json',
446
- },
447
- ],
448
- },
449
- };
450
-
451
- const result = validateWithSdk(profile);
452
- expect(result.valid).toBe(true);
453
- });
454
-
455
- it('should validate profile with multiple transports on same service', () => {
456
- const profile = {
457
- ucp: {
458
- version: '2026-01-15',
459
- services: {
460
- 'dev.ucp.shopping': {
461
- version: '2026-01-15',
462
- spec: 'https://ucp.dev/specs/shopping',
463
- rest: {
464
- endpoint: 'https://example.com/api',
465
- schema: 'https://ucp.dev/schemas/shopping.json',
466
- },
467
- mcp: {
468
- endpoint: 'https://example.com/mcp',
469
- schema: 'https://ucp.dev/schemas/shopping-mcp.json',
470
- },
471
- },
472
- },
473
- capabilities: [
474
- {
475
- name: 'dev.ucp.shopping.checkout',
476
- version: '2026-01-15',
477
- spec: 'https://ucp.dev/specs/checkout',
478
- schema: 'https://ucp.dev/schemas/checkout.json',
479
- },
480
- ],
481
- },
482
- };
483
-
484
- const result = validateWithSdk(profile);
485
- expect(result.valid).toBe(true);
486
- });
487
-
488
- it('should validate profile with capability extension chain', () => {
489
- const profile = {
490
- ucp: {
491
- version: '2026-01-15',
492
- services: {
493
- 'dev.ucp.shopping': {
494
- version: '2026-01-15',
495
- spec: 'https://ucp.dev/specs/shopping',
496
- rest: {
497
- endpoint: 'https://example.com/api',
498
- schema: 'https://ucp.dev/schemas/shopping.json',
499
- },
500
- },
501
- },
502
- capabilities: [
503
- {
504
- name: 'dev.ucp.shopping.checkout',
505
- version: '2026-01-15',
506
- spec: 'https://ucp.dev/specs/checkout',
507
- schema: 'https://ucp.dev/schemas/checkout.json',
508
- },
509
- {
510
- name: 'dev.ucp.shopping.order',
511
- version: '2026-01-15',
512
- spec: 'https://ucp.dev/specs/order',
513
- schema: 'https://ucp.dev/schemas/order.json',
514
- extends: 'dev.ucp.shopping.checkout',
515
- },
516
- {
517
- name: 'dev.ucp.shopping.fulfillment',
518
- version: '2026-01-15',
519
- spec: 'https://ucp.dev/specs/fulfillment',
520
- schema: 'https://ucp.dev/schemas/fulfillment.json',
521
- extends: 'dev.ucp.shopping.order',
522
- },
523
- ],
524
- },
525
- };
526
-
527
- const result = validateWithSdk(profile);
528
- expect(result.valid).toBe(true);
529
- });
530
- });
531
- });