@omnixhq/ucp-js-sdk 1.1.0-draft.4.1 → 2.0.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/README.md CHANGED
@@ -30,12 +30,12 @@
30
30
  ## Overview
31
31
 
32
32
  The JavaScript SDK for the [Universal Commerce Protocol (UCP)](https://ucp.dev).
33
- Auto-generated from the UCP spec with full coverage — 100 schemas including
34
- checkout, orders, payments, fulfillment, discovery profiles, and all inline enums.
33
+ Auto-generated from the UCP spec with full coverage — 134 schemas including
34
+ checkout, cart, catalog, orders, payments, fulfillment, discovery profiles, and all inline enums.
35
35
 
36
36
  **Key features:**
37
37
 
38
- - 100% spec coverage — every schema, `$def`, request variant, and enum
38
+ - 100% spec coverage — every schema, `$def`, request variant, and enum (134 exports)
39
39
  - Fully generated from the UCP JSON Schema spec — consumer aliases in `extensions.ts`
40
40
  - Runtime validation with [Zod](https://zod.dev/) — `.parse()` and `.safeParse()`
41
41
  - Extension-safe — `additionalProperties: true` schemas use `.passthrough()` to preserve extension data
@@ -50,8 +50,7 @@ npm install @omnixhq/ucp-js-sdk
50
50
 
51
51
  ### Draft builds
52
52
 
53
- To build against upcoming UCP spec changes (Catalog capability, Order updates, etc.),
54
- install the `next` tag:
53
+ To build against upcoming UCP spec changes, install the `next` tag:
55
54
 
56
55
  ```bash
57
56
  # Draft (latest UCP spec main branch)
@@ -146,7 +145,7 @@ Node.js 22+ and npm.
146
145
  `src/spec_generated.ts` is auto-generated from the UCP spec:
147
146
 
148
147
  ```bash
149
- npm run generate # default release (v2026-01-23)
148
+ npm run generate # default release (v2026-04-08)
150
149
  npm run generate -- --release v2026-01-24 # specific release tag
151
150
  npm run generate -- --branch main # latest commit on a branch
152
151
  npm run generate -- --commit abc1234 # exact commit SHA
package/dist/index.cjs CHANGED
@@ -182,7 +182,7 @@ const ServicePlatformSchema = zod.intersection(zod.intersection(zod.object({
182
182
  zod.object({ "transport": zod.literal("mcp").optional() }),
183
183
  zod.object({ "transport": zod.literal("a2a").optional() }),
184
184
  zod.object({ "transport": zod.literal("embedded").optional() })
185
- ]))).describe("Full service declaration for platform-level discovery. Different transports require different fields.");
185
+ ]))).describe("Full service declaration for platform-level discovery. All transports require `version`, `spec`, and `transport`. REST and MCP additionally require `schema` and `endpoint`; A2A requires `endpoint`; embedded requires `schema`.");
186
186
  const ServiceBusinessSchema = zod.intersection(zod.intersection(zod.object({
187
187
  "version": zod.string().regex(/* @__PURE__ */ new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."),
188
188
  "spec": zod.string().url().describe("URL to human-readable specification document.").optional(),
@@ -657,7 +657,6 @@ const CheckoutSchema = zod.object({
657
657
  "dev.ucp.buyer_ip": zod.string().describe("Client's IP address (IPv4 or IPv6).").optional(),
658
658
  "dev.ucp.user_agent": zod.string().describe("Client's HTTP User-Agent header or equivalent.").optional()
659
659
  }).passthrough().describe("Environment data provided by the platform to support authorization and abuse prevention. Values MUST NOT be buyer-asserted claims — platforms provide signals based on direct observation or independently verifiable third-party attestations. All signal keys MUST use reverse-domain naming to ensure provenance and prevent collisions when multiple extensions contribute to the shared namespace.").optional(),
660
- "risk_signals": zod.record(zod.string(), zod.unknown()).describe("Deprecated. Use signals instead. Will be removed in the next version.").optional(),
661
660
  "status": zod.enum([
662
661
  "incomplete",
663
662
  "requires_escalation",
@@ -1261,7 +1260,53 @@ const OrderSchema = zod.object({
1261
1260
  }).and(zod.intersection(zod.any(), zod.any())).describe("A cost breakdown entry with a category, amount, and optional display text."), zod.intersection(zod.object({ "lines": zod.array(zod.object({
1262
1261
  "display_text": zod.string().describe("Human-readable label for this sub-line."),
1263
1262
  "amount": zod.number().int().describe("Monetary amount in the currency's minor unit as defined by ISO 4217. Refer to the currency's exponent to determine minor-to-major ratio (e.g., 2 for USD, 0 for JPY, 3 for KWD). May be negative — the sign is intrinsic to the value (e.g., discounts are negative, charges are positive).")
1264
- }).describe("Sub-line entry. Additional metadata MAY be included.")).describe("Optional itemized breakdown. The parent entry is always rendered; lines are supplementary. Sum of line amounts MUST equal the parent entry amount.").optional() }), zod.any()))).describe("Different totals for the order.")
1263
+ }).describe("Sub-line entry. Additional metadata MAY be included.")).describe("Optional itemized breakdown. The parent entry is always rendered; lines are supplementary. Sum of line amounts MUST equal the parent entry amount.").optional() }), zod.any()))).describe("Different totals for the order."),
1264
+ "messages": zod.array(zod.record(zod.string(), zod.unknown()).and(zod.unknown().superRefine((x, ctx) => {
1265
+ const schemas = [
1266
+ zod.object({
1267
+ "type": zod.literal("error").describe("Message type discriminator."),
1268
+ "code": zod.string().describe("Error code identifying the type of error. Standard errors are defined in specification (see examples), and have standardized semantics; freeform codes are permitted."),
1269
+ "path": zod.string().describe("RFC 9535 JSONPath to the component the message refers to (e.g., $.items[1]).").optional(),
1270
+ "content_type": zod.enum(["plain", "markdown"]).describe("Content format, default = plain.").default("plain"),
1271
+ "content": zod.string().describe("Human-readable message."),
1272
+ "severity": zod.enum([
1273
+ "recoverable",
1274
+ "requires_buyer_input",
1275
+ "requires_buyer_review",
1276
+ "unrecoverable"
1277
+ ]).describe("Reflects the resource state and recommended action. 'recoverable': platform can resolve by modifying inputs and retrying via API. 'requires_buyer_input': merchant requires information their API doesn't support collecting programmatically (checkout incomplete). 'requires_buyer_review': buyer must authorize before order placement due to policy, regulatory, or entitlement rules. 'unrecoverable': no valid resource exists to act on, retry with new resource or inputs. Errors with 'requires_*' severity contribute to 'status: requires_escalation'.")
1278
+ }),
1279
+ zod.object({
1280
+ "type": zod.literal("warning").describe("Message type discriminator."),
1281
+ "path": zod.string().describe("JSONPath (RFC 9535) to related field (e.g., $.line_items[0]).").optional(),
1282
+ "code": zod.string().describe("Warning code. Machine-readable identifier for the warning type (e.g., final_sale, prop65, fulfillment_changed, age_restricted, etc.)."),
1283
+ "content": zod.string().describe("Human-readable warning message that MUST be displayed."),
1284
+ "content_type": zod.enum(["plain", "markdown"]).describe("Content format, default = plain.").default("plain"),
1285
+ "presentation": zod.string().describe("Rendering contract for this warning. 'notice' (default): platform MUST display, MAY dismiss. 'disclosure': platform MUST display in proximity to the path-referenced component, MUST NOT hide or auto-dismiss. See specification for full contract.").default("notice"),
1286
+ "image_url": zod.string().url().describe("URL to a required visual element (e.g., warning symbol, energy class label).").optional(),
1287
+ "url": zod.string().url().describe("Reference URL for more information (e.g., regulatory site, registry entry, policy page).").optional()
1288
+ }),
1289
+ zod.object({
1290
+ "type": zod.literal("info").describe("Message type discriminator."),
1291
+ "path": zod.string().describe("RFC 9535 JSONPath to the component the message refers to.").optional(),
1292
+ "code": zod.string().describe("Info code for programmatic handling.").optional(),
1293
+ "content_type": zod.enum(["plain", "markdown"]).describe("Content format, default = plain.").default("plain"),
1294
+ "content": zod.string().describe("Human-readable message.")
1295
+ })
1296
+ ];
1297
+ const errors = schemas.reduce((errors, schema) => ((result) => result.error ? [...errors, result.error] : errors)(schema.safeParse(x)), []);
1298
+ const passed = schemas.length - errors.length;
1299
+ if (passed !== 1) ctx.addIssue(errors.length ? {
1300
+ path: ctx.path,
1301
+ code: "invalid_union",
1302
+ unionErrors: errors,
1303
+ message: "Invalid input: Should pass single schema. Passed " + passed
1304
+ } : {
1305
+ path: ctx.path,
1306
+ code: "custom",
1307
+ message: "Invalid input: Should pass single schema. Passed " + passed
1308
+ });
1309
+ })).describe("Container for error, warning, or info messages.")).describe("Business outcome messages (errors, warnings, informational). Present when the business needs to communicate status or issues to the platform.").optional()
1265
1310
  }).describe("Order schema with line items, buyer-facing fulfillment expectations, and event logs.");
1266
1311
  const PaymentSchema = zod.object({ "instruments": zod.array(zod.intersection(zod.object({
1267
1312
  "id": zod.string().describe("A unique identifier for this instrument instance, assigned by the platform."),
@@ -2291,6 +2336,106 @@ const UcpBaseSchema = zod.object({
2291
2336
  "constraints": zod.record(zod.string(), zod.unknown()).describe("Constraints on this instrument type. Structure depends on instrument type and active capabilities.").optional()
2292
2337
  }).describe("An instrument type available from a payment handler with optional constraints.")).min(1).describe("Instrument types this handler supports, with optional constraints. When absent, every instrument should be considered available.").optional() }))))).describe("Payment handler registry keyed by reverse-domain name.").optional()
2293
2338
  }).describe("Base UCP metadata with shared properties for all schema types.");
2339
+ const UcpSuccessSchema = zod.intersection(zod.object({
2340
+ "version": zod.string().regex(/* @__PURE__ */ new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("UCP version in YYYY-MM-DD format."),
2341
+ "status": zod.enum(["success", "error"]).describe("Application-level status of the UCP operation.").default("success"),
2342
+ "services": zod.record(zod.array(zod.intersection(zod.object({
2343
+ "version": zod.string().regex(/* @__PURE__ */ new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."),
2344
+ "spec": zod.string().url().describe("URL to human-readable specification document.").optional(),
2345
+ "schema": zod.string().url().describe("URL to JSON Schema defining this entity's structure and payloads.").optional(),
2346
+ "id": zod.string().describe("Unique identifier for this entity instance. Used to disambiguate when multiple instances exist.").optional(),
2347
+ "config": zod.record(zod.string(), zod.unknown()).describe("Entity-specific configuration. Structure defined by each entity's schema.").optional()
2348
+ }).describe("Shared foundation for all UCP entities."), zod.object({
2349
+ "transport": zod.enum([
2350
+ "rest",
2351
+ "mcp",
2352
+ "a2a",
2353
+ "embedded"
2354
+ ]).describe("Transport protocol for this service binding."),
2355
+ "endpoint": zod.string().url().describe("Endpoint URL for this transport binding.").optional()
2356
+ })))).describe("Service registry keyed by reverse-domain name.").optional(),
2357
+ "capabilities": zod.record(zod.array(zod.intersection(zod.object({
2358
+ "version": zod.string().regex(/* @__PURE__ */ new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."),
2359
+ "spec": zod.string().url().describe("URL to human-readable specification document.").optional(),
2360
+ "schema": zod.string().url().describe("URL to JSON Schema defining this entity's structure and payloads.").optional(),
2361
+ "id": zod.string().describe("Unique identifier for this entity instance. Used to disambiguate when multiple instances exist.").optional(),
2362
+ "config": zod.record(zod.string(), zod.unknown()).describe("Entity-specific configuration. Structure defined by each entity's schema.").optional()
2363
+ }).describe("Shared foundation for all UCP entities."), zod.object({ "extends": zod.unknown().superRefine((x, ctx) => {
2364
+ const schemas = [zod.string().regex(/* @__PURE__ */ new RegExp("^[a-z][a-z0-9]*(?:\\.[a-z][a-z0-9_]*)+$")), zod.array(zod.string().regex(/* @__PURE__ */ new RegExp("^[a-z][a-z0-9]*(?:\\.[a-z][a-z0-9_]*)+$"))).min(1)];
2365
+ const errors = schemas.reduce((errors, schema) => ((result) => result.error ? [...errors, result.error] : errors)(schema.safeParse(x)), []);
2366
+ const passed = schemas.length - errors.length;
2367
+ if (passed !== 1) ctx.addIssue(errors.length ? {
2368
+ path: ctx.path,
2369
+ code: "invalid_union",
2370
+ unionErrors: errors,
2371
+ message: "Invalid input: Should pass single schema. Passed " + passed
2372
+ } : {
2373
+ path: ctx.path,
2374
+ code: "custom",
2375
+ message: "Invalid input: Should pass single schema. Passed " + passed
2376
+ });
2377
+ }).describe("Parent capability(s) this extends. Present for extensions, absent for root capabilities. Use array for multi-parent extensions.").optional() })))).describe("Capability registry keyed by reverse-domain name.").optional(),
2378
+ "payment_handlers": zod.record(zod.array(zod.intersection(zod.object({
2379
+ "version": zod.string().regex(/* @__PURE__ */ new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."),
2380
+ "spec": zod.string().url().describe("URL to human-readable specification document.").optional(),
2381
+ "schema": zod.string().url().describe("URL to JSON Schema defining this entity's structure and payloads.").optional(),
2382
+ "id": zod.string().describe("Unique identifier for this entity instance. Used to disambiguate when multiple instances exist.").optional(),
2383
+ "config": zod.record(zod.string(), zod.unknown()).describe("Entity-specific configuration. Structure defined by each entity's schema.").optional()
2384
+ }).describe("Shared foundation for all UCP entities."), zod.intersection(zod.record(zod.string(), zod.unknown()), zod.object({ "available_instruments": zod.array(zod.object({
2385
+ "type": zod.string().describe("The instrument type identifier (e.g., 'card', 'gift_card'). References an instrument schema's type constant."),
2386
+ "constraints": zod.record(zod.string(), zod.unknown()).describe("Constraints on this instrument type. Structure depends on instrument type and active capabilities.").optional()
2387
+ }).describe("An instrument type available from a payment handler with optional constraints.")).min(1).describe("Instrument types this handler supports, with optional constraints. When absent, every instrument should be considered available.").optional() }))))).describe("Payment handler registry keyed by reverse-domain name.").optional()
2388
+ }).describe("Base UCP metadata with shared properties for all schema types."), zod.object({ "status": zod.literal("success") })).describe("UCP metadata with status 'success'. Use for response branches that carry the expected payload.");
2389
+ const UcpErrorSchema = zod.intersection(zod.object({
2390
+ "version": zod.string().regex(/* @__PURE__ */ new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("UCP version in YYYY-MM-DD format."),
2391
+ "status": zod.enum(["success", "error"]).describe("Application-level status of the UCP operation.").default("success"),
2392
+ "services": zod.record(zod.array(zod.intersection(zod.object({
2393
+ "version": zod.string().regex(/* @__PURE__ */ new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."),
2394
+ "spec": zod.string().url().describe("URL to human-readable specification document.").optional(),
2395
+ "schema": zod.string().url().describe("URL to JSON Schema defining this entity's structure and payloads.").optional(),
2396
+ "id": zod.string().describe("Unique identifier for this entity instance. Used to disambiguate when multiple instances exist.").optional(),
2397
+ "config": zod.record(zod.string(), zod.unknown()).describe("Entity-specific configuration. Structure defined by each entity's schema.").optional()
2398
+ }).describe("Shared foundation for all UCP entities."), zod.object({
2399
+ "transport": zod.enum([
2400
+ "rest",
2401
+ "mcp",
2402
+ "a2a",
2403
+ "embedded"
2404
+ ]).describe("Transport protocol for this service binding."),
2405
+ "endpoint": zod.string().url().describe("Endpoint URL for this transport binding.").optional()
2406
+ })))).describe("Service registry keyed by reverse-domain name.").optional(),
2407
+ "capabilities": zod.record(zod.array(zod.intersection(zod.object({
2408
+ "version": zod.string().regex(/* @__PURE__ */ new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."),
2409
+ "spec": zod.string().url().describe("URL to human-readable specification document.").optional(),
2410
+ "schema": zod.string().url().describe("URL to JSON Schema defining this entity's structure and payloads.").optional(),
2411
+ "id": zod.string().describe("Unique identifier for this entity instance. Used to disambiguate when multiple instances exist.").optional(),
2412
+ "config": zod.record(zod.string(), zod.unknown()).describe("Entity-specific configuration. Structure defined by each entity's schema.").optional()
2413
+ }).describe("Shared foundation for all UCP entities."), zod.object({ "extends": zod.unknown().superRefine((x, ctx) => {
2414
+ const schemas = [zod.string().regex(/* @__PURE__ */ new RegExp("^[a-z][a-z0-9]*(?:\\.[a-z][a-z0-9_]*)+$")), zod.array(zod.string().regex(/* @__PURE__ */ new RegExp("^[a-z][a-z0-9]*(?:\\.[a-z][a-z0-9_]*)+$"))).min(1)];
2415
+ const errors = schemas.reduce((errors, schema) => ((result) => result.error ? [...errors, result.error] : errors)(schema.safeParse(x)), []);
2416
+ const passed = schemas.length - errors.length;
2417
+ if (passed !== 1) ctx.addIssue(errors.length ? {
2418
+ path: ctx.path,
2419
+ code: "invalid_union",
2420
+ unionErrors: errors,
2421
+ message: "Invalid input: Should pass single schema. Passed " + passed
2422
+ } : {
2423
+ path: ctx.path,
2424
+ code: "custom",
2425
+ message: "Invalid input: Should pass single schema. Passed " + passed
2426
+ });
2427
+ }).describe("Parent capability(s) this extends. Present for extensions, absent for root capabilities. Use array for multi-parent extensions.").optional() })))).describe("Capability registry keyed by reverse-domain name.").optional(),
2428
+ "payment_handlers": zod.record(zod.array(zod.intersection(zod.object({
2429
+ "version": zod.string().regex(/* @__PURE__ */ new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."),
2430
+ "spec": zod.string().url().describe("URL to human-readable specification document.").optional(),
2431
+ "schema": zod.string().url().describe("URL to JSON Schema defining this entity's structure and payloads.").optional(),
2432
+ "id": zod.string().describe("Unique identifier for this entity instance. Used to disambiguate when multiple instances exist.").optional(),
2433
+ "config": zod.record(zod.string(), zod.unknown()).describe("Entity-specific configuration. Structure defined by each entity's schema.").optional()
2434
+ }).describe("Shared foundation for all UCP entities."), zod.intersection(zod.record(zod.string(), zod.unknown()), zod.object({ "available_instruments": zod.array(zod.object({
2435
+ "type": zod.string().describe("The instrument type identifier (e.g., 'card', 'gift_card'). References an instrument schema's type constant."),
2436
+ "constraints": zod.record(zod.string(), zod.unknown()).describe("Constraints on this instrument type. Structure depends on instrument type and active capabilities.").optional()
2437
+ }).describe("An instrument type available from a payment handler with optional constraints.")).min(1).describe("Instrument types this handler supports, with optional constraints. When absent, every instrument should be considered available.").optional() }))))).describe("Payment handler registry keyed by reverse-domain name.").optional()
2438
+ }).describe("Base UCP metadata with shared properties for all schema types."), zod.object({ "status": zod.literal("error") })).describe("UCP metadata with status 'error'. Use for response branches that carry error information.");
2294
2439
  const UcpPlatformSchema = zod.intersection(zod.object({
2295
2440
  "version": zod.string().regex(/* @__PURE__ */ new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("UCP version in YYYY-MM-DD format."),
2296
2441
  "status": zod.enum(["success", "error"]).describe("Application-level status of the UCP operation.").default("success"),
@@ -2360,7 +2505,7 @@ const UcpPlatformSchema = zod.intersection(zod.object({
2360
2505
  zod.object({ "transport": zod.literal("mcp").optional() }),
2361
2506
  zod.object({ "transport": zod.literal("a2a").optional() }),
2362
2507
  zod.object({ "transport": zod.literal("embedded").optional() })
2363
- ]))).describe("Full service declaration for platform-level discovery. Different transports require different fields."))),
2508
+ ]))).describe("Full service declaration for platform-level discovery. All transports require `version`, `spec`, and `transport`. REST and MCP additionally require `schema` and `endpoint`; A2A requires `endpoint`; embedded requires `schema`."))),
2364
2509
  "capabilities": zod.record(zod.array(zod.intersection(zod.intersection(zod.object({
2365
2510
  "version": zod.string().regex(/* @__PURE__ */ new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."),
2366
2511
  "spec": zod.string().url().describe("URL to human-readable specification document.").optional(),
@@ -3025,7 +3170,7 @@ const ProfileSchemaPlatformProfileSchema = zod.intersection(zod.object({
3025
3170
  zod.object({ "transport": zod.literal("mcp").optional() }),
3026
3171
  zod.object({ "transport": zod.literal("a2a").optional() }),
3027
3172
  zod.object({ "transport": zod.literal("embedded").optional() })
3028
- ]))).describe("Full service declaration for platform-level discovery. Different transports require different fields."))),
3173
+ ]))).describe("Full service declaration for platform-level discovery. All transports require `version`, `spec`, and `transport`. REST and MCP additionally require `schema` and `endpoint`; A2A requires `endpoint`; embedded requires `schema`."))),
3029
3174
  "capabilities": zod.record(zod.array(zod.intersection(zod.intersection(zod.object({
3030
3175
  "version": zod.string().regex(/* @__PURE__ */ new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("UCP version in YYYY-MM-DD format."),
3031
3176
  "spec": zod.string().url().describe("URL to human-readable specification document.").optional(),
@@ -3431,6 +3576,7 @@ exports.UcpDiscoveryBusinessProfileSchema = UcpDiscoveryBusinessProfileSchema;
3431
3576
  exports.UcpDiscoveryPlatformProfileSchema = UcpDiscoveryPlatformProfileSchema;
3432
3577
  exports.UcpDiscoveryProfileSchema = UcpDiscoveryProfileSchema;
3433
3578
  exports.UcpEntitySchema = UcpEntitySchema;
3579
+ exports.UcpErrorSchema = UcpErrorSchema;
3434
3580
  exports.UcpPlatformSchema = UcpPlatformSchema;
3435
3581
  exports.UcpRequiresSchema = UcpRequiresSchema;
3436
3582
  exports.UcpResponseCartSchema = UcpResponseCartSchema;
@@ -3438,6 +3584,7 @@ exports.UcpResponseCatalogSchema = UcpResponseCatalogSchema;
3438
3584
  exports.UcpResponseCheckoutSchema = UcpResponseCheckoutSchema;
3439
3585
  exports.UcpResponseOrderSchema = UcpResponseOrderSchema;
3440
3586
  exports.UcpSigningKeySchema = UcpSigningKeySchema;
3587
+ exports.UcpSuccessSchema = UcpSuccessSchema;
3441
3588
  exports.UcpVersionConstraintSchema = UcpVersionConstraintSchema;
3442
3589
  exports.UcpVersionSchema = UcpVersionSchema;
3443
3590
  exports.VariantSchema = VariantSchema;