diff --git a/generate_models.sh b/generate_models.sh index 4c2aa79..990bc3e 100755 --- a/generate_models.sh +++ b/generate_models.sh @@ -1,29 +1,82 @@ #!/bin/bash -if [[ -z "$1" ]]; then - echo "Error: spec directory path is required." - echo "Usage: $0 " - echo "Example: npm run generate -- /path/to/spec" +set -euo pipefail + +if [[ -z "${1:-}" ]]; then + echo "Error: schema directory path is required." + echo "Usage: $0 " + echo "Examples:" + echo " npm run generate -- /path/to/legacy-ucp/spec" + echo " npm run generate -- /path/to/legacy-ucp" + exit 1 +fi + +INPUT_DIR="${1%/}" + +if [[ -d "$INPUT_DIR/schemas/shopping" ]]; then + SPEC_DIR="$INPUT_DIR" + SCHEMA_LAYOUT="legacy" +elif [[ -d "$INPUT_DIR/spec/schemas/shopping" ]]; then + SPEC_DIR="$INPUT_DIR/spec" + SCHEMA_LAYOUT="legacy" +elif [[ -d "$INPUT_DIR/source/schemas/shopping" ]]; then + SPEC_DIR="$INPUT_DIR/source" + SCHEMA_LAYOUT="source" +else + echo "Error: could not find a supported UCP schema directory." + echo "Expected one of:" + echo " /schemas/shopping" + echo " /spec/schemas/shopping" + echo " /source/schemas/shopping" exit 1 fi -SPEC_DIR="${1%/}" - -quicktype \ - --lang typescript-zod \ - --src-lang schema \ - --src "$SPEC_DIR"/discovery/*.json \ - --src "$SPEC_DIR"/schemas/shopping/*.json \ - --src "$SPEC_DIR"/schemas/shopping/types/*.json \ - --src "$SPEC_DIR/schemas/shopping/ap2_mandate.json#/\$defs/complete_request_with_ap2" \ - --src "$SPEC_DIR/schemas/shopping/ap2_mandate.json#/\$defs/checkout_response_with_ap2" \ - --src "$SPEC_DIR/schemas/shopping/buyer_consent.create_req.json#/\$defs/checkout" \ - --src "$SPEC_DIR/schemas/shopping/buyer_consent.update_req.json#/\$defs/checkout" \ - --src "$SPEC_DIR/schemas/shopping/buyer_consent_resp.json#/\$defs/checkout" \ - --src "$SPEC_DIR/schemas/shopping/discount.create_req.json#/\$defs/checkout" \ - --src "$SPEC_DIR/schemas/shopping/discount.update_req.json#/\$defs/checkout" \ - --src "$SPEC_DIR/schemas/shopping/discount_resp.json#/\$defs/checkout" \ - --src "$SPEC_DIR/schemas/shopping/fulfillment.create_req.json#/\$defs/checkout" \ - --src "$SPEC_DIR/schemas/shopping/fulfillment.update_req.json#/\$defs/checkout" \ - --src "$SPEC_DIR/schemas/shopping/fulfillment_resp.json#/\$defs/checkout" \ - -o src/spec_generated.ts +TMP_OUTPUT="$(mktemp "${TMPDIR:-/tmp}/ucp-spec-generated.XXXXXX.ts")" +PROJECTED_SPEC_DIR="" +cleanup() { + rm -f "$TMP_OUTPUT" + if [[ -n "$PROJECTED_SPEC_DIR" ]]; then + rm -rf "$PROJECTED_SPEC_DIR" + fi +} +trap cleanup EXIT + +if [[ "$SCHEMA_LAYOUT" == "source" ]]; then + PROJECTED_SPEC_DIR="$(mktemp -d "${TMPDIR:-/tmp}/ucp-js-sdk-projected.XXXXXX")" + node scripts/project-current-ucp-schemas.mjs "$SPEC_DIR" "$PROJECTED_SPEC_DIR" + SPEC_DIR="$PROJECTED_SPEC_DIR" +fi + +QUICKTYPE_ARGS=( + --lang typescript-zod + --src-lang schema + --src "$SPEC_DIR"/discovery/*.json + --src "$SPEC_DIR/schemas/shopping/checkout.create_req.json" + --src "$SPEC_DIR/schemas/shopping/checkout.update_req.json" + --src "$SPEC_DIR/schemas/shopping/checkout_resp.json" + --src "$SPEC_DIR/schemas/shopping/order.json" + --src "$SPEC_DIR/schemas/shopping/payment.create_req.json" + --src "$SPEC_DIR/schemas/shopping/payment.update_req.json" + --src "$SPEC_DIR/schemas/shopping/payment_data.json" + --src "$SPEC_DIR/schemas/shopping/payment_resp.json" + --src "$SPEC_DIR/schemas/shopping/ap2_mandate.json#/\$defs/complete_request_with_ap2" + --src "$SPEC_DIR/schemas/shopping/ap2_mandate.json#/\$defs/checkout_response_with_ap2" + --src "$SPEC_DIR/schemas/shopping/buyer_consent.create_req.json#/\$defs/checkout" + --src "$SPEC_DIR/schemas/shopping/buyer_consent.update_req.json#/\$defs/checkout" + --src "$SPEC_DIR/schemas/shopping/buyer_consent_resp.json#/\$defs/checkout" + --src "$SPEC_DIR/schemas/shopping/discount.create_req.json#/\$defs/checkout" + --src "$SPEC_DIR/schemas/shopping/discount.update_req.json#/\$defs/checkout" + --src "$SPEC_DIR/schemas/shopping/discount_resp.json#/\$defs/checkout" + --src "$SPEC_DIR/schemas/shopping/fulfillment.create_req.json#/\$defs/checkout" + --src "$SPEC_DIR/schemas/shopping/fulfillment.update_req.json#/\$defs/checkout" + --src "$SPEC_DIR/schemas/shopping/fulfillment_resp.json#/\$defs/checkout" + -o "$TMP_OUTPUT" +) + +if [[ "$SCHEMA_LAYOUT" == "legacy" ]]; then + QUICKTYPE_ARGS+=(--src "$SPEC_DIR"/schemas/shopping/types/*.json) +fi + +npx quicktype "${QUICKTYPE_ARGS[@]}" + +node scripts/normalize-generated-schemas.mjs "$TMP_OUTPUT" src/spec_generated.ts diff --git a/scripts/normalize-generated-schemas.mjs b/scripts/normalize-generated-schemas.mjs new file mode 100644 index 0000000..cec861d --- /dev/null +++ b/scripts/normalize-generated-schemas.mjs @@ -0,0 +1,189 @@ +import fs from "node:fs"; +import path from "node:path"; +import ts from "typescript"; + +const [, , inputPath, outputPath] = process.argv; + +if (!inputPath || !outputPath) { + console.error( + "Usage: node scripts/normalize-generated-schemas.mjs " + ); + process.exit(1); +} + +const sourcePath = path.resolve(inputPath); +const destinationPath = path.resolve(outputPath); +const sourceText = fs.readFileSync(sourcePath, "utf8"); +const sourceFile = ts.createSourceFile( + sourcePath, + sourceText, + ts.ScriptTarget.Latest, + true, + ts.ScriptKind.TS +); + +const canonicalNames = new Map([ + ["AdjustmentLineItem", "LineItemQuantityRef"], + ["AdjustmentLineItemClass", "LineItemQuantityRef"], + ["AllocationClass", "Allocation"], + ["AllocationElement", "Allocation"], + ["AppliedAllocation", "Allocation"], + ["BillingAddressClass", "PostalAddress"], + ["BuyerClass", "Buyer"], + ["CardPaymentInstrument", "PaymentInstrument"], + ["CheckoutUpdateRequestPayment", "PaymentSelection"], + ["EventLineItem", "LineItemQuantityRef"], + ["ExpectationLineItem", "LineItemQuantityRef"], + ["ExpectationLineItemClass", "LineItemQuantityRef"], + ["FluffyConsent", "Consent"], + ["FulfillmentDestinationRequestElement", "FulfillmentDestinationRequest"], + ["FulfillmentEventLineItem", "LineItemQuantityRef"], + ["GroupClass", "FulfillmentGroupUpdateRequest"], + ["GroupElement", "FulfillmentGroupCreateRequest"], + ["IdentityClass", "PaymentIdentity"], + ["ItemClass", "ItemReference"], + ["ItemCreateRequest", "ItemReference"], + ["ItemUpdateRequest", "ItemReference"], + ["LineItemClass", "LineItemUpdateRequest"], + ["LineItemElement", "LineItemCreateRequest"], + ["LineItemItem", "ItemReference"], + ["LinkElement", "Link"], + ["Mcp", "SchemaEndpoint"], + ["MessageElement", "Message"], + ["MethodElement", "FulfillmentMethodCreateRequest"], + ["OrderClass", "OrderConfirmation"], + ["OrderLineItemQuantity", "LineItemQuantity"], + ["PaymentClass", "PaymentSelection"], + ["PaymentCreateRequest", "PaymentSelection"], + ["PaymentUpdateRequest", "PaymentSelection"], + ["PurpleConsent", "Consent"], + ["Rest", "SchemaEndpoint"], + ["TentacledConsent", "Consent"], + ["TokenCredentialCreateRequest", "TokenCredentialRequest"], + ["TokenCredentialUpdateRequest", "TokenCredentialRequest"], + ["UcpCheckoutResponse", "UcpResponse"], + ["UcpOrderResponse", "UcpResponse"], +]); + +function normalizeSchemaText(text) { + return text.replace(/\s+/g, " ").trim(); +} + +function aliasBlock(aliasName, canonicalName) { + return `export const ${aliasName}Schema = ${canonicalName}Schema;\nexport type ${aliasName} = ${canonicalName};`; +} + +const schemaBlocks = new Map(); + +for (let index = 0; index < sourceFile.statements.length; index += 1) { + const statement = sourceFile.statements[index]; + if (!ts.isVariableStatement(statement)) { + continue; + } + + const declaration = statement.declarationList.declarations[0]; + if ( + !declaration || + !ts.isIdentifier(declaration.name) || + !declaration.initializer || + !declaration.name.text.endsWith("Schema") + ) { + continue; + } + + const schemaName = declaration.name.text.slice(0, -6); + const nextStatement = sourceFile.statements[index + 1]; + + if ( + !nextStatement || + !ts.isTypeAliasDeclaration(nextStatement) || + nextStatement.name.text !== schemaName + ) { + continue; + } + + schemaBlocks.set(schemaName, { + schemaName, + start: statement.getStart(sourceFile), + end: nextStatement.end, + initializerText: declaration.initializer.getText(sourceFile), + normalizedInitializer: normalizeSchemaText( + declaration.initializer.getText(sourceFile) + ), + }); +} + +const duplicateGroups = new Map(); +for (const block of schemaBlocks.values()) { + const group = duplicateGroups.get(block.normalizedInitializer) ?? []; + group.push(block.schemaName); + duplicateGroups.set(block.normalizedInitializer, group); +} + +const replacements = []; + +for (const [normalizedInitializer, names] of duplicateGroups.entries()) { + if (names.length === 1) { + continue; + } + + const canonicalName = + names.map((name) => canonicalNames.get(name)).find(Boolean) ?? names[0]; + const keepName = names + .map((name) => schemaBlocks.get(name)) + .filter(Boolean) + .sort((left, right) => left.start - right.start)[0]?.schemaName; + const keepBlock = schemaBlocks.get(keepName); + + if (!keepBlock) { + continue; + } + + const aliases = new Set(names.filter((name) => name !== canonicalName)); + if (keepName !== canonicalName) { + aliases.add(keepName); + } + + const canonicalBlock = [ + `export const ${canonicalName}Schema = ${keepBlock.initializerText};`, + `export type ${canonicalName} = z.infer;`, + ...Array.from(aliases) + .sort((left, right) => left.localeCompare(right)) + .map((name) => aliasBlock(name, canonicalName)), + ].join("\n"); + + replacements.push({ + start: keepBlock.start, + end: keepBlock.end, + text: `${canonicalBlock}\n`, + }); + + for (const name of names) { + if (name === keepName) { + continue; + } + + const block = schemaBlocks.get(name); + if (!block) { + continue; + } + + replacements.push({ + start: block.start, + end: block.end, + text: "", + }); + } +} + +replacements.sort((left, right) => right.start - left.start); + +let outputText = sourceText; +for (const replacement of replacements) { + outputText = + outputText.slice(0, replacement.start) + + replacement.text + + outputText.slice(replacement.end); +} + +fs.writeFileSync(destinationPath, outputText); diff --git a/scripts/project-current-ucp-schemas.mjs b/scripts/project-current-ucp-schemas.mjs new file mode 100644 index 0000000..d35d7cf --- /dev/null +++ b/scripts/project-current-ucp-schemas.mjs @@ -0,0 +1,849 @@ +import fs from "node:fs"; +import path from "node:path"; + +const [, , sourceRootArg, outputRootArg] = process.argv; + +if (!sourceRootArg || !outputRootArg) { + console.error( + "Usage: node scripts/project-current-ucp-schemas.mjs " + ); + process.exit(1); +} + +const sourceRoot = path.resolve(sourceRootArg); +const outputRoot = path.resolve(outputRootArg); +const sourceSchemasRoot = path.join(sourceRoot, "schemas"); + +const sourceShoppingRoot = path.join(sourceSchemasRoot, "shopping"); +const sourceTypesRoot = path.join(sourceShoppingRoot, "types"); + +if (!fs.existsSync(sourceShoppingRoot)) { + console.error(`Expected shopping schemas at ${sourceShoppingRoot}`); + process.exit(1); +} + +fs.rmSync(outputRoot, { recursive: true, force: true }); +fs.mkdirSync(outputRoot, { recursive: true }); + +const outputDiscoveryRoot = path.join(outputRoot, "discovery"); +const outputSchemasRoot = path.join(outputRoot, "schemas"); +const outputShoppingRoot = path.join(outputSchemasRoot, "shopping"); +const outputTypesRoot = path.join(outputShoppingRoot, "types"); + +fs.mkdirSync(outputDiscoveryRoot, { recursive: true }); +fs.mkdirSync(outputTypesRoot, { recursive: true }); + +const CUSTOM_KEYS = new Set([ + "$comment", + "identity_scopes", + "name", + "ucp_request", + "ucp_response", + "ucp_shared_request", +]); + +const topLevelVariantMap = { + "shopping/checkout.json": { + create: "shopping/checkout.create_req.json", + update: "shopping/checkout.update_req.json", + response: "shopping/checkout_resp.json", + }, + "shopping/payment.json": { + create: "shopping/payment.create_req.json", + update: "shopping/payment.update_req.json", + response: "shopping/payment_resp.json", + }, + "shopping/order.json": { + response: "shopping/order.json", + }, + "shopping/buyer_consent.json": { + create: "shopping/buyer_consent.create_req.json", + update: "shopping/buyer_consent.update_req.json", + response: "shopping/buyer_consent_resp.json", + }, + "shopping/discount.json": { + create: "shopping/discount.create_req.json", + update: "shopping/discount.update_req.json", + response: "shopping/discount_resp.json", + }, + "shopping/fulfillment.json": { + create: "shopping/fulfillment.create_req.json", + update: "shopping/fulfillment.update_req.json", + response: "shopping/fulfillment_resp.json", + }, +}; + +const alwaysUnifiedTypeFiles = new Set([ + "account_info", + "adjustment", + "amount", + "available_payment_instrument", + "binding", + "buyer", + "business_fulfillment_config", + "card_credential", + "card_payment_instrument", + "category", + "context", + "description", + "error_code", + "error_response", + "expectation", + "fulfillment_event", + "link", + "media", + "merchant_fulfillment_config", + "message", + "message_error", + "message_info", + "message_warning", + "option_value", + "order_confirmation", + "order_line_item", + "pagination", + "payment_credential", + "payment_identity", + "payment_instrument", + "platform_fulfillment_config", + "postal_address", + "price", + "price_filter", + "price_range", + "product", + "product_option", + "rating", + "reverse_domain_name", + "search_filters", + "selected_option", + "signals", + "signed_amount", + "variant", +]); + +function readJson(filePath) { + return JSON.parse(fs.readFileSync(filePath, "utf8")); +} + +function writeJson(filePath, value) { + fs.mkdirSync(path.dirname(filePath), { recursive: true }); + fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`); +} + +function clone(value) { + return JSON.parse(JSON.stringify(value)); +} + +function hasKeyword(value, key) { + if (!value || typeof value !== "object") { + return false; + } + + if (Object.prototype.hasOwnProperty.call(value, key)) { + return true; + } + + if (Array.isArray(value)) { + return value.some((entry) => hasKeyword(entry, key)); + } + + return Object.values(value).some((entry) => hasKeyword(entry, key)); +} + +function normalizeRequestRule(rule) { + if (!rule) { + return undefined; + } + + if (typeof rule === "string") { + return rule; + } + + if (typeof rule === "object" && rule.transition) { + return rule.transition.to; + } + + return undefined; +} + +function effectiveRequestRule(schema, variant) { + const rule = schema?.ucp_request; + if (!rule) { + return undefined; + } + + if (typeof rule === "string") { + return rule; + } + + return normalizeRequestRule(rule[variant]); +} + +function splitStrategyForSchema(baseName, schema) { + if (alwaysUnifiedTypeFiles.has(baseName)) { + return "unified"; + } + + if (schema?.ucp_shared_request) { + return "shared_request"; + } + + if (hasKeyword(schema, "ucp_request") || hasKeyword(schema, "ucp_response")) { + return "create_update"; + } + + return "unified"; +} + +function legacyTypeOutputPath(baseName, schema, variant) { + const strategy = splitStrategyForSchema(baseName, schema); + + if (strategy === "unified") { + return `shopping/types/${baseName}.json`; + } + + if (strategy === "shared_request") { + if (variant === "response") { + return `shopping/types/${baseName}_resp.json`; + } + + return `shopping/types/${baseName}_req.json`; + } + + if (variant === "response") { + return `shopping/types/${baseName}_resp.json`; + } + + return `shopping/types/${baseName}.${variant}_req.json`; +} + +function topLevelOutputPath(sourceRel, variant) { + return topLevelVariantMap[sourceRel]?.[variant]; +} + +function mapOutputPathForTarget(sourceRel, variant, sourceSchema) { + if (sourceRel.startsWith("shopping/types/")) { + const baseName = path.posix.basename(sourceRel, ".json"); + return legacyTypeOutputPath(baseName, sourceSchema, variant); + } + + return topLevelOutputPath(sourceRel, variant) ?? sourceRel; +} + +function rewriteRef(ref, sourceRel, outputRel, variant, schemaCache) { + if (!ref || ref.startsWith("#") || /^[a-z]+:\/\//i.test(ref)) { + return ref; + } + + const [refPath, fragment = ""] = ref.split("#"); + const currentDir = path.posix.dirname(sourceRel); + const targetSourceRel = path.posix.normalize( + path.posix.join(currentDir, refPath) + ); + const targetSourceSchema = schemaCache.get(targetSourceRel); + const targetOutputRel = mapOutputPathForTarget( + targetSourceRel, + variant, + targetSourceSchema + ); + + const relativeTarget = path.posix.relative( + path.posix.dirname(outputRel), + targetOutputRel + ); + + const normalizedTarget = relativeTarget === "" ? "." : relativeTarget; + return fragment ? `${normalizedTarget}#${fragment}` : normalizedTarget; +} + +function projectSchemaNode(node, context) { + if (Array.isArray(node)) { + return node.map((entry) => projectSchemaNode(entry, context)); + } + + if (!node || typeof node !== "object") { + return node; + } + + const output = {}; + + for (const [key, value] of Object.entries(node)) { + if (CUSTOM_KEYS.has(key)) { + continue; + } + + if (key === "$ref" && typeof value === "string") { + output[key] = rewriteRef( + value, + context.sourceRel, + context.outputRel, + context.variant, + context.schemaCache + ); + continue; + } + + if (key === "properties" && value && typeof value === "object") { + const properties = {}; + const required = new Set( + Array.isArray(node.required) ? node.required : [] + ); + + for (const [propertyName, propertySchema] of Object.entries(value)) { + const requestRule = effectiveRequestRule( + propertySchema, + context.variant + ); + const omitForRequest = + context.variant !== "response" && requestRule === "omit"; + const omitForResponse = + context.variant === "response" && + propertySchema && + typeof propertySchema === "object" && + propertySchema.ucp_response === "omit"; + + if (omitForRequest || omitForResponse) { + required.delete(propertyName); + continue; + } + + if (context.variant !== "response") { + if (requestRule === "required") { + required.add(propertyName); + } else if (requestRule === "optional") { + required.delete(propertyName); + } + } + + properties[propertyName] = projectSchemaNode(propertySchema, context); + } + + output.properties = properties; + + if (required.size > 0) { + output.required = Array.from(required); + } else { + delete output.required; + } + + continue; + } + + if (key === "required") { + continue; + } + + output[key] = projectSchemaNode(value, context); + } + + return output; +} + +function titleSuffixForOutput(outputRel) { + if (outputRel.endsWith(".create_req.json")) { + return "Create Request"; + } + + if (outputRel.endsWith(".update_req.json")) { + return "Update Request"; + } + + if (outputRel.endsWith("_req.json")) { + return "Request"; + } + + if (outputRel.endsWith("_resp.json")) { + return "Response"; + } + + return null; +} + +function applyVariantTitles(node, suffix) { + if (!suffix || !node || typeof node !== "object") { + return node; + } + + if (Array.isArray(node)) { + return node.map((entry) => applyVariantTitles(entry, suffix)); + } + + const output = {}; + + for (const [key, value] of Object.entries(node)) { + if ( + key === "title" && + typeof value === "string" && + !value.endsWith(suffix) + ) { + output[key] = `${value} ${suffix}`; + continue; + } + + output[key] = applyVariantTitles(value, suffix); + } + + return output; +} + +function loadSchemaCache() { + const cache = new Map(); + + for (const fileName of fs.readdirSync(sourceTypesRoot)) { + if (!fileName.endsWith(".json")) { + continue; + } + + cache.set( + `shopping/types/${fileName}`, + readJson(path.join(sourceTypesRoot, fileName)) + ); + } + + for (const fileName of fs.readdirSync(sourceShoppingRoot)) { + if (!fileName.endsWith(".json")) { + continue; + } + + cache.set( + `shopping/${fileName}`, + readJson(path.join(sourceShoppingRoot, fileName)) + ); + } + + return cache; +} + +function writeProjectedFile( + schema, + sourceRel, + outputRel, + variant, + schemaCache +) { + let projected = projectSchemaNode(schema, { + outputRel, + schemaCache, + sourceRel, + variant, + }); + projected = applyVariantTitles(projected, titleSuffixForOutput(outputRel)); + writeJson(path.join(outputSchemasRoot, outputRel), projected); +} + +function writeCompatibilityDiscoverySchemas() { + const signingKey = { + $schema: "https://json-schema.org/draft/2020-12/schema", + title: "Signing Key", + type: "object", + required: ["kid", "kty"], + properties: { + alg: { type: "string" }, + crv: { type: "string" }, + e: { type: "string" }, + kid: { type: "string" }, + kty: { type: "string" }, + n: { type: "string" }, + use: { type: "string", enum: ["enc", "sig"] }, + x: { type: "string" }, + y: { type: "string" }, + }, + }; + + const paymentHandlerResponse = { + $schema: "https://json-schema.org/draft/2020-12/schema", + title: "Payment Handler Response", + type: "object", + required: [ + "config", + "config_schema", + "id", + "instrument_schemas", + "name", + "spec", + "version", + ], + properties: { + config: { type: "object", additionalProperties: true }, + config_schema: { type: "string" }, + id: { type: "string" }, + instrument_schemas: { + type: "array", + items: { type: "string" }, + }, + name: { type: "string" }, + spec: { type: "string" }, + version: { type: "string" }, + }, + }; + + const capabilityDiscovery = { + $schema: "https://json-schema.org/draft/2020-12/schema", + title: "Capability Discovery", + type: "object", + required: ["name", "schema", "spec", "version"], + properties: { + config: { type: "object", additionalProperties: true }, + extends: { type: "string" }, + name: { type: "string" }, + schema: { type: "string" }, + spec: { type: "string" }, + version: { type: "string" }, + }, + }; + + const capabilityResponse = { + $schema: "https://json-schema.org/draft/2020-12/schema", + title: "Capability Response", + type: "object", + required: ["name", "version"], + properties: { + config: { type: "object", additionalProperties: true }, + extends: { type: "string" }, + name: { type: "string" }, + schema: { type: "string" }, + spec: { type: "string" }, + version: { type: "string" }, + }, + }; + + const ucpService = { + $schema: "https://json-schema.org/draft/2020-12/schema", + title: "UCP Service", + type: "object", + required: ["spec", "version"], + properties: { + a2a: { + type: "object", + required: ["endpoint"], + properties: { endpoint: { type: "string" } }, + }, + embedded: { + type: "object", + required: ["schema"], + properties: { schema: { type: "string" } }, + }, + mcp: { + type: "object", + required: ["endpoint", "schema"], + properties: { + endpoint: { type: "string" }, + schema: { type: "string" }, + }, + }, + rest: { + type: "object", + required: ["endpoint", "schema"], + properties: { + endpoint: { type: "string" }, + schema: { type: "string" }, + }, + }, + spec: { type: "string" }, + version: { type: "string" }, + }, + }; + + const ucpResponse = { + $schema: "https://json-schema.org/draft/2020-12/schema", + title: "UCP Response", + type: "object", + required: ["capabilities", "version"], + properties: { + capabilities: { + type: "array", + items: { $ref: "capability_response.json" }, + }, + version: { type: "string" }, + }, + }; + + const ucpDiscoveryProfile = { + $schema: "https://json-schema.org/draft/2020-12/schema", + title: "UCP Discovery Profile", + type: "object", + required: ["ucp"], + properties: { + payment: { + type: "object", + properties: { + handlers: { + type: "array", + items: { $ref: "payment_handler_resp.json" }, + }, + }, + }, + signing_keys: { + type: "array", + items: { $ref: "signing_key.json" }, + }, + ucp: { + type: "object", + required: ["capabilities", "services", "version"], + properties: { + capabilities: { + type: "array", + items: { $ref: "capability.json" }, + }, + services: { + type: "object", + additionalProperties: { $ref: "ucp_service.json" }, + }, + version: { type: "string" }, + }, + }, + }, + }; + + writeJson(path.join(outputDiscoveryRoot, "signing_key.json"), signingKey); + writeJson( + path.join(outputDiscoveryRoot, "payment_handler_resp.json"), + paymentHandlerResponse + ); + writeJson( + path.join(outputDiscoveryRoot, "capability.json"), + capabilityDiscovery + ); + writeJson( + path.join(outputDiscoveryRoot, "capability_response.json"), + capabilityResponse + ); + writeJson(path.join(outputDiscoveryRoot, "ucp_service.json"), ucpService); + writeJson(path.join(outputDiscoveryRoot, "ucp_response.json"), ucpResponse); + writeJson( + path.join(outputDiscoveryRoot, "ucp_discovery_profile.json"), + ucpDiscoveryProfile + ); +} + +function writeCompatibilityCoreSchemas() { + const ucpSchema = { + $schema: "https://json-schema.org/draft/2020-12/schema", + $defs: { + response_checkout_schema: { $ref: "../discovery/ucp_response.json" }, + response_order_schema: { $ref: "../discovery/ucp_response.json" }, + response_cart_schema: { $ref: "../discovery/ucp_response.json" }, + }, + }; + + writeJson(path.join(outputSchemasRoot, "ucp.json"), ucpSchema); +} + +function writeCompatibilityPaymentDataSchema() { + const paymentDataSchema = { + $schema: "https://json-schema.org/draft/2020-12/schema", + title: "Payment Data", + type: "object", + required: ["payment_data"], + properties: { + payment_data: { + $ref: "types/payment_instrument.json", + }, + }, + }; + + writeJson( + path.join(outputShoppingRoot, "payment_data.json"), + paymentDataSchema + ); +} + +function writeProjectedTypeSchemas(schemaCache) { + for (const [sourceRel, schema] of schemaCache.entries()) { + if (!sourceRel.startsWith("shopping/types/")) { + continue; + } + + const baseName = path.posix.basename(sourceRel, ".json"); + const strategy = splitStrategyForSchema(baseName, schema); + + if (strategy === "unified") { + writeProjectedFile( + schema, + sourceRel, + `shopping/types/${baseName}.json`, + "response", + schemaCache + ); + continue; + } + + if (strategy === "shared_request") { + writeProjectedFile( + schema, + sourceRel, + `shopping/types/${baseName}_req.json`, + "create", + schemaCache + ); + writeProjectedFile( + schema, + sourceRel, + `shopping/types/${baseName}_resp.json`, + "response", + schemaCache + ); + continue; + } + + writeProjectedFile( + schema, + sourceRel, + `shopping/types/${baseName}.create_req.json`, + "create", + schemaCache + ); + writeProjectedFile( + schema, + sourceRel, + `shopping/types/${baseName}.update_req.json`, + "update", + schemaCache + ); + writeProjectedFile( + schema, + sourceRel, + `shopping/types/${baseName}_resp.json`, + "response", + schemaCache + ); + } +} + +function renameExtensionCheckoutDef(projectedSchema) { + const schema = clone(projectedSchema); + if (!schema.$defs) { + return schema; + } + + for (const key of Object.keys(schema.$defs)) { + if (key.endsWith(".checkout")) { + schema.$defs.checkout = schema.$defs[key]; + delete schema.$defs[key]; + break; + } + } + + return schema; +} + +function writeProjectedTopLevelSchemas(schemaCache) { + for (const [sourceRel, variants] of Object.entries(topLevelVariantMap)) { + const sourceSchema = schemaCache.get(sourceRel); + + for (const [variant, outputRel] of Object.entries(variants)) { + let projected = projectSchemaNode(sourceSchema, { + outputRel, + schemaCache, + sourceRel, + variant, + }); + + projected = applyVariantTitles( + projected, + titleSuffixForOutput(outputRel) + ); + + if ( + sourceRel === "shopping/buyer_consent.json" || + sourceRel === "shopping/discount.json" || + sourceRel === "shopping/fulfillment.json" + ) { + projected = renameExtensionCheckoutDef(projected); + } + + writeJson(path.join(outputSchemasRoot, outputRel), projected); + } + } +} + +function writeCompatibilityAp2Schema(schemaCache) { + const sourceRel = "shopping/ap2_mandate.json"; + const sourceSchema = schemaCache.get(sourceRel); + + const responseProjection = projectSchemaNode(sourceSchema, { + outputRel: "shopping/ap2_mandate.json", + schemaCache, + sourceRel, + variant: "response", + }); + + const ap2WithCheckoutMandate = sourceSchema?.$defs + ?.ap2_with_checkout_mandate ?? { + type: "object", + properties: { + checkout_mandate: { type: "string" }, + }, + }; + + const completeRequestWithAp2 = { + title: "Complete Checkout Request With AP2", + type: "object", + properties: { + ap2: projectSchemaNode(ap2WithCheckoutMandate, { + outputRel: "shopping/ap2_mandate.json", + schemaCache, + sourceRel, + variant: "complete", + }), + }, + }; + + const checkoutResponseWithAp2 = renameExtensionCheckoutDef(responseProjection) + .$defs?.checkout ?? { + title: "Checkout with AP2 Mandate", + type: "object", + }; + + const ap2Schema = { + $schema: "https://json-schema.org/draft/2020-12/schema", + title: "AP2 Mandate Extension", + $defs: { + checkout_mandate: projectSchemaNode( + sourceSchema?.$defs?.checkout_mandate, + { + outputRel: "shopping/ap2_mandate.json", + schemaCache, + sourceRel, + variant: "response", + } + ), + merchant_authorization: projectSchemaNode( + sourceSchema?.$defs?.merchant_authorization, + { + outputRel: "shopping/ap2_mandate.json", + schemaCache, + sourceRel, + variant: "response", + } + ), + ap2_with_checkout_mandate: projectSchemaNode(ap2WithCheckoutMandate, { + outputRel: "shopping/ap2_mandate.json", + schemaCache, + sourceRel, + variant: "complete", + }), + ap2_with_merchant_authorization: projectSchemaNode( + sourceSchema?.$defs?.ap2_with_merchant_authorization, + { + outputRel: "shopping/ap2_mandate.json", + schemaCache, + sourceRel, + variant: "response", + } + ), + complete_request_with_ap2: completeRequestWithAp2, + checkout_response_with_ap2: checkoutResponseWithAp2, + }, + }; + + writeJson(path.join(outputShoppingRoot, "ap2_mandate.json"), ap2Schema); +} + +const schemaCache = loadSchemaCache(); + +writeCompatibilityDiscoverySchemas(); +writeCompatibilityCoreSchemas(); +writeProjectedTypeSchemas(schemaCache); +writeProjectedTopLevelSchemas(schemaCache); +writeCompatibilityPaymentDataSchema(); +writeCompatibilityAp2Schema(schemaCache); diff --git a/src/spec_generated.ts b/src/spec_generated.ts index 7fde596..b914fb1 100644 --- a/src/spec_generated.ts +++ b/src/spec_generated.ts @@ -1,1302 +1,874 @@ import * as z from "zod"; -// Key usage. Should be 'sig' for signing keys. -export const UseSchema = z.enum(["enc", "sig"]); -export type Use = z.infer; - -// The type of card number. Network tokens are preferred with fallback to FPAN. -// See PCI Scope for more details. - -export const CardNumberTypeSchema = z.enum(["dpan", "fpan", "network_token"]); -export type CardNumberType = z.infer; - -// A URI pointing to a schema definition (e.g., JSON Schema) used to validate -// the structure of the instrument object. - -export const CardPaymentInstrumentTypeSchema = z.enum(["card"]); -export type CardPaymentInstrumentType = z.infer< - typeof CardPaymentInstrumentTypeSchema ->; - -// Type of total categorization. - -export const TotalResponseTypeSchema = z.enum([ - "discount", - "fee", - "fulfillment", - "items_discount", - "subtotal", - "tax", - "total", +export const UseSchema = z.enum([ + "enc", + "sig", ]); -export type TotalResponseType = z.infer; +export type Use = z.infer; // Content format, default = plain. -export const ContentTypeSchema = z.enum(["markdown", "plain"]); +export const ContentTypeSchema = z.enum([ + "markdown", + "plain", +]); export type ContentType = z.infer; -// Declares who resolves this error. 'recoverable': agent can fix 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 (checkout complete). Errors with -// 'requires_*' severity contribute to 'status: requires_escalation'. +// 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'. export const SeveritySchema = z.enum([ - "recoverable", - "requires_buyer_input", - "requires_buyer_review", + "recoverable", + "requires_buyer_input", + "requires_buyer_review", + "unrecoverable", ]); export type Severity = z.infer; -export const MessageTypeSchema = z.enum(["error", "info", "warning"]); + +export const MessageTypeSchema = z.enum([ + "error", + "info", + "warning", +]); export type MessageType = z.infer; -// Checkout state indicating the current phase and required action. See Checkout -// Status lifecycle documentation for state transition details. +// Checkout state indicating the current phase and required action. See Checkout Status +// lifecycle documentation for state transition details. export const CheckoutResponseStatusSchema = z.enum([ - "canceled", - "complete_in_progress", - "completed", - "incomplete", - "ready_for_complete", - "requires_escalation", + "canceled", + "complete_in_progress", + "completed", + "incomplete", + "ready_for_complete", + "requires_escalation", ]); -export type CheckoutResponseStatus = z.infer< - typeof CheckoutResponseStatusSchema ->; +export type CheckoutResponseStatus = z.infer; // Adjustment status. export const AdjustmentStatusSchema = z.enum([ - "completed", - "failed", - "pending", + "completed", + "failed", + "pending", ]); export type AdjustmentStatus = z.infer; // Delivery method type (shipping, pickup, digital). -export const MethodTypeSchema = z.enum(["digital", "pickup", "shipping"]); -export type MethodType = z.infer; +export const MethodTypeEnumSchema = z.enum([ + "digital", + "pickup", + "shipping", +]); +export type MethodTypeEnum = z.infer; // Derived status: fulfilled if quantity.fulfilled == quantity.total, partial if // quantity.fulfilled > 0, otherwise processing. export const LineItemStatusSchema = z.enum([ - "fulfilled", - "partial", - "processing", + "fulfilled", + "partial", + "processing", ]); export type LineItemStatus = z.infer; -// Fulfillment method type this availability applies to. -// -// Fulfillment method type. - -export const TypeElementSchema = z.enum(["pickup", "shipping"]); -export type TypeElement = z.infer; - -export const MessageErrorTypeSchema = z.enum(["error"]); -export type MessageErrorType = z.infer; - -export const MessageInfoTypeSchema = z.enum(["info"]); -export type MessageInfoType = z.infer; - -export const MessageWarningTypeSchema = z.enum(["warning"]); -export type MessageWarningType = z.infer; - // Allocation method. 'each' = applied independently per item. 'across' = split // proportionally by value. -export const MethodSchema = z.enum(["across", "each"]); +export const MethodSchema = z.enum([ + "across", + "each", +]); export type Method = z.infer; +// Fulfillment method type. +// +// Fulfillment method type this availability applies to. + +export const MethodTypeSchema = z.enum([ + "pickup", + "shipping", +]); +export type MethodType = z.infer; + export const PaymentHandlerResponseSchema = z.object({ - config: z.record(z.string(), z.any()), - config_schema: z.string(), - id: z.string(), - instrument_schemas: z.array(z.string()), - name: z.string(), - spec: z.string(), - version: z.string(), -}); -export type PaymentHandlerResponse = z.infer< - typeof PaymentHandlerResponseSchema ->; + "config": z.record(z.string(), z.any()), + "config_schema": z.string(), + "id": z.string(), + "instrument_schemas": z.array(z.string()), + "name": z.string(), + "spec": z.string(), + "version": z.string(), +}); +export type PaymentHandlerResponse = z.infer; export const SigningKeySchema = z.object({ - alg: z.string().optional(), - crv: z.string().optional(), - e: z.string().optional(), - kid: z.string(), - kty: z.string(), - n: z.string().optional(), - use: UseSchema.optional(), - x: z.string().optional(), - y: z.string().optional(), + "alg": z.string().optional(), + "crv": z.string().optional(), + "e": z.string().optional(), + "kid": z.string(), + "kty": z.string(), + "n": z.string().optional(), + "use": UseSchema.optional(), + "x": z.string().optional(), + "y": z.string().optional(), }); export type SigningKey = z.infer; export const CapabilityDiscoverySchema = z.object({ - config: z.record(z.string(), z.any()).optional(), - extends: z.string().optional(), - name: z.string(), - schema: z.string(), - spec: z.string(), - version: z.string(), + "config": z.record(z.string(), z.any()).optional(), + "extends": z.string().optional(), + "name": z.string(), + "schema": z.string(), + "spec": z.string(), + "version": z.string(), }); export type CapabilityDiscovery = z.infer; export const A2ASchema = z.object({ - endpoint: z.string(), + "endpoint": z.string(), }); export type A2A = z.infer; export const EmbeddedSchema = z.object({ - schema: z.string(), + "schema": z.string(), }); export type Embedded = z.infer; -export const McpSchema = z.object({ - endpoint: z.string(), - schema: z.string(), +export const SchemaEndpointSchema = z.object({ + "endpoint": z.string(), + "schema": z.string(), }); -export type Mcp = z.infer; +export type SchemaEndpoint = z.infer; +export const McpSchema = SchemaEndpointSchema; +export type Mcp = SchemaEndpoint; +export const RestSchema = SchemaEndpointSchema; +export type Rest = SchemaEndpoint; -export const RestSchema = z.object({ - endpoint: z.string(), - schema: z.string(), -}); -export type Rest = z.infer; -export const BuyerClassSchema = z.object({ - email: z.string().optional(), - first_name: z.string().optional(), - full_name: z.string().optional(), - last_name: z.string().optional(), - phone_number: z.string().optional(), -}); -export type BuyerClass = z.infer; -export const ItemClassSchema = z.object({ - id: z.string(), -}); -export type ItemClass = z.infer; -export const BillingAddressClassSchema = z.object({ - address_country: z.string().optional(), - address_locality: z.string().optional(), - address_region: z.string().optional(), - extended_address: z.string().optional(), - first_name: z.string().optional(), - full_name: z.string().optional(), - last_name: z.string().optional(), - phone_number: z.string().optional(), - postal_code: z.string().optional(), - street_address: z.string().optional(), +export const BuyerSchema = z.object({ + "email": z.string().optional(), + "first_name": z.string().optional(), + "last_name": z.string().optional(), + "phone_number": z.string().optional(), }); -export type BillingAddressClass = z.infer; +export type Buyer = z.infer; -export const PaymentCredentialSchema = z.object({ - type: z.string(), - card_number_type: CardNumberTypeSchema.optional(), - cryptogram: z.string().optional(), - cvc: z.string().optional(), - eci_value: z.string().optional(), - expiry_month: z.number().optional(), - expiry_year: z.number().optional(), - name: z.string().optional(), - number: z.string().optional(), +export const ContextSchema = z.object({ + "address_country": z.string().optional(), + "address_region": z.string().optional(), + "currency": z.string().optional(), + "eligibility": z.array(z.string()).optional(), + "intent": z.string().optional(), + "language": z.string().optional(), + "postal_code": z.string().optional(), }); -export type PaymentCredential = z.infer; +export type Context = z.infer; -export const ItemResponseSchema = z.object({ - id: z.string(), - image_url: z.string().optional(), - price: z.number(), - title: z.string(), +export const ItemReferenceSchema = z.object({ + "id": z.string(), }); -export type ItemResponse = z.infer; +export type ItemReference = z.infer; +export const ItemCreateRequestSchema = ItemReferenceSchema; +export type ItemCreateRequest = ItemReference; +export const ItemUpdateRequestSchema = ItemReferenceSchema; +export type ItemUpdateRequest = ItemReference; -export const TotalResponseSchema = z.object({ - amount: z.number(), - display_text: z.string().optional(), - type: TotalResponseTypeSchema, -}); -export type TotalResponse = z.infer; -export const LinkElementSchema = z.object({ - title: z.string().optional(), - type: z.string(), - url: z.string(), +export const PostalAddressSchema = z.object({ + "address_country": z.string().optional(), + "address_locality": z.string().optional(), + "address_region": z.string().optional(), + "extended_address": z.string().optional(), + "first_name": z.string().optional(), + "last_name": z.string().optional(), + "phone_number": z.string().optional(), + "postal_code": z.string().optional(), + "street_address": z.string().optional(), }); -export type LinkElement = z.infer; +export type PostalAddress = z.infer; -export const MessageElementSchema = z.object({ - code: z.string().optional(), - content: z.string(), - content_type: ContentTypeSchema.optional(), - path: z.string().optional(), - severity: SeveritySchema.optional(), - type: MessageTypeSchema, +export const PaymentCredentialSchema = z.object({ + "type": z.string(), }); -export type MessageElement = z.infer; +export type PaymentCredential = z.infer; -export const OrderClassSchema = z.object({ - id: z.string(), - permalink_url: z.string(), +export const SignalsSchema = z.object({ + "dev.ucp.buyer_ip": z.string().optional(), + "dev.ucp.user_agent": z.string().optional(), }); -export type OrderClass = z.infer; +export type Signals = z.infer; -export const CapabilityResponseSchema = z.object({ - config: z.record(z.string(), z.any()).optional(), - extends: z.string().optional(), - name: z.string(), - schema: z.string().optional(), - spec: z.string().optional(), - version: z.string(), -}); -export type CapabilityResponse = z.infer; -export const LineItemItemSchema = z.object({ - id: z.string(), -}); -export type LineItemItem = z.infer; -export const AdjustmentLineItemSchema = z.object({ - id: z.string(), - quantity: z.number(), +export const ItemResponseSchema = z.object({ + "id": z.string(), + "image_url": z.string().optional(), + "price": z.number(), + "title": z.string(), }); -export type AdjustmentLineItem = z.infer; +export type ItemResponse = z.infer; -export const EventLineItemSchema = z.object({ - id: z.string(), - quantity: z.number(), +export const TotalResponseSchema = z.object({ + "amount": z.number(), + "display_text": z.string().optional(), + "type": z.string(), }); -export type EventLineItem = z.infer; +export type TotalResponse = z.infer; -export const ExpectationLineItemSchema = z.object({ - id: z.string(), - quantity: z.number(), +export const LinkSchema = z.object({ + "title": z.string().optional(), + "type": z.string(), + "url": z.string(), }); -export type ExpectationLineItem = z.infer; +export type Link = z.infer; -export const LineItemQuantitySchema = z.object({ - fulfilled: z.number(), - total: z.number(), +export const MessageSchema = z.object({ + "code": z.string().optional(), + "content": z.string(), + "content_type": ContentTypeSchema.optional(), + "path": z.string().optional(), + "severity": SeveritySchema.optional(), + "type": MessageTypeSchema, + "image_url": z.string().optional(), + "presentation": z.string().optional(), + "url": z.string().optional(), }); -export type LineItemQuantity = z.infer; +export type Message = z.infer; -export const UcpOrderResponseSchema = z.object({ - capabilities: z.array(CapabilityResponseSchema), - version: z.string(), +export const OrderConfirmationSchema = z.object({ + "id": z.string(), + "permalink_url": z.string(), }); -export type UcpOrderResponse = z.infer; +export type OrderConfirmation = z.infer; -export const PaymentAccountInfoSchema = z.object({ - payment_account_reference: z.string().optional(), +export const LineSchema = z.object({ + "amount": z.number(), + "display_text": z.string(), }); -export type PaymentAccountInfo = z.infer; +export type Line = z.infer; -export const AdjustmentLineItemClassSchema = z.object({ - id: z.string(), - quantity: z.number(), +export const CapabilityResponseSchema = z.object({ + "config": z.record(z.string(), z.any()).optional(), + "extends": z.string().optional(), + "name": z.string(), + "schema": z.string().optional(), + "spec": z.string().optional(), + "version": z.string(), }); -export type AdjustmentLineItemClass = z.infer< - typeof AdjustmentLineItemClassSchema ->; +export type CapabilityResponse = z.infer; -export const IdentityClassSchema = z.object({ - access_token: z.string(), +export const LineItemQuantityRefSchema = z.object({ + "id": z.string(), + "quantity": z.number(), }); -export type IdentityClass = z.infer; +export type LineItemQuantityRef = z.infer; +export const AdjustmentLineItemSchema = LineItemQuantityRefSchema; +export type AdjustmentLineItem = LineItemQuantityRef; +export const EventLineItemSchema = LineItemQuantityRefSchema; +export type EventLineItem = LineItemQuantityRef; +export const ExpectationLineItemSchema = LineItemQuantityRefSchema; +export type ExpectationLineItem = LineItemQuantityRef; -export const BuyerSchema = z.object({ - email: z.string().optional(), - first_name: z.string().optional(), - full_name: z.string().optional(), - last_name: z.string().optional(), - phone_number: z.string().optional(), -}); -export type Buyer = z.infer; -export const CardCredentialSchema = z.object({ - card_number_type: CardNumberTypeSchema, - cryptogram: z.string().optional(), - cvc: z.string().optional(), - eci_value: z.string().optional(), - expiry_month: z.number().optional(), - expiry_year: z.number().optional(), - name: z.string().optional(), - number: z.string().optional(), - type: CardPaymentInstrumentTypeSchema, -}); -export type CardCredential = z.infer; - -export const CardPaymentInstrumentSchema = z.object({ - billing_address: BillingAddressClassSchema.optional(), - credential: PaymentCredentialSchema.optional(), - handler_id: z.string(), - id: z.string(), - type: CardPaymentInstrumentTypeSchema, - brand: z.string(), - expiry_month: z.number().optional(), - expiry_year: z.number().optional(), - last_digits: z.string(), - rich_card_art: z.string().optional(), - rich_text_description: z.string().optional(), -}); -export type CardPaymentInstrument = z.infer; - -export const ExpectationLineItemClassSchema = z.object({ - id: z.string(), - quantity: z.number(), -}); -export type ExpectationLineItemClass = z.infer< - typeof ExpectationLineItemClassSchema ->; -export const FulfillmentDestinationRequestSchema = z.object({ - address_country: z.string().optional(), - address_locality: z.string().optional(), - address_region: z.string().optional(), - extended_address: z.string().optional(), - first_name: z.string().optional(), - full_name: z.string().optional(), - last_name: z.string().optional(), - phone_number: z.string().optional(), - postal_code: z.string().optional(), - street_address: z.string().optional(), - id: z.string().optional(), - address: BillingAddressClassSchema.optional(), - name: z.string().optional(), -}); -export type FulfillmentDestinationRequest = z.infer< - typeof FulfillmentDestinationRequestSchema ->; - -export const FulfillmentEventLineItemSchema = z.object({ - id: z.string(), - quantity: z.number(), -}); -export type FulfillmentEventLineItem = z.infer< - typeof FulfillmentEventLineItemSchema ->; -export const FulfillmentGroupCreateRequestSchema = z.object({ - selected_option_id: z.union([z.null(), z.string()]).optional(), -}); -export type FulfillmentGroupCreateRequest = z.infer< - typeof FulfillmentGroupCreateRequestSchema ->; -export const FulfillmentGroupUpdateRequestSchema = z.object({ - id: z.string(), - selected_option_id: z.union([z.null(), z.string()]).optional(), -}); -export type FulfillmentGroupUpdateRequest = z.infer< - typeof FulfillmentGroupUpdateRequestSchema ->; -export const FulfillmentDestinationRequestElementSchema = z.object({ - address_country: z.string().optional(), - address_locality: z.string().optional(), - address_region: z.string().optional(), - extended_address: z.string().optional(), - first_name: z.string().optional(), - full_name: z.string().optional(), - last_name: z.string().optional(), - phone_number: z.string().optional(), - postal_code: z.string().optional(), - street_address: z.string().optional(), - id: z.string().optional(), - address: BillingAddressClassSchema.optional(), - name: z.string().optional(), +export const QuantitySchema = z.object({ + "fulfilled": z.number(), + "total": z.number(), }); -export type FulfillmentDestinationRequestElement = z.infer< - typeof FulfillmentDestinationRequestElementSchema ->; +export type Quantity = z.infer; -export const GroupElementSchema = z.object({ - selected_option_id: z.union([z.null(), z.string()]).optional(), +export const PaymentInstrumentSchema = z.object({ + "billing_address": PostalAddressSchema.optional(), + "credential": PaymentCredentialSchema.optional(), + "display": z.record(z.string(), z.any()).optional(), + "handler_id": z.string(), + "id": z.string(), + "type": z.string(), }); -export type GroupElement = z.infer; +export type PaymentInstrument = z.infer; -export const GroupClassSchema = z.object({ - id: z.string(), - selected_option_id: z.union([z.null(), z.string()]).optional(), +export const CompleteCheckoutRequestWithAp2Ap2Schema = z.object({ + "checkout_mandate": z.string(), }); -export type GroupClass = z.infer; +export type CompleteCheckoutRequestWithAp2Ap2 = z.infer; -export const ItemCreateRequestSchema = z.object({ - id: z.string(), +export const CheckoutWithAp2MandateAp2Schema = z.object({ + "merchant_authorization": z.string().optional(), + "checkout_mandate": z.string(), }); -export type ItemCreateRequest = z.infer; +export type CheckoutWithAp2MandateAp2 = z.infer; -export const ItemUpdateRequestSchema = z.object({ - id: z.string(), +export const ConsentSchema = z.object({ + "analytics": z.boolean().optional(), + "marketing": z.boolean().optional(), + "preferences": z.boolean().optional(), + "sale_of_data": z.boolean().optional(), }); -export type ItemUpdateRequest = z.infer; +export type Consent = z.infer; +export const FluffyConsentSchema = ConsentSchema; +export type FluffyConsent = Consent; +export const PurpleConsentSchema = ConsentSchema; +export type PurpleConsent = Consent; +export const TentacledConsentSchema = ConsentSchema; +export type TentacledConsent = Consent; -export const LineItemCreateRequestSchema = z.object({ - item: ItemClassSchema, - quantity: z.number(), -}); -export type LineItemCreateRequest = z.infer; -export const LineItemUpdateRequestSchema = z.object({ - id: z.string().optional(), - item: LineItemItemSchema, - parent_id: z.string().optional(), - quantity: z.number(), -}); -export type LineItemUpdateRequest = z.infer; -export const LinkSchema = z.object({ - title: z.string().optional(), - type: z.string(), - url: z.string(), -}); -export type Link = z.infer; -export const AllowsMultiDestinationSchema = z.object({ - pickup: z.boolean().optional(), - shipping: z.boolean().optional(), -}); -export type AllowsMultiDestination = z.infer< - typeof AllowsMultiDestinationSchema ->; -export const MessageErrorSchema = z.object({ - code: z.string(), - content: z.string(), - content_type: ContentTypeSchema.optional(), - path: z.string().optional(), - severity: SeveritySchema, - type: MessageErrorTypeSchema, -}); -export type MessageError = z.infer; - -export const MessageInfoSchema = z.object({ - code: z.string().optional(), - content: z.string(), - content_type: ContentTypeSchema.optional(), - path: z.string().optional(), - type: MessageInfoTypeSchema, -}); -export type MessageInfo = z.infer; - -export const MessageSchema = z.object({ - code: z.string().optional(), - content: z.string(), - content_type: ContentTypeSchema.optional(), - path: z.string().optional(), - severity: SeveritySchema.optional(), - type: MessageTypeSchema, -}); -export type Message = z.infer; -export const MessageWarningSchema = z.object({ - code: z.string(), - content: z.string(), - content_type: ContentTypeSchema.optional(), - path: z.string().optional(), - type: MessageWarningTypeSchema, -}); -export type MessageWarning = z.infer; - -export const OrderConfirmationSchema = z.object({ - id: z.string(), - permalink_url: z.string(), +export const AllocationSchema = z.object({ + "amount": z.number(), + "path": z.string(), }); -export type OrderConfirmation = z.infer; +export type Allocation = z.infer; +export const AllocationClassSchema = AllocationSchema; +export type AllocationClass = Allocation; +export const AllocationElementSchema = AllocationSchema; +export type AllocationElement = Allocation; +export const AppliedAllocationSchema = AllocationSchema; +export type AppliedAllocation = Allocation; -export const OrderLineItemQuantitySchema = z.object({ - fulfilled: z.number(), - total: z.number(), -}); -export type OrderLineItemQuantity = z.infer; -export const PaymentIdentitySchema = z.object({ - access_token: z.string(), -}); -export type PaymentIdentity = z.infer; -export const PaymentInstrumentBaseSchema = z.object({ - billing_address: BillingAddressClassSchema.optional(), - credential: PaymentCredentialSchema.optional(), - handler_id: z.string(), - id: z.string(), - type: z.string(), -}); -export type PaymentInstrumentBase = z.infer; -export const PlatformFulfillmentConfigSchema = z.object({ - supports_multi_group: z.boolean().optional(), -}); -export type PlatformFulfillmentConfig = z.infer< - typeof PlatformFulfillmentConfigSchema ->; -export const PostalAddressSchema = z.object({ - address_country: z.string().optional(), - address_locality: z.string().optional(), - address_region: z.string().optional(), - extended_address: z.string().optional(), - first_name: z.string().optional(), - full_name: z.string().optional(), - last_name: z.string().optional(), - phone_number: z.string().optional(), - postal_code: z.string().optional(), - street_address: z.string().optional(), -}); -export type PostalAddress = z.infer; -export const RetailLocationRequestSchema = z.object({ - address: BillingAddressClassSchema.optional(), - name: z.string(), -}); -export type RetailLocationRequest = z.infer; - -export const RetailLocationResponseSchema = z.object({ - address: BillingAddressClassSchema.optional(), - id: z.string(), - name: z.string(), -}); -export type RetailLocationResponse = z.infer< - typeof RetailLocationResponseSchema ->; - -export const ShippingDestinationRequestSchema = z.object({ - address_country: z.string().optional(), - address_locality: z.string().optional(), - address_region: z.string().optional(), - extended_address: z.string().optional(), - first_name: z.string().optional(), - full_name: z.string().optional(), - last_name: z.string().optional(), - phone_number: z.string().optional(), - postal_code: z.string().optional(), - street_address: z.string().optional(), - id: z.string().optional(), -}); -export type ShippingDestinationRequest = z.infer< - typeof ShippingDestinationRequestSchema ->; - -export const ShippingDestinationResponseSchema = z.object({ - address_country: z.string().optional(), - address_locality: z.string().optional(), - address_region: z.string().optional(), - extended_address: z.string().optional(), - first_name: z.string().optional(), - full_name: z.string().optional(), - last_name: z.string().optional(), - phone_number: z.string().optional(), - postal_code: z.string().optional(), - street_address: z.string().optional(), - id: z.string(), -}); -export type ShippingDestinationResponse = z.infer< - typeof ShippingDestinationResponseSchema ->; - -export const TokenCredentialCreateRequestSchema = z.object({ - token: z.string(), - type: z.string(), -}); -export type TokenCredentialCreateRequest = z.infer< - typeof TokenCredentialCreateRequestSchema ->; - -export const TokenCredentialResponseSchema = z.object({ - type: z.string(), -}); -export type TokenCredentialResponse = z.infer< - typeof TokenCredentialResponseSchema ->; - -export const TokenCredentialUpdateRequestSchema = z.object({ - token: z.string(), - type: z.string(), -}); -export type TokenCredentialUpdateRequest = z.infer< - typeof TokenCredentialUpdateRequestSchema ->; - -export const Ap2CompleteRequestObjectSchema = z.object({ - checkout_mandate: z.string(), -}); -export type Ap2CompleteRequestObject = z.infer< - typeof Ap2CompleteRequestObjectSchema ->; - -export const Ap2CheckoutResponseObjectSchema = z.object({ - merchant_authorization: z.string(), -}); -export type Ap2CheckoutResponseObject = z.infer< - typeof Ap2CheckoutResponseObjectSchema ->; - -export const PurpleConsentSchema = z.object({ - analytics: z.boolean().optional(), - marketing: z.boolean().optional(), - preferences: z.boolean().optional(), - sale_of_data: z.boolean().optional(), -}); -export type PurpleConsent = z.infer; - -export const FluffyConsentSchema = z.object({ - analytics: z.boolean().optional(), - marketing: z.boolean().optional(), - preferences: z.boolean().optional(), - sale_of_data: z.boolean().optional(), -}); -export type FluffyConsent = z.infer; - -export const TentacledConsentSchema = z.object({ - analytics: z.boolean().optional(), - marketing: z.boolean().optional(), - preferences: z.boolean().optional(), - sale_of_data: z.boolean().optional(), -}); -export type TentacledConsent = z.infer; - -export const AllocationElementSchema = z.object({ - amount: z.number(), - path: z.string(), -}); -export type AllocationElement = z.infer; - -export const AllocationClassSchema = z.object({ - amount: z.number(), - path: z.string(), -}); -export type AllocationClass = z.infer; - -export const AppliedAllocationSchema = z.object({ - amount: z.number(), - path: z.string(), -}); -export type AppliedAllocation = z.infer; +export const FulfillmentDestinationRequestSchema = z.object({ + "address_country": z.string().optional(), + "address_locality": z.string().optional(), + "address_region": z.string().optional(), + "extended_address": z.string().optional(), + "first_name": z.string().optional(), + "last_name": z.string().optional(), + "phone_number": z.string().optional(), + "postal_code": z.string().optional(), + "street_address": z.string().optional(), + "id": z.string().optional(), + "address": PostalAddressSchema.optional(), + "name": z.string().optional(), +}); +export type FulfillmentDestinationRequest = z.infer; -export const MethodElementSchema = z.object({ - destinations: z.array(FulfillmentDestinationRequestElementSchema).optional(), - groups: z.array(GroupElementSchema).optional(), - line_item_ids: z.array(z.string()).optional(), - selected_destination_id: z.union([z.null(), z.string()]).optional(), - type: TypeElementSchema, +export const FulfillmentGroupCreateRequestSchema = z.object({ + "selected_option_id": z.union([z.null(), z.string()]).optional(), }); -export type MethodElement = z.infer; +export type FulfillmentGroupCreateRequest = z.infer; export const FulfillmentAvailableMethodResponseSchema = z.object({ - description: z.string().optional(), - fulfillable_on: z.union([z.null(), z.string()]).optional(), - line_item_ids: z.array(z.string()), - type: TypeElementSchema, + "description": z.string().optional(), + "fulfillable_on": z.union([z.null(), z.string()]).optional(), + "line_item_ids": z.array(z.string()), + "type": MethodTypeSchema, }); -export type FulfillmentAvailableMethodResponse = z.infer< - typeof FulfillmentAvailableMethodResponseSchema ->; +export type FulfillmentAvailableMethodResponse = z.infer; export const FulfillmentDestinationResponseSchema = z.object({ - address_country: z.string().optional(), - address_locality: z.string().optional(), - address_region: z.string().optional(), - extended_address: z.string().optional(), - first_name: z.string().optional(), - full_name: z.string().optional(), - last_name: z.string().optional(), - phone_number: z.string().optional(), - postal_code: z.string().optional(), - street_address: z.string().optional(), - id: z.string(), - address: BillingAddressClassSchema.optional(), - name: z.string().optional(), -}); -export type FulfillmentDestinationResponse = z.infer< - typeof FulfillmentDestinationResponseSchema ->; + "address_country": z.string().optional(), + "address_locality": z.string().optional(), + "address_region": z.string().optional(), + "extended_address": z.string().optional(), + "first_name": z.string().optional(), + "last_name": z.string().optional(), + "phone_number": z.string().optional(), + "postal_code": z.string().optional(), + "street_address": z.string().optional(), + "id": z.string(), + "address": PostalAddressSchema.optional(), + "name": z.string().optional(), +}); +export type FulfillmentDestinationResponse = z.infer; export const FulfillmentOptionResponseSchema = z.object({ - carrier: z.string().optional(), - description: z.string().optional(), - earliest_fulfillment_time: z.coerce.date().optional(), - id: z.string(), - latest_fulfillment_time: z.coerce.date().optional(), - title: z.string(), - totals: z.array(TotalResponseSchema), -}); -export type FulfillmentOptionResponse = z.infer< - typeof FulfillmentOptionResponseSchema ->; + "carrier": z.string().optional(), + "description": z.string().optional(), + "earliest_fulfillment_time": z.coerce.date().optional(), + "id": z.string(), + "latest_fulfillment_time": z.coerce.date().optional(), + "title": z.string(), + "totals": z.array(TotalResponseSchema), +}); +export type FulfillmentOptionResponse = z.infer; export const PaymentSchema = z.object({ - handlers: z.array(PaymentHandlerResponseSchema).optional(), + "handlers": z.array(PaymentHandlerResponseSchema).optional(), }); export type Payment = z.infer; export const UcpServiceSchema = z.object({ - a2a: A2ASchema.optional(), - embedded: EmbeddedSchema.optional(), - mcp: McpSchema.optional(), - rest: RestSchema.optional(), - spec: z.string(), - version: z.string(), + "a2a": A2ASchema.optional(), + "embedded": EmbeddedSchema.optional(), + "mcp": McpSchema.optional(), + "rest": RestSchema.optional(), + "spec": z.string(), + "version": z.string(), }); export type UcpService = z.infer; -export const LineItemElementSchema = z.object({ - item: ItemClassSchema, - quantity: z.number(), -}); -export type LineItemElement = z.infer; - -export const PaymentInstrumentSchema = z.object({ - billing_address: BillingAddressClassSchema.optional(), - credential: PaymentCredentialSchema.optional(), - handler_id: z.string(), - id: z.string(), - type: CardPaymentInstrumentTypeSchema, - brand: z.string(), - expiry_month: z.number().optional(), - expiry_year: z.number().optional(), - last_digits: z.string(), - rich_card_art: z.string().optional(), - rich_text_description: z.string().optional(), -}); -export type PaymentInstrument = z.infer; - -export const LineItemResponseSchema = z.object({ - id: z.string(), - item: ItemResponseSchema, - parent_id: z.string().optional(), - quantity: z.number(), - totals: z.array(TotalResponseSchema), -}); -export type LineItemResponse = z.infer; - -export const PaymentResponseSchema = z.object({ - handlers: z.array(PaymentHandlerResponseSchema), - instruments: z.array(PaymentInstrumentSchema).optional(), - selected_instrument_id: z.string().optional(), -}); -export type PaymentResponse = z.infer; - -export const UcpCheckoutResponseSchema = z.object({ - capabilities: z.array(CapabilityResponseSchema), - version: z.string(), +export const LineItemCreateRequestSchema = z.object({ + "item": ItemCreateRequestSchema, + "quantity": z.number(), }); -export type UcpCheckoutResponse = z.infer; +export type LineItemCreateRequest = z.infer; -export const LineItemClassSchema = z.object({ - id: z.string().optional(), - item: LineItemItemSchema, - parent_id: z.string().optional(), - quantity: z.number(), +export const SelectedPaymentInstrumentSchema = z.object({ + "billing_address": PostalAddressSchema.optional(), + "credential": PaymentCredentialSchema.optional(), + "display": z.record(z.string(), z.any()).optional(), + "handler_id": z.string(), + "id": z.string(), + "type": z.string(), + "selected": z.boolean().optional(), }); -export type LineItemClass = z.infer; +export type SelectedPaymentInstrument = z.infer; -export const CheckoutUpdateRequestPaymentSchema = z.object({ - instruments: z.array(PaymentInstrumentSchema).optional(), - selected_instrument_id: z.string().optional(), +export const LineItemUpdateRequestSchema = z.object({ + "id": z.string().optional(), + "item": ItemUpdateRequestSchema, + "parent_id": z.string().optional(), + "quantity": z.number(), }); -export type CheckoutUpdateRequestPayment = z.infer< - typeof CheckoutUpdateRequestPaymentSchema ->; +export type LineItemUpdateRequest = z.infer; -export const AdjustmentElementSchema = z.object({ - amount: z.number().optional(), - description: z.string().optional(), - id: z.string(), - line_items: z.array(AdjustmentLineItemSchema).optional(), - occurred_at: z.coerce.date(), - status: AdjustmentStatusSchema, - type: z.string(), +export const PaymentSelectionSchema = z.object({ + "instruments": z.array(SelectedPaymentInstrumentSchema).optional(), }); -export type AdjustmentElement = z.infer; +export type PaymentSelection = z.infer; +export const PaymentCreateRequestSchema = PaymentSelectionSchema; +export type PaymentCreateRequest = PaymentSelection; +export const PaymentResponseSchema = PaymentSelectionSchema; +export type PaymentResponse = PaymentSelection; +export const PaymentUpdateRequestSchema = PaymentSelectionSchema; +export type PaymentUpdateRequest = PaymentSelection; -export const EventElementSchema = z.object({ - carrier: z.string().optional(), - description: z.string().optional(), - id: z.string(), - line_items: z.array(EventLineItemSchema), - occurred_at: z.coerce.date(), - tracking_number: z.string().optional(), - tracking_url: z.string().optional(), - type: z.string(), -}); -export type EventElement = z.infer; -export const ExpectationElementSchema = z.object({ - description: z.string().optional(), - destination: BillingAddressClassSchema, - fulfillable_on: z.string().optional(), - id: z.string(), - line_items: z.array(ExpectationLineItemSchema), - method_type: MethodTypeSchema, +export const LineItemResponseSchema = z.object({ + "id": z.string(), + "item": ItemResponseSchema, + "parent_id": z.string().optional(), + "quantity": z.number(), + "totals": z.array(TotalResponseSchema), }); -export type ExpectationElement = z.infer; +export type LineItemResponse = z.infer; -export const OrderLineItemClassSchema = z.object({ - id: z.string(), - item: ItemResponseSchema, - parent_id: z.string().optional(), - quantity: LineItemQuantitySchema, - status: LineItemStatusSchema, - totals: z.array(TotalResponseSchema), -}); -export type OrderLineItemClass = z.infer; -export const PaymentCreateRequestSchema = z.object({ - instruments: z.array(PaymentInstrumentSchema).optional(), - selected_instrument_id: z.string().optional(), -}); -export type PaymentCreateRequest = z.infer; -export const PaymentDataSchema = z.object({ - payment_data: PaymentInstrumentSchema, +export const TotalsResponseSchema = z.object({ + "amount": z.number(), + "display_text": z.string().optional(), + "type": z.string(), + "lines": z.array(LineSchema).optional(), }); -export type PaymentData = z.infer; +export type TotalsResponse = z.infer; -export const PaymentUpdateRequestSchema = z.object({ - instruments: z.array(PaymentInstrumentSchema).optional(), - selected_instrument_id: z.string().optional(), +export const UcpResponseSchema = z.object({ + "capabilities": z.array(CapabilityResponseSchema), + "version": z.string(), }); -export type PaymentUpdateRequest = z.infer; +export type UcpResponse = z.infer; export const AdjustmentSchema = z.object({ - amount: z.number().optional(), - description: z.string().optional(), - id: z.string(), - line_items: z.array(AdjustmentLineItemClassSchema).optional(), - occurred_at: z.coerce.date(), - status: AdjustmentStatusSchema, - type: z.string(), + "amount": z.number().optional(), + "description": z.string().optional(), + "id": z.string(), + "line_items": z.array(AdjustmentLineItemSchema).optional(), + "occurred_at": z.coerce.date(), + "status": AdjustmentStatusSchema, + "type": z.string(), }); export type Adjustment = z.infer; -export const BindingSchema = z.object({ - checkout_id: z.string(), - identity: IdentityClassSchema.optional(), +export const FulfillmentEventSchema = z.object({ + "carrier": z.string().optional(), + "description": z.string().optional(), + "id": z.string(), + "line_items": z.array(EventLineItemSchema), + "occurred_at": z.coerce.date(), + "tracking_number": z.string().optional(), + "tracking_url": z.string().optional(), + "type": z.string(), }); -export type Binding = z.infer; +export type FulfillmentEvent = z.infer; export const ExpectationSchema = z.object({ - description: z.string().optional(), - destination: BillingAddressClassSchema, - fulfillable_on: z.string().optional(), - id: z.string(), - line_items: z.array(ExpectationLineItemClassSchema), - method_type: MethodTypeSchema, + "description": z.string().optional(), + "destination": PostalAddressSchema, + "fulfillable_on": z.string().optional(), + "id": z.string(), + "line_items": z.array(ExpectationLineItemSchema), + "method_type": MethodTypeEnumSchema, }); export type Expectation = z.infer; -export const FulfillmentEventSchema = z.object({ - carrier: z.string().optional(), - description: z.string().optional(), - id: z.string(), - line_items: z.array(FulfillmentEventLineItemSchema), - occurred_at: z.coerce.date(), - tracking_number: z.string().optional(), - tracking_url: z.string().optional(), - type: z.string(), -}); -export type FulfillmentEvent = z.infer; - -export const FulfillmentMethodCreateRequestSchema = z.object({ - destinations: z.array(FulfillmentDestinationRequestElementSchema).optional(), - groups: z.array(GroupElementSchema).optional(), - line_item_ids: z.array(z.string()).optional(), - selected_destination_id: z.union([z.null(), z.string()]).optional(), - type: TypeElementSchema, -}); -export type FulfillmentMethodCreateRequest = z.infer< - typeof FulfillmentMethodCreateRequestSchema ->; - -export const FulfillmentMethodUpdateRequestSchema = z.object({ - destinations: z.array(FulfillmentDestinationRequestElementSchema).optional(), - groups: z.array(GroupClassSchema).optional(), - id: z.string(), - line_item_ids: z.array(z.string()), - selected_destination_id: z.union([z.null(), z.string()]).optional(), -}); -export type FulfillmentMethodUpdateRequest = z.infer< - typeof FulfillmentMethodUpdateRequestSchema ->; - -export const MerchantFulfillmentConfigSchema = z.object({ - allows_method_combinations: z.array(z.array(TypeElementSchema)).optional(), - allows_multi_destination: AllowsMultiDestinationSchema.optional(), -}); -export type MerchantFulfillmentConfig = z.infer< - typeof MerchantFulfillmentConfigSchema ->; - export const OrderLineItemSchema = z.object({ - id: z.string(), - item: ItemResponseSchema, - parent_id: z.string().optional(), - quantity: OrderLineItemQuantitySchema, - status: LineItemStatusSchema, - totals: z.array(TotalResponseSchema), + "id": z.string(), + "item": ItemResponseSchema, + "parent_id": z.string().optional(), + "quantity": QuantitySchema, + "status": LineItemStatusSchema, + "totals": z.array(TotalResponseSchema), }); export type OrderLineItem = z.infer; +export const PaymentDataSchema = z.object({ + "payment_data": PaymentInstrumentSchema, +}); +export type PaymentData = z.infer; + export const CompleteCheckoutRequestWithAp2Schema = z.object({ - ap2: Ap2CompleteRequestObjectSchema.optional(), + "ap2": CompleteCheckoutRequestWithAp2Ap2Schema.optional(), }); -export type CompleteCheckoutRequestWithAp2 = z.infer< - typeof CompleteCheckoutRequestWithAp2Schema ->; +export type CompleteCheckoutRequestWithAp2 = z.infer; export const CheckoutWithAp2MandateSchema = z.object({ - buyer: BuyerClassSchema.optional(), - continue_url: z.string().optional(), - currency: z.string(), - expires_at: z.coerce.date().optional(), - id: z.string(), - line_items: z.array(LineItemResponseSchema), - links: z.array(LinkElementSchema), - messages: z.array(MessageElementSchema).optional(), - order: OrderClassSchema.optional(), - payment: PaymentResponseSchema, - status: CheckoutResponseStatusSchema, - totals: z.array(TotalResponseSchema), - ucp: UcpCheckoutResponseSchema, - ap2: Ap2CheckoutResponseObjectSchema.optional(), -}); -export type CheckoutWithAp2Mandate = z.infer< - typeof CheckoutWithAp2MandateSchema ->; + "buyer": BuyerSchema.optional(), + "context": ContextSchema.optional(), + "continue_url": z.string().optional(), + "currency": z.string(), + "expires_at": z.coerce.date().optional(), + "id": z.string(), + "line_items": z.array(LineItemResponseSchema), + "links": z.array(LinkSchema), + "messages": z.array(MessageSchema).optional(), + "order": OrderConfirmationSchema.optional(), + "payment": PaymentResponseSchema.optional(), + "signals": SignalsSchema.optional(), + "status": CheckoutResponseStatusSchema, + "totals": z.array(TotalsResponseSchema), + "ucp": UcpResponseSchema, + "ap2": CheckoutWithAp2MandateAp2Schema.optional(), +}); +export type CheckoutWithAp2Mandate = z.infer; export const BuyerWithConsentCreateRequestSchema = z.object({ - email: z.string().optional(), - first_name: z.string().optional(), - full_name: z.string().optional(), - last_name: z.string().optional(), - phone_number: z.string().optional(), - consent: PurpleConsentSchema.optional(), + "email": z.string().optional(), + "first_name": z.string().optional(), + "last_name": z.string().optional(), + "phone_number": z.string().optional(), + "consent": PurpleConsentSchema.optional(), }); -export type BuyerWithConsentCreateRequest = z.infer< - typeof BuyerWithConsentCreateRequestSchema ->; +export type BuyerWithConsentCreateRequest = z.infer; export const BuyerWithConsentUpdateRequestSchema = z.object({ - email: z.string().optional(), - first_name: z.string().optional(), - full_name: z.string().optional(), - last_name: z.string().optional(), - phone_number: z.string().optional(), - consent: FluffyConsentSchema.optional(), + "email": z.string().optional(), + "first_name": z.string().optional(), + "last_name": z.string().optional(), + "phone_number": z.string().optional(), + "consent": FluffyConsentSchema.optional(), }); -export type BuyerWithConsentUpdateRequest = z.infer< - typeof BuyerWithConsentUpdateRequestSchema ->; +export type BuyerWithConsentUpdateRequest = z.infer; export const BuyerWithConsentResponseSchema = z.object({ - email: z.string().optional(), - first_name: z.string().optional(), - full_name: z.string().optional(), - last_name: z.string().optional(), - phone_number: z.string().optional(), - consent: TentacledConsentSchema.optional(), + "email": z.string().optional(), + "first_name": z.string().optional(), + "last_name": z.string().optional(), + "phone_number": z.string().optional(), + "consent": TentacledConsentSchema.optional(), }); -export type BuyerWithConsentResponse = z.infer< - typeof BuyerWithConsentResponseSchema ->; +export type BuyerWithConsentResponse = z.infer; export const AppliedElementSchema = z.object({ - allocations: z.array(AllocationElementSchema).optional(), - amount: z.number(), - automatic: z.boolean().optional(), - code: z.string().optional(), - method: MethodSchema.optional(), - priority: z.number().optional(), - title: z.string(), + "allocations": z.array(AllocationElementSchema).optional(), + "amount": z.number(), + "automatic": z.boolean().optional(), + "code": z.string().optional(), + "eligibility": z.string().optional(), + "method": MethodSchema.optional(), + "priority": z.number().optional(), + "provisional": z.boolean().optional(), + "title": z.string(), }); export type AppliedElement = z.infer; export const AppliedClassSchema = z.object({ - allocations: z.array(AllocationClassSchema).optional(), - amount: z.number(), - automatic: z.boolean().optional(), - code: z.string().optional(), - method: MethodSchema.optional(), - priority: z.number().optional(), - title: z.string(), + "allocations": z.array(AllocationClassSchema).optional(), + "amount": z.number(), + "automatic": z.boolean().optional(), + "code": z.string().optional(), + "eligibility": z.string().optional(), + "method": MethodSchema.optional(), + "priority": z.number().optional(), + "provisional": z.boolean().optional(), + "title": z.string(), }); export type AppliedClass = z.infer; export const DiscountsAppliedSchema = z.object({ - allocations: z.array(AppliedAllocationSchema).optional(), - amount: z.number(), - automatic: z.boolean().optional(), - code: z.string().optional(), - method: MethodSchema.optional(), - priority: z.number().optional(), - title: z.string(), + "allocations": z.array(AppliedAllocationSchema).optional(), + "amount": z.number(), + "automatic": z.boolean().optional(), + "code": z.string().optional(), + "eligibility": z.string().optional(), + "method": MethodSchema.optional(), + "priority": z.number().optional(), + "provisional": z.boolean().optional(), + "title": z.string(), }); export type DiscountsApplied = z.infer; -export const FulfillmentRequestSchema = z.object({ - methods: z.array(MethodElementSchema).optional(), -}); -export type FulfillmentRequest = z.infer; - -export const CheckoutWithFulfillmentUpdateRequestSchema = z.object({ - buyer: BuyerClassSchema.optional(), - currency: z.string(), - id: z.string(), - line_items: z.array(LineItemClassSchema), - payment: CheckoutUpdateRequestPaymentSchema, - fulfillment: FulfillmentRequestSchema.optional(), +export const FulfillmentMethodCreateRequestSchema = z.object({ + "destinations": z.array(FulfillmentDestinationRequestSchema).optional(), + "groups": z.array(FulfillmentGroupCreateRequestSchema).optional(), + "line_item_ids": z.array(z.string()).optional(), + "selected_destination_id": z.union([z.null(), z.string()]).optional(), + "type": MethodTypeSchema, }); -export type CheckoutWithFulfillmentUpdateRequest = z.infer< - typeof CheckoutWithFulfillmentUpdateRequestSchema ->; +export type FulfillmentMethodCreateRequest = z.infer; export const FulfillmentGroupResponseSchema = z.object({ - id: z.string(), - line_item_ids: z.array(z.string()), - options: z.array(FulfillmentOptionResponseSchema).optional(), - selected_option_id: z.union([z.null(), z.string()]).optional(), + "id": z.string(), + "line_item_ids": z.array(z.string()), + "options": z.array(FulfillmentOptionResponseSchema).optional(), + "selected_option_id": z.union([z.null(), z.string()]).optional(), }); -export type FulfillmentGroupResponse = z.infer< - typeof FulfillmentGroupResponseSchema ->; +export type FulfillmentGroupResponse = z.infer; -export const UcpClassSchema = z.object({ - capabilities: z.array(CapabilityDiscoverySchema), - services: z.record(z.string(), UcpServiceSchema), - version: z.string(), +export const UcpSchema = z.object({ + "capabilities": z.array(CapabilityDiscoverySchema), + "services": z.record(z.string(), UcpServiceSchema), + "version": z.string(), }); -export type UcpClass = z.infer; +export type Ucp = z.infer; -export const PaymentClassSchema = z.object({ - instruments: z.array(PaymentInstrumentSchema).optional(), - selected_instrument_id: z.string().optional(), -}); -export type PaymentClass = z.infer; -export const CheckoutResponseSchema = z.object({ - buyer: BuyerClassSchema.optional(), - continue_url: z.string().optional(), - currency: z.string(), - expires_at: z.coerce.date().optional(), - id: z.string(), - line_items: z.array(LineItemResponseSchema), - links: z.array(LinkElementSchema), - messages: z.array(MessageElementSchema).optional(), - order: OrderClassSchema.optional(), - payment: PaymentResponseSchema, - status: CheckoutResponseStatusSchema, - totals: z.array(TotalResponseSchema), - ucp: UcpCheckoutResponseSchema, -}); -export type CheckoutResponse = z.infer; export const CheckoutUpdateRequestSchema = z.object({ - buyer: BuyerClassSchema.optional(), - currency: z.string(), - id: z.string(), - line_items: z.array(LineItemClassSchema), - payment: CheckoutUpdateRequestPaymentSchema, + "buyer": BuyerSchema.optional(), + "context": ContextSchema.optional(), + "line_items": z.array(LineItemUpdateRequestSchema), + "payment": PaymentUpdateRequestSchema.optional(), + "risk_signals": z.record(z.string(), z.any()).optional(), + "signals": SignalsSchema.optional(), }); export type CheckoutUpdateRequest = z.infer; +export const CheckoutResponseSchema = z.object({ + "buyer": BuyerSchema.optional(), + "context": ContextSchema.optional(), + "continue_url": z.string().optional(), + "currency": z.string(), + "expires_at": z.coerce.date().optional(), + "id": z.string(), + "line_items": z.array(LineItemResponseSchema), + "links": z.array(LinkSchema), + "messages": z.array(MessageSchema).optional(), + "order": OrderConfirmationSchema.optional(), + "payment": PaymentResponseSchema.optional(), + "signals": SignalsSchema.optional(), + "status": CheckoutResponseStatusSchema, + "totals": z.array(TotalsResponseSchema), + "ucp": UcpResponseSchema, +}); +export type CheckoutResponse = z.infer; + export const FulfillmentSchema = z.object({ - events: z.array(EventElementSchema).optional(), - expectations: z.array(ExpectationElementSchema).optional(), + "events": z.array(FulfillmentEventSchema).optional(), + "expectations": z.array(ExpectationSchema).optional(), }); export type Fulfillment = z.infer; export const CheckoutWithBuyerConsentCreateRequestSchema = z.object({ - buyer: BuyerWithConsentCreateRequestSchema.optional(), - currency: z.string(), - line_items: z.array(LineItemElementSchema), - payment: PaymentClassSchema, + "buyer": BuyerWithConsentCreateRequestSchema.optional(), + "context": ContextSchema.optional(), + "line_items": z.array(LineItemCreateRequestSchema), + "payment": PaymentCreateRequestSchema.optional(), + "risk_signals": z.record(z.string(), z.any()).optional(), + "signals": SignalsSchema.optional(), }); -export type CheckoutWithBuyerConsentCreateRequest = z.infer< - typeof CheckoutWithBuyerConsentCreateRequestSchema ->; +export type CheckoutWithBuyerConsentCreateRequest = z.infer; export const CheckoutWithBuyerConsentUpdateRequestSchema = z.object({ - buyer: BuyerWithConsentUpdateRequestSchema.optional(), - currency: z.string(), - id: z.string(), - line_items: z.array(LineItemClassSchema), - payment: CheckoutUpdateRequestPaymentSchema, + "buyer": BuyerWithConsentUpdateRequestSchema.optional(), + "context": ContextSchema.optional(), + "line_items": z.array(LineItemUpdateRequestSchema), + "payment": PaymentUpdateRequestSchema.optional(), + "risk_signals": z.record(z.string(), z.any()).optional(), + "signals": SignalsSchema.optional(), }); -export type CheckoutWithBuyerConsentUpdateRequest = z.infer< - typeof CheckoutWithBuyerConsentUpdateRequestSchema ->; +export type CheckoutWithBuyerConsentUpdateRequest = z.infer; export const CheckoutWithBuyerConsentResponseSchema = z.object({ - buyer: BuyerWithConsentResponseSchema.optional(), - continue_url: z.string().optional(), - currency: z.string(), - expires_at: z.coerce.date().optional(), - id: z.string(), - line_items: z.array(LineItemResponseSchema), - links: z.array(LinkElementSchema), - messages: z.array(MessageElementSchema).optional(), - order: OrderClassSchema.optional(), - payment: PaymentResponseSchema, - status: CheckoutResponseStatusSchema, - totals: z.array(TotalResponseSchema), - ucp: UcpCheckoutResponseSchema, -}); -export type CheckoutWithBuyerConsentResponse = z.infer< - typeof CheckoutWithBuyerConsentResponseSchema ->; + "buyer": BuyerWithConsentResponseSchema.optional(), + "context": ContextSchema.optional(), + "continue_url": z.string().optional(), + "currency": z.string(), + "expires_at": z.coerce.date().optional(), + "id": z.string(), + "line_items": z.array(LineItemResponseSchema), + "links": z.array(LinkSchema), + "messages": z.array(MessageSchema).optional(), + "order": OrderConfirmationSchema.optional(), + "payment": PaymentResponseSchema.optional(), + "signals": SignalsSchema.optional(), + "status": CheckoutResponseStatusSchema, + "totals": z.array(TotalsResponseSchema), + "ucp": UcpResponseSchema, +}); +export type CheckoutWithBuyerConsentResponse = z.infer; export const CheckoutWithDiscountCreateRequestDiscountsSchema = z.object({ - applied: z.array(AppliedElementSchema).optional(), - codes: z.array(z.string()).optional(), + "applied": z.array(AppliedElementSchema).optional(), + "codes": z.array(z.string()).optional(), }); -export type CheckoutWithDiscountCreateRequestDiscounts = z.infer< - typeof CheckoutWithDiscountCreateRequestDiscountsSchema ->; +export type CheckoutWithDiscountCreateRequestDiscounts = z.infer; export const CheckoutWithDiscountUpdateRequestDiscountsSchema = z.object({ - applied: z.array(AppliedClassSchema).optional(), - codes: z.array(z.string()).optional(), + "applied": z.array(AppliedClassSchema).optional(), + "codes": z.array(z.string()).optional(), }); -export type CheckoutWithDiscountUpdateRequestDiscounts = z.infer< - typeof CheckoutWithDiscountUpdateRequestDiscountsSchema ->; +export type CheckoutWithDiscountUpdateRequestDiscounts = z.infer; export const CheckoutWithDiscountResponseDiscountsSchema = z.object({ - applied: z.array(DiscountsAppliedSchema).optional(), - codes: z.array(z.string()).optional(), + "applied": z.array(DiscountsAppliedSchema).optional(), + "codes": z.array(z.string()).optional(), }); -export type CheckoutWithDiscountResponseDiscounts = z.infer< - typeof CheckoutWithDiscountResponseDiscountsSchema ->; +export type CheckoutWithDiscountResponseDiscounts = z.infer; -export const CheckoutWithFulfillmentCreateRequestSchema = z.object({ - buyer: BuyerClassSchema.optional(), - currency: z.string(), - line_items: z.array(LineItemElementSchema), - payment: PaymentClassSchema, - fulfillment: FulfillmentRequestSchema.optional(), +export const FulfillmentRequestSchema = z.object({ + "methods": z.array(FulfillmentMethodCreateRequestSchema).optional(), +}); +export type FulfillmentRequest = z.infer; + +export const CheckoutWithFulfillmentUpdateRequestSchema = z.object({ + "buyer": BuyerSchema.optional(), + "context": ContextSchema.optional(), + "line_items": z.array(LineItemUpdateRequestSchema), + "payment": PaymentUpdateRequestSchema.optional(), + "risk_signals": z.record(z.string(), z.any()).optional(), + "signals": SignalsSchema.optional(), + "fulfillment": FulfillmentRequestSchema.optional(), }); -export type CheckoutWithFulfillmentCreateRequest = z.infer< - typeof CheckoutWithFulfillmentCreateRequestSchema ->; +export type CheckoutWithFulfillmentUpdateRequest = z.infer; export const FulfillmentMethodResponseSchema = z.object({ - destinations: z.array(FulfillmentDestinationResponseSchema).optional(), - groups: z.array(FulfillmentGroupResponseSchema).optional(), - id: z.string(), - line_item_ids: z.array(z.string()), - selected_destination_id: z.union([z.null(), z.string()]).optional(), - type: TypeElementSchema, + "destinations": z.array(FulfillmentDestinationResponseSchema).optional(), + "groups": z.array(FulfillmentGroupResponseSchema).optional(), + "id": z.string(), + "line_item_ids": z.array(z.string()), + "selected_destination_id": z.union([z.null(), z.string()]).optional(), + "type": MethodTypeSchema, }); -export type FulfillmentMethodResponse = z.infer< - typeof FulfillmentMethodResponseSchema ->; +export type FulfillmentMethodResponse = z.infer; export const UcpDiscoveryProfileSchema = z.object({ - payment: PaymentSchema.optional(), - signing_keys: z.array(SigningKeySchema).optional(), - ucp: UcpClassSchema, + "payment": PaymentSchema.optional(), + "signing_keys": z.array(SigningKeySchema).optional(), + "ucp": UcpSchema, }); export type UcpDiscoveryProfile = z.infer; export const CheckoutCreateRequestSchema = z.object({ - buyer: BuyerClassSchema.optional(), - currency: z.string(), - line_items: z.array(LineItemElementSchema), - payment: PaymentClassSchema, + "buyer": BuyerSchema.optional(), + "context": ContextSchema.optional(), + "line_items": z.array(LineItemCreateRequestSchema), + "payment": PaymentCreateRequestSchema.optional(), + "risk_signals": z.record(z.string(), z.any()).optional(), + "signals": SignalsSchema.optional(), }); export type CheckoutCreateRequest = z.infer; export const OrderSchema = z.object({ - adjustments: z.array(AdjustmentElementSchema).optional(), - checkout_id: z.string(), - fulfillment: FulfillmentSchema, - id: z.string(), - line_items: z.array(OrderLineItemClassSchema), - permalink_url: z.string(), - totals: z.array(TotalResponseSchema), - ucp: UcpOrderResponseSchema, + "adjustments": z.array(AdjustmentSchema).optional(), + "checkout_id": z.string(), + "currency": z.string().optional(), + "fulfillment": FulfillmentSchema, + "id": z.string(), + "line_items": z.array(OrderLineItemSchema), + "permalink_url": z.string(), + "totals": z.array(TotalsResponseSchema), + "ucp": UcpResponseSchema, }); export type Order = z.infer; export const CheckoutWithDiscountCreateRequestSchema = z.object({ - buyer: BuyerClassSchema.optional(), - currency: z.string(), - line_items: z.array(LineItemElementSchema), - payment: PaymentClassSchema, - discounts: CheckoutWithDiscountCreateRequestDiscountsSchema.optional(), + "buyer": BuyerSchema.optional(), + "context": ContextSchema.optional(), + "line_items": z.array(LineItemCreateRequestSchema), + "payment": PaymentCreateRequestSchema.optional(), + "risk_signals": z.record(z.string(), z.any()).optional(), + "signals": SignalsSchema.optional(), + "discounts": CheckoutWithDiscountCreateRequestDiscountsSchema.optional(), }); -export type CheckoutWithDiscountCreateRequest = z.infer< - typeof CheckoutWithDiscountCreateRequestSchema ->; +export type CheckoutWithDiscountCreateRequest = z.infer; export const CheckoutWithDiscountUpdateRequestSchema = z.object({ - buyer: BuyerClassSchema.optional(), - currency: z.string(), - id: z.string(), - line_items: z.array(LineItemClassSchema), - payment: CheckoutUpdateRequestPaymentSchema, - discounts: CheckoutWithDiscountUpdateRequestDiscountsSchema.optional(), + "buyer": BuyerSchema.optional(), + "context": ContextSchema.optional(), + "line_items": z.array(LineItemUpdateRequestSchema), + "payment": PaymentUpdateRequestSchema.optional(), + "risk_signals": z.record(z.string(), z.any()).optional(), + "signals": SignalsSchema.optional(), + "discounts": CheckoutWithDiscountUpdateRequestDiscountsSchema.optional(), }); -export type CheckoutWithDiscountUpdateRequest = z.infer< - typeof CheckoutWithDiscountUpdateRequestSchema ->; +export type CheckoutWithDiscountUpdateRequest = z.infer; export const CheckoutWithDiscountResponseSchema = z.object({ - buyer: BuyerClassSchema.optional(), - continue_url: z.string().optional(), - currency: z.string(), - expires_at: z.coerce.date().optional(), - id: z.string(), - line_items: z.array(LineItemResponseSchema), - links: z.array(LinkElementSchema), - messages: z.array(MessageElementSchema).optional(), - order: OrderClassSchema.optional(), - payment: PaymentResponseSchema, - status: CheckoutResponseStatusSchema, - totals: z.array(TotalResponseSchema), - ucp: UcpCheckoutResponseSchema, - discounts: CheckoutWithDiscountResponseDiscountsSchema.optional(), -}); -export type CheckoutWithDiscountResponse = z.infer< - typeof CheckoutWithDiscountResponseSchema ->; + "buyer": BuyerSchema.optional(), + "context": ContextSchema.optional(), + "continue_url": z.string().optional(), + "currency": z.string(), + "expires_at": z.coerce.date().optional(), + "id": z.string(), + "line_items": z.array(LineItemResponseSchema), + "links": z.array(LinkSchema), + "messages": z.array(MessageSchema).optional(), + "order": OrderConfirmationSchema.optional(), + "payment": PaymentResponseSchema.optional(), + "signals": SignalsSchema.optional(), + "status": CheckoutResponseStatusSchema, + "totals": z.array(TotalsResponseSchema), + "ucp": UcpResponseSchema, + "discounts": CheckoutWithDiscountResponseDiscountsSchema.optional(), +}); +export type CheckoutWithDiscountResponse = z.infer; + +export const CheckoutWithFulfillmentCreateRequestSchema = z.object({ + "buyer": BuyerSchema.optional(), + "context": ContextSchema.optional(), + "line_items": z.array(LineItemCreateRequestSchema), + "payment": PaymentCreateRequestSchema.optional(), + "risk_signals": z.record(z.string(), z.any()).optional(), + "signals": SignalsSchema.optional(), + "fulfillment": FulfillmentRequestSchema.optional(), +}); +export type CheckoutWithFulfillmentCreateRequest = z.infer; export const FulfillmentResponseSchema = z.object({ - available_methods: z - .array(FulfillmentAvailableMethodResponseSchema) - .optional(), - methods: z.array(FulfillmentMethodResponseSchema).optional(), + "available_methods": z.array(FulfillmentAvailableMethodResponseSchema).optional(), + "methods": z.array(FulfillmentMethodResponseSchema).optional(), }); export type FulfillmentResponse = z.infer; export const CheckoutWithFulfillmentResponseSchema = z.object({ - buyer: BuyerClassSchema.optional(), - continue_url: z.string().optional(), - currency: z.string(), - expires_at: z.coerce.date().optional(), - id: z.string(), - line_items: z.array(LineItemResponseSchema), - links: z.array(LinkElementSchema), - messages: z.array(MessageElementSchema).optional(), - order: OrderClassSchema.optional(), - payment: PaymentResponseSchema, - status: CheckoutResponseStatusSchema, - totals: z.array(TotalResponseSchema), - ucp: UcpCheckoutResponseSchema, - fulfillment: FulfillmentResponseSchema.optional(), -}); -export type CheckoutWithFulfillmentResponse = z.infer< - typeof CheckoutWithFulfillmentResponseSchema ->; + "buyer": BuyerSchema.optional(), + "context": ContextSchema.optional(), + "continue_url": z.string().optional(), + "currency": z.string(), + "expires_at": z.coerce.date().optional(), + "id": z.string(), + "line_items": z.array(LineItemResponseSchema), + "links": z.array(LinkSchema), + "messages": z.array(MessageSchema).optional(), + "order": OrderConfirmationSchema.optional(), + "payment": PaymentResponseSchema.optional(), + "signals": SignalsSchema.optional(), + "status": CheckoutResponseStatusSchema, + "totals": z.array(TotalsResponseSchema), + "ucp": UcpResponseSchema, + "fulfillment": FulfillmentResponseSchema.optional(), +}); +export type CheckoutWithFulfillmentResponse = z.infer;