@ucptools/validator 1.0.0 → 1.0.1

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 (236) hide show
  1. package/.claude/settings.local.json +60 -0
  2. package/.vercel/README.txt +11 -0
  3. package/.vercel/project.json +1 -0
  4. package/dist/cli/index.d.ts +6 -0
  5. package/dist/cli/index.d.ts.map +1 -0
  6. package/dist/cli/index.js +279 -0
  7. package/dist/cli/index.js.map +1 -0
  8. package/dist/compliance/compliance-generator.d.ts +34 -0
  9. package/dist/compliance/compliance-generator.d.ts.map +1 -0
  10. package/dist/compliance/compliance-generator.js +320 -0
  11. package/dist/compliance/compliance-generator.js.map +1 -0
  12. package/dist/compliance/index.d.ts +8 -0
  13. package/dist/compliance/index.d.ts.map +1 -0
  14. package/dist/compliance/index.js +17 -0
  15. package/dist/compliance/index.js.map +1 -0
  16. package/dist/compliance/templates.d.ts +34 -0
  17. package/dist/compliance/templates.d.ts.map +1 -0
  18. package/{src/compliance/templates.ts → dist/compliance/templates.js} +117 -155
  19. package/dist/compliance/templates.js.map +1 -0
  20. package/dist/compliance/types.d.ts +64 -0
  21. package/dist/compliance/types.d.ts.map +1 -0
  22. package/dist/compliance/types.js +64 -0
  23. package/dist/compliance/types.js.map +1 -0
  24. package/dist/db/index.d.ts +11 -0
  25. package/dist/db/index.d.ts.map +1 -0
  26. package/dist/db/index.js +63 -0
  27. package/dist/db/index.js.map +1 -0
  28. package/dist/db/schema.d.ts +444 -0
  29. package/dist/db/schema.d.ts.map +1 -0
  30. package/dist/db/schema.js +65 -0
  31. package/dist/db/schema.js.map +1 -0
  32. package/dist/feed-analyzer/feed-analyzer.d.ts +26 -0
  33. package/dist/feed-analyzer/feed-analyzer.d.ts.map +1 -0
  34. package/{src/feed-analyzer/feed-analyzer.ts → dist/feed-analyzer/feed-analyzer.js} +642 -726
  35. package/dist/feed-analyzer/feed-analyzer.js.map +1 -0
  36. package/dist/feed-analyzer/index.d.ts +8 -0
  37. package/dist/feed-analyzer/index.d.ts.map +1 -0
  38. package/dist/feed-analyzer/index.js +19 -0
  39. package/dist/feed-analyzer/index.js.map +1 -0
  40. package/dist/feed-analyzer/types.d.ts +204 -0
  41. package/dist/feed-analyzer/types.d.ts.map +1 -0
  42. package/dist/feed-analyzer/types.js +162 -0
  43. package/dist/feed-analyzer/types.js.map +1 -0
  44. package/{src/generator/index.ts → dist/generator/index.d.ts} +1 -1
  45. package/dist/generator/index.d.ts.map +1 -0
  46. package/dist/generator/index.js +13 -0
  47. package/dist/generator/index.js.map +1 -0
  48. package/dist/generator/key-generator.d.ts +24 -0
  49. package/dist/generator/key-generator.d.ts.map +1 -0
  50. package/dist/generator/key-generator.js +144 -0
  51. package/dist/generator/key-generator.js.map +1 -0
  52. package/dist/generator/profile-builder.d.ts +15 -0
  53. package/dist/generator/profile-builder.d.ts.map +1 -0
  54. package/dist/generator/profile-builder.js +338 -0
  55. package/dist/generator/profile-builder.js.map +1 -0
  56. package/dist/hosting/artifacts-generator.d.ts +10 -0
  57. package/dist/hosting/artifacts-generator.d.ts.map +1 -0
  58. package/{src/hosting/artifacts-generator.ts → dist/hosting/artifacts-generator.js} +191 -241
  59. package/dist/hosting/artifacts-generator.js.map +1 -0
  60. package/{src/hosting/index.ts → dist/hosting/index.d.ts} +1 -1
  61. package/dist/hosting/index.d.ts.map +1 -0
  62. package/dist/hosting/index.js +10 -0
  63. package/dist/hosting/index.js.map +1 -0
  64. package/dist/index.d.ts +18 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +78 -0
  67. package/dist/index.js.map +1 -0
  68. package/{src/security/index.ts → dist/security/index.d.ts} +8 -15
  69. package/dist/security/index.d.ts.map +1 -0
  70. package/dist/security/index.js +12 -0
  71. package/dist/security/index.js.map +1 -0
  72. package/dist/security/security-scanner.d.ts +10 -0
  73. package/dist/security/security-scanner.d.ts.map +1 -0
  74. package/dist/security/security-scanner.js +541 -0
  75. package/dist/security/security-scanner.js.map +1 -0
  76. package/dist/security/types.d.ts +48 -0
  77. package/dist/security/types.d.ts.map +1 -0
  78. package/dist/security/types.js +21 -0
  79. package/dist/security/types.js.map +1 -0
  80. package/dist/services/directory.d.ts +104 -0
  81. package/dist/services/directory.d.ts.map +1 -0
  82. package/dist/services/directory.js +333 -0
  83. package/dist/services/directory.js.map +1 -0
  84. package/dist/simulator/agent-simulator.d.ts +69 -0
  85. package/dist/simulator/agent-simulator.d.ts.map +1 -0
  86. package/{src/simulator/agent-simulator.ts → dist/simulator/agent-simulator.js} +650 -941
  87. package/dist/simulator/agent-simulator.js.map +1 -0
  88. package/{src/simulator/index.ts → dist/simulator/index.d.ts} +7 -7
  89. package/dist/simulator/index.d.ts.map +1 -0
  90. package/dist/simulator/index.js +23 -0
  91. package/dist/simulator/index.js.map +1 -0
  92. package/{src/simulator/types.ts → dist/simulator/types.d.ts} +145 -170
  93. package/dist/simulator/types.d.ts.map +1 -0
  94. package/dist/simulator/types.js +18 -0
  95. package/dist/simulator/types.js.map +1 -0
  96. package/dist/types/generator.d.ts +106 -0
  97. package/dist/types/generator.d.ts.map +1 -0
  98. package/dist/types/generator.js +6 -0
  99. package/dist/types/generator.js.map +1 -0
  100. package/{src/types/index.ts → dist/types/index.d.ts} +1 -1
  101. package/dist/types/index.d.ts.map +1 -0
  102. package/dist/types/index.js +23 -0
  103. package/dist/types/index.js.map +1 -0
  104. package/dist/types/ucp-profile.d.ts +103 -0
  105. package/dist/types/ucp-profile.d.ts.map +1 -0
  106. package/dist/types/ucp-profile.js +45 -0
  107. package/dist/types/ucp-profile.js.map +1 -0
  108. package/dist/types/validation.d.ts +68 -0
  109. package/dist/types/validation.d.ts.map +1 -0
  110. package/dist/types/validation.js +32 -0
  111. package/dist/types/validation.js.map +1 -0
  112. package/dist/validator/index.d.ts +26 -0
  113. package/dist/validator/index.d.ts.map +1 -0
  114. package/dist/validator/index.js +161 -0
  115. package/dist/validator/index.js.map +1 -0
  116. package/dist/validator/network-validator.d.ts +28 -0
  117. package/dist/validator/network-validator.d.ts.map +1 -0
  118. package/dist/validator/network-validator.js +319 -0
  119. package/dist/validator/network-validator.js.map +1 -0
  120. package/dist/validator/rules-validator.d.ts +11 -0
  121. package/dist/validator/rules-validator.d.ts.map +1 -0
  122. package/dist/validator/rules-validator.js +257 -0
  123. package/dist/validator/rules-validator.js.map +1 -0
  124. package/dist/validator/sdk-validator.d.ts +58 -0
  125. package/dist/validator/sdk-validator.d.ts.map +1 -0
  126. package/{src/validator/sdk-validator.ts → dist/validator/sdk-validator.js} +273 -330
  127. package/dist/validator/sdk-validator.js.map +1 -0
  128. package/dist/validator/structural-validator.d.ts +11 -0
  129. package/dist/validator/structural-validator.d.ts.map +1 -0
  130. package/dist/validator/structural-validator.js +415 -0
  131. package/dist/validator/structural-validator.js.map +1 -0
  132. package/package.json +1 -1
  133. package/publish-output.txt +0 -0
  134. package/CLAUDE.md +0 -109
  135. package/api/analyze-feed.js +0 -140
  136. package/api/badge.js +0 -185
  137. package/api/benchmark.js +0 -177
  138. package/api/directory-stats.ts +0 -29
  139. package/api/directory.ts +0 -73
  140. package/api/generate-compliance.js +0 -143
  141. package/api/generate-schema.js +0 -457
  142. package/api/generate.js +0 -132
  143. package/api/security-scan.js +0 -133
  144. package/api/simulate.js +0 -187
  145. package/api/tsconfig.json +0 -10
  146. package/api/validate.js +0 -1351
  147. package/apify-actor/.actor/actor.json +0 -68
  148. package/apify-actor/.actor/input_schema.json +0 -32
  149. package/apify-actor/APIFY-STORE-LISTING.md +0 -412
  150. package/apify-actor/Dockerfile +0 -8
  151. package/apify-actor/README.md +0 -166
  152. package/apify-actor/main.ts +0 -111
  153. package/apify-actor/package.json +0 -17
  154. package/apify-actor/src/main.js +0 -199
  155. package/docs/BRAND-IDENTITY.md +0 -238
  156. package/docs/BRAND-STYLE-GUIDE.md +0 -356
  157. package/drizzle/0000_black_king_cobra.sql +0 -39
  158. package/drizzle/meta/0000_snapshot.json +0 -309
  159. package/drizzle/meta/_journal.json +0 -13
  160. package/drizzle.config.ts +0 -10
  161. package/public/.well-known/ucp +0 -25
  162. package/public/android-chrome-192x192.png +0 -0
  163. package/public/android-chrome-512x512.png +0 -0
  164. package/public/apple-touch-icon.png +0 -0
  165. package/public/brand.css +0 -321
  166. package/public/directory.html +0 -701
  167. package/public/favicon-16x16.png +0 -0
  168. package/public/favicon-32x32.png +0 -0
  169. package/public/favicon.ico +0 -0
  170. package/public/guides/bigcommerce.html +0 -743
  171. package/public/guides/fastucp.html +0 -838
  172. package/public/guides/magento.html +0 -779
  173. package/public/guides/shopify.html +0 -726
  174. package/public/guides/squarespace.html +0 -749
  175. package/public/guides/wix.html +0 -747
  176. package/public/guides/woocommerce.html +0 -733
  177. package/public/index.html +0 -3835
  178. package/public/learn.html +0 -396
  179. package/public/logo.jpeg +0 -0
  180. package/public/og-image-icon.png +0 -0
  181. package/public/og-image.png +0 -0
  182. package/public/robots.txt +0 -6
  183. package/public/site.webmanifest +0 -31
  184. package/public/sitemap.xml +0 -69
  185. package/public/social/linkedin-banner-1128x191.png +0 -0
  186. package/public/social/temp.PNG +0 -0
  187. package/public/social/x-header-1500x500.png +0 -0
  188. package/public/verify.html +0 -410
  189. package/scripts/generate-favicons.js +0 -44
  190. package/scripts/generate-ico.js +0 -23
  191. package/scripts/generate-og-image.js +0 -45
  192. package/scripts/reset-db.ts +0 -77
  193. package/scripts/seed-db.ts +0 -71
  194. package/scripts/setup-benchmark-db.js +0 -70
  195. package/src/api/server.ts +0 -266
  196. package/src/cli/index.ts +0 -302
  197. package/src/compliance/compliance-generator.ts +0 -452
  198. package/src/compliance/index.ts +0 -28
  199. package/src/compliance/types.ts +0 -170
  200. package/src/db/index.ts +0 -28
  201. package/src/db/schema.ts +0 -84
  202. package/src/feed-analyzer/index.ts +0 -34
  203. package/src/feed-analyzer/types.ts +0 -354
  204. package/src/generator/key-generator.ts +0 -124
  205. package/src/generator/profile-builder.ts +0 -402
  206. package/src/index.ts +0 -105
  207. package/src/security/security-scanner.ts +0 -604
  208. package/src/security/types.ts +0 -55
  209. package/src/services/directory.ts +0 -434
  210. package/src/types/generator.ts +0 -140
  211. package/src/types/ucp-profile.ts +0 -140
  212. package/src/types/validation.ts +0 -89
  213. package/src/validator/index.ts +0 -194
  214. package/src/validator/network-validator.ts +0 -417
  215. package/src/validator/rules-validator.ts +0 -297
  216. package/src/validator/structural-validator.ts +0 -476
  217. package/tests/fixtures/non-compliant-profile.json +0 -25
  218. package/tests/fixtures/official-sample-profile.json +0 -75
  219. package/tests/integration/benchmark.test.ts +0 -207
  220. package/tests/integration/database.test.ts +0 -163
  221. package/tests/integration/directory-api.test.ts +0 -268
  222. package/tests/integration/simulate-api.test.ts +0 -230
  223. package/tests/integration/validate-api.test.ts +0 -269
  224. package/tests/setup.ts +0 -15
  225. package/tests/unit/agent-simulator.test.ts +0 -575
  226. package/tests/unit/compliance-generator.test.ts +0 -374
  227. package/tests/unit/directory-service.test.ts +0 -272
  228. package/tests/unit/feed-analyzer.test.ts +0 -517
  229. package/tests/unit/lint-suggestions.test.ts +0 -423
  230. package/tests/unit/official-samples.test.ts +0 -211
  231. package/tests/unit/pdf-report.test.ts +0 -390
  232. package/tests/unit/sdk-validator.test.ts +0 -531
  233. package/tests/unit/security-scanner.test.ts +0 -410
  234. package/tests/unit/validation.test.ts +0 -390
  235. package/vercel.json +0 -34
  236. package/vitest.config.ts +0 -22
@@ -0,0 +1,415 @@
1
+ "use strict";
2
+ /**
3
+ * Structural Validator
4
+ * Validates UCP Profile JSON structure (no network calls)
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.validateStructure = validateStructure;
8
+ const validation_js_1 = require("../types/validation.js");
9
+ /**
10
+ * Version format regex (YYYY-MM-DD)
11
+ */
12
+ const VERSION_REGEX = /^\d{4}-\d{2}-\d{2}$/;
13
+ /**
14
+ * Validate the structural integrity of a UCP profile
15
+ * Returns an array of validation issues
16
+ */
17
+ function validateStructure(profile) {
18
+ const issues = [];
19
+ // Check if it's an object
20
+ if (!profile || typeof profile !== 'object') {
21
+ issues.push({
22
+ severity: 'error',
23
+ code: validation_js_1.ValidationErrorCodes.MISSING_UCP_OBJECT,
24
+ path: '$',
25
+ message: 'Profile must be a JSON object',
26
+ hint: 'Ensure your profile is valid JSON and contains a root object',
27
+ });
28
+ return issues;
29
+ }
30
+ const profileObj = profile;
31
+ // Check for ucp root object
32
+ if (!profileObj.ucp || typeof profileObj.ucp !== 'object') {
33
+ issues.push({
34
+ severity: 'error',
35
+ code: validation_js_1.ValidationErrorCodes.MISSING_UCP_OBJECT,
36
+ path: '$.ucp',
37
+ message: 'Missing required "ucp" object at root level',
38
+ hint: 'Add a "ucp" object containing version, services, and capabilities',
39
+ });
40
+ return issues;
41
+ }
42
+ const ucp = profileObj.ucp;
43
+ // Validate version
44
+ issues.push(...validateVersion(ucp));
45
+ // Validate services
46
+ issues.push(...validateServices(ucp));
47
+ // Validate capabilities
48
+ issues.push(...validateCapabilities(ucp));
49
+ // Validate signing_keys if present
50
+ if (profileObj.signing_keys !== undefined) {
51
+ issues.push(...validateSigningKeys(profileObj.signing_keys));
52
+ }
53
+ return issues;
54
+ }
55
+ /**
56
+ * Validate UCP version field
57
+ */
58
+ function validateVersion(ucp) {
59
+ const issues = [];
60
+ if (!ucp.version) {
61
+ issues.push({
62
+ severity: 'error',
63
+ code: validation_js_1.ValidationErrorCodes.MISSING_VERSION,
64
+ path: '$.ucp.version',
65
+ message: 'Missing required "version" field in ucp object',
66
+ hint: 'Add version field with format "YYYY-MM-DD" (e.g., "2026-01-11")',
67
+ });
68
+ }
69
+ else if (typeof ucp.version !== 'string') {
70
+ issues.push({
71
+ severity: 'error',
72
+ code: validation_js_1.ValidationErrorCodes.INVALID_VERSION_FORMAT,
73
+ path: '$.ucp.version',
74
+ message: 'Version must be a string',
75
+ hint: 'Use format "YYYY-MM-DD" (e.g., "2026-01-11")',
76
+ });
77
+ }
78
+ else if (!VERSION_REGEX.test(ucp.version)) {
79
+ issues.push({
80
+ severity: 'error',
81
+ code: validation_js_1.ValidationErrorCodes.INVALID_VERSION_FORMAT,
82
+ path: '$.ucp.version',
83
+ message: `Invalid version format: "${ucp.version}"`,
84
+ hint: 'Use format "YYYY-MM-DD" (e.g., "2026-01-11")',
85
+ });
86
+ }
87
+ return issues;
88
+ }
89
+ /**
90
+ * Validate services object
91
+ */
92
+ function validateServices(ucp) {
93
+ const issues = [];
94
+ if (!ucp.services) {
95
+ issues.push({
96
+ severity: 'error',
97
+ code: validation_js_1.ValidationErrorCodes.MISSING_SERVICES,
98
+ path: '$.ucp.services',
99
+ message: 'Missing required "services" field in ucp object',
100
+ hint: 'Add a services object with at least one service definition',
101
+ });
102
+ return issues;
103
+ }
104
+ if (typeof ucp.services !== 'object' || Array.isArray(ucp.services)) {
105
+ issues.push({
106
+ severity: 'error',
107
+ code: validation_js_1.ValidationErrorCodes.INVALID_SERVICE_STRUCTURE,
108
+ path: '$.ucp.services',
109
+ message: 'Services must be an object (not an array)',
110
+ hint: 'Use format: { "dev.ucp.shopping": { ... } }',
111
+ });
112
+ return issues;
113
+ }
114
+ const services = ucp.services;
115
+ // Check for at least one service
116
+ if (Object.keys(services).length === 0) {
117
+ issues.push({
118
+ severity: 'warn',
119
+ code: validation_js_1.ValidationErrorCodes.MISSING_SERVICES,
120
+ path: '$.ucp.services',
121
+ message: 'Services object is empty',
122
+ hint: 'Add at least one service (e.g., "dev.ucp.shopping")',
123
+ });
124
+ }
125
+ // Validate each service
126
+ for (const [serviceName, service] of Object.entries(services)) {
127
+ issues.push(...validateService(serviceName, service));
128
+ }
129
+ return issues;
130
+ }
131
+ /**
132
+ * Validate individual service definition
133
+ */
134
+ function validateService(name, service) {
135
+ const issues = [];
136
+ const path = `$.ucp.services["${name}"]`;
137
+ if (!service || typeof service !== 'object') {
138
+ issues.push({
139
+ severity: 'error',
140
+ code: validation_js_1.ValidationErrorCodes.INVALID_SERVICE_STRUCTURE,
141
+ path,
142
+ message: `Service "${name}" must be an object`,
143
+ });
144
+ return issues;
145
+ }
146
+ const svc = service;
147
+ // Check required version
148
+ if (!svc.version) {
149
+ issues.push({
150
+ severity: 'error',
151
+ code: validation_js_1.ValidationErrorCodes.INVALID_SERVICE_STRUCTURE,
152
+ path: `${path}.version`,
153
+ message: `Service "${name}" missing required "version" field`,
154
+ });
155
+ }
156
+ else if (typeof svc.version === 'string' && !VERSION_REGEX.test(svc.version)) {
157
+ issues.push({
158
+ severity: 'error',
159
+ code: validation_js_1.ValidationErrorCodes.INVALID_VERSION_FORMAT,
160
+ path: `${path}.version`,
161
+ message: `Invalid version format in service "${name}"`,
162
+ hint: 'Use format "YYYY-MM-DD"',
163
+ });
164
+ }
165
+ // Check required spec
166
+ if (!svc.spec) {
167
+ issues.push({
168
+ severity: 'error',
169
+ code: validation_js_1.ValidationErrorCodes.INVALID_SERVICE_STRUCTURE,
170
+ path: `${path}.spec`,
171
+ message: `Service "${name}" missing required "spec" field`,
172
+ });
173
+ }
174
+ // Check for at least one transport
175
+ const hasTransport = svc.rest || svc.mcp || svc.a2a || svc.embedded;
176
+ if (!hasTransport) {
177
+ issues.push({
178
+ severity: 'warn',
179
+ code: validation_js_1.ValidationErrorCodes.INVALID_SERVICE_STRUCTURE,
180
+ path,
181
+ message: `Service "${name}" has no transport bindings`,
182
+ hint: 'Add at least one transport: rest, mcp, a2a, or embedded',
183
+ });
184
+ }
185
+ // Validate REST transport if present
186
+ if (svc.rest) {
187
+ issues.push(...validateRestTransport(svc.rest, `${path}.rest`));
188
+ }
189
+ // Validate MCP transport if present
190
+ if (svc.mcp) {
191
+ issues.push(...validateMcpTransport(svc.mcp, `${path}.mcp`));
192
+ }
193
+ return issues;
194
+ }
195
+ /**
196
+ * Validate REST transport binding
197
+ */
198
+ function validateRestTransport(transport, path) {
199
+ const issues = [];
200
+ if (!transport || typeof transport !== 'object') {
201
+ issues.push({
202
+ severity: 'error',
203
+ code: validation_js_1.ValidationErrorCodes.INVALID_SERVICE_STRUCTURE,
204
+ path,
205
+ message: 'REST transport must be an object',
206
+ });
207
+ return issues;
208
+ }
209
+ const rest = transport;
210
+ if (!rest.schema) {
211
+ issues.push({
212
+ severity: 'error',
213
+ code: validation_js_1.ValidationErrorCodes.INVALID_SERVICE_STRUCTURE,
214
+ path: `${path}.schema`,
215
+ message: 'REST transport missing required "schema" field',
216
+ });
217
+ }
218
+ if (!rest.endpoint) {
219
+ issues.push({
220
+ severity: 'error',
221
+ code: validation_js_1.ValidationErrorCodes.INVALID_SERVICE_STRUCTURE,
222
+ path: `${path}.endpoint`,
223
+ message: 'REST transport missing required "endpoint" field',
224
+ });
225
+ }
226
+ return issues;
227
+ }
228
+ /**
229
+ * Validate MCP transport binding
230
+ */
231
+ function validateMcpTransport(transport, path) {
232
+ const issues = [];
233
+ if (!transport || typeof transport !== 'object') {
234
+ issues.push({
235
+ severity: 'error',
236
+ code: validation_js_1.ValidationErrorCodes.INVALID_SERVICE_STRUCTURE,
237
+ path,
238
+ message: 'MCP transport must be an object',
239
+ });
240
+ return issues;
241
+ }
242
+ const mcp = transport;
243
+ if (!mcp.schema) {
244
+ issues.push({
245
+ severity: 'error',
246
+ code: validation_js_1.ValidationErrorCodes.INVALID_SERVICE_STRUCTURE,
247
+ path: `${path}.schema`,
248
+ message: 'MCP transport missing required "schema" field',
249
+ });
250
+ }
251
+ if (!mcp.endpoint) {
252
+ issues.push({
253
+ severity: 'error',
254
+ code: validation_js_1.ValidationErrorCodes.INVALID_SERVICE_STRUCTURE,
255
+ path: `${path}.endpoint`,
256
+ message: 'MCP transport missing required "endpoint" field',
257
+ });
258
+ }
259
+ return issues;
260
+ }
261
+ /**
262
+ * Validate capabilities array
263
+ */
264
+ function validateCapabilities(ucp) {
265
+ const issues = [];
266
+ if (!ucp.capabilities) {
267
+ issues.push({
268
+ severity: 'error',
269
+ code: validation_js_1.ValidationErrorCodes.MISSING_CAPABILITIES,
270
+ path: '$.ucp.capabilities',
271
+ message: 'Missing required "capabilities" field in ucp object',
272
+ hint: 'Add a capabilities array with at least one capability',
273
+ });
274
+ return issues;
275
+ }
276
+ if (!Array.isArray(ucp.capabilities)) {
277
+ issues.push({
278
+ severity: 'error',
279
+ code: validation_js_1.ValidationErrorCodes.INVALID_CAPABILITY_STRUCTURE,
280
+ path: '$.ucp.capabilities',
281
+ message: 'Capabilities must be an array',
282
+ });
283
+ return issues;
284
+ }
285
+ if (ucp.capabilities.length === 0) {
286
+ issues.push({
287
+ severity: 'warn',
288
+ code: validation_js_1.ValidationErrorCodes.MISSING_CAPABILITIES,
289
+ path: '$.ucp.capabilities',
290
+ message: 'Capabilities array is empty',
291
+ hint: 'Add at least one capability (e.g., dev.ucp.shopping.checkout)',
292
+ });
293
+ }
294
+ // Validate each capability
295
+ for (let i = 0; i < ucp.capabilities.length; i++) {
296
+ issues.push(...validateCapability(ucp.capabilities[i], i));
297
+ }
298
+ return issues;
299
+ }
300
+ /**
301
+ * Validate individual capability
302
+ */
303
+ function validateCapability(capability, index) {
304
+ const issues = [];
305
+ const path = `$.ucp.capabilities[${index}]`;
306
+ if (!capability || typeof capability !== 'object') {
307
+ issues.push({
308
+ severity: 'error',
309
+ code: validation_js_1.ValidationErrorCodes.INVALID_CAPABILITY_STRUCTURE,
310
+ path,
311
+ message: `Capability at index ${index} must be an object`,
312
+ });
313
+ return issues;
314
+ }
315
+ const cap = capability;
316
+ // Check required fields
317
+ if (!cap.name) {
318
+ issues.push({
319
+ severity: 'error',
320
+ code: validation_js_1.ValidationErrorCodes.INVALID_CAPABILITY_STRUCTURE,
321
+ path: `${path}.name`,
322
+ message: 'Capability missing required "name" field',
323
+ });
324
+ }
325
+ if (!cap.version) {
326
+ issues.push({
327
+ severity: 'error',
328
+ code: validation_js_1.ValidationErrorCodes.INVALID_CAPABILITY_STRUCTURE,
329
+ path: `${path}.version`,
330
+ message: 'Capability missing required "version" field',
331
+ });
332
+ }
333
+ else if (typeof cap.version === 'string' && !VERSION_REGEX.test(cap.version)) {
334
+ issues.push({
335
+ severity: 'error',
336
+ code: validation_js_1.ValidationErrorCodes.INVALID_VERSION_FORMAT,
337
+ path: `${path}.version`,
338
+ message: `Invalid version format: "${cap.version}"`,
339
+ hint: 'Use format "YYYY-MM-DD"',
340
+ });
341
+ }
342
+ if (!cap.spec) {
343
+ issues.push({
344
+ severity: 'error',
345
+ code: validation_js_1.ValidationErrorCodes.INVALID_CAPABILITY_STRUCTURE,
346
+ path: `${path}.spec`,
347
+ message: 'Capability missing required "spec" field',
348
+ });
349
+ }
350
+ if (!cap.schema) {
351
+ issues.push({
352
+ severity: 'error',
353
+ code: validation_js_1.ValidationErrorCodes.INVALID_CAPABILITY_STRUCTURE,
354
+ path: `${path}.schema`,
355
+ message: 'Capability missing required "schema" field',
356
+ });
357
+ }
358
+ return issues;
359
+ }
360
+ /**
361
+ * Validate signing_keys structure
362
+ * Accepts signing_keys as a direct array of JWKs (official UCP format)
363
+ */
364
+ function validateSigningKeys(signingKeys) {
365
+ const issues = [];
366
+ const path = '$.signing_keys';
367
+ // signing_keys should be an array of JWKs
368
+ if (!Array.isArray(signingKeys)) {
369
+ issues.push({
370
+ severity: 'error',
371
+ code: validation_js_1.ValidationErrorCodes.INVALID_SIGNING_KEY,
372
+ path,
373
+ message: 'signing_keys must be an array of JWK objects',
374
+ });
375
+ return issues;
376
+ }
377
+ for (let i = 0; i < signingKeys.length; i++) {
378
+ issues.push(...validateJwk(signingKeys[i], `${path}[${i}]`));
379
+ }
380
+ return issues;
381
+ }
382
+ /**
383
+ * Validate JWK structure
384
+ */
385
+ function validateJwk(jwk, path) {
386
+ const issues = [];
387
+ if (!jwk || typeof jwk !== 'object') {
388
+ issues.push({
389
+ severity: 'error',
390
+ code: validation_js_1.ValidationErrorCodes.INVALID_SIGNING_KEY,
391
+ path,
392
+ message: 'JWK must be an object',
393
+ });
394
+ return issues;
395
+ }
396
+ const key = jwk;
397
+ if (!key.kty) {
398
+ issues.push({
399
+ severity: 'error',
400
+ code: validation_js_1.ValidationErrorCodes.INVALID_SIGNING_KEY,
401
+ path: `${path}.kty`,
402
+ message: 'JWK missing required "kty" field',
403
+ });
404
+ }
405
+ if (!key.kid) {
406
+ issues.push({
407
+ severity: 'error',
408
+ code: validation_js_1.ValidationErrorCodes.INVALID_SIGNING_KEY,
409
+ path: `${path}.kid`,
410
+ message: 'JWK missing required "kid" field',
411
+ });
412
+ }
413
+ return issues;
414
+ }
415
+ //# sourceMappingURL=structural-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structural-validator.js","sourceRoot":"","sources":["../../src/validator/structural-validator.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ucptools/validator",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Validate and generate UCP (Universal Commerce Protocol) Business Profiles",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
File without changes
package/CLAUDE.md DELETED
@@ -1,109 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Project Overview
6
-
7
- UCP Profile Manager is a toolkit for validating and generating UCP (Universal Commerce Protocol) Business Profiles - an open standard enabling AI agents to discover, browse, and complete purchases on UCP-enabled merchants. The project includes a core library, REST API, CLI tools, web UI, and Apify actor integration.
8
-
9
- **Live deployment:** https://ucptools.dev
10
-
11
- ## Commands
12
-
13
- ```bash
14
- # Development
15
- npm run dev # Watch mode Express server (tsx watch src/api/server.ts)
16
- npm run build # TypeScript compilation
17
- npm start # Production server (node dist/api/server.js)
18
-
19
- # Testing
20
- npm test # Vitest tests (30s timeout, v8 coverage)
21
-
22
- # Linting
23
- npm run lint # ESLint on src/**/*.ts
24
-
25
- # CLI tools
26
- npm run validate # Run validator CLI (tsx src/cli/index.ts)
27
- npm run generate # Run generator CLI (tsx src/cli/generate.ts)
28
-
29
- # Database (Drizzle + PostgreSQL)
30
- npm run db:generate # Generate Drizzle schema
31
- npm run db:migrate # Apply migrations
32
- npm run db:push # Push schema to DB
33
- npm run db:studio # Open Drizzle Studio
34
- ```
35
-
36
- ## Architecture
37
-
38
- ### Core Library (`/src/`)
39
-
40
- **Validator (`/src/validator/`)** - Four validation levels:
41
- - `structural-validator.ts` - JSON structure, required fields, version format (YYYY-MM-DD)
42
- - `rules-validator.ts` - UCP compliance (namespace/origin binding, extension chains, HTTPS endpoints, signing keys)
43
- - `network-validator.ts` - Remote schema fetching/verification, self-describing schema validation
44
- - `sdk-validator.ts` - Integration with @ucp-js/sdk for official UCP compliance
45
- - `index.ts` - Orchestrator exposing `validateProfile()`, `validateRemote()`, `validateQuick()`, `validateJsonString()`
46
-
47
- **Generator (`/src/generator/`)** - Profile generation:
48
- - `profile-builder.ts` - `buildProfile()` for full profiles, `generateMinimalProfile()` for checkout-only
49
- - `key-generator.ts` - Ed25519/ES256 signing key generation (`generateSigningKeyPair()`)
50
-
51
- **Simulator (`/src/simulator/`)** - AI agent interaction simulation:
52
- - `agent-simulator.ts` - Tests real-world functionality: discovery flow, capability inspection, checkout simulation
53
- - Not just spec compliance - simulates actual agent workflows
54
-
55
- **Hosting (`/src/hosting/`)** - Platform-specific deployment configs:
56
- - `artifacts-generator.ts` - Generates installation artifacts for Nginx, Apache, Vercel, Netlify, Cloudflare Workers, S3+CloudFront
57
-
58
- ### API & Deployment
59
-
60
- **Express API (`/src/api/server.ts`)** - REST endpoints:
61
- - `POST /v1/profiles/validate`, `/validate-quick`, `/validate-remote`, `/validate-json`
62
- - `POST /v1/profiles/generate`, `/generate-minimal`
63
- - `POST /v1/hosting/artifacts`
64
-
65
- **Vercel Serverless (`/api/`)** - Edge functions for ucptools.dev
66
-
67
- **Database (`/src/db/`)** - Drizzle ORM with PostgreSQL (Neon):
68
- - Schema: merchants (directory), benchmarkStats, benchmarkSummary
69
- - Service: `/src/services/directory.ts` - merchant CRUD, filtering, stats
70
-
71
- ### Types (`/src/types/`)
72
- - `ucp-profile.ts` - UCP specification types
73
- - `validation.ts` - ValidationReport, ValidationIssue interfaces
74
- - `generator.ts` - Generator input/output types
75
-
76
- ## Key Patterns
77
-
78
- **Validation Issue Structure:**
79
- ```typescript
80
- {
81
- severity: 'error' | 'warn' | 'info',
82
- code: string, // e.g., 'UCP_NS_ORIGIN_MISMATCH'
83
- path: string, // JSON path, e.g., '$.ucp.capabilities[0]'
84
- message: string,
85
- hint?: string // Fix suggestion
86
- }
87
- ```
88
-
89
- **Error Codes:** `UCP_MISSING_ROOT`, `UCP_MISSING_VERSION`, `UCP_INVALID_VERSION_FORMAT`, `UCP_NS_ORIGIN_MISMATCH`, `UCP_ORPHANED_EXTENSION`, `UCP_ENDPOINT_NOT_HTTPS`, `UCP_ENDPOINT_TRAILING_SLASH`, `UCP_MISSING_SIGNING_KEYS`, `UCP_SCHEMA_FETCH_FAILED`
90
-
91
- ## Environment Variables
92
-
93
- ```
94
- DATABASE_URL # PostgreSQL connection string (Neon)
95
- NODE_ENV # development | production
96
- PORT # API port (default: 3000)
97
- LOG_LEVEL # Pino log level (default: info)
98
- ```
99
-
100
- ## Tech Stack
101
-
102
- - **Runtime:** Node.js 20+, TypeScript 5.6, ES2022 target
103
- - **API:** Express 4.21
104
- - **Database:** PostgreSQL via @neondatabase/serverless, Drizzle ORM
105
- - **Validation:** AJV 8.17 (JSON Schema), Zod 3.23, @ucp-js/sdk 0.1
106
- - **Crypto:** jose (JWT/JWK), Ed25519 signing
107
- - **CLI:** Commander 12, Chalk 5
108
- - **Testing:** Vitest
109
- - **Deployment:** Vercel