@portel/photon-core 1.5.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto-ui.js +1 -1
- package/dist/auto-ui.js.map +1 -1
- package/dist/base.d.ts +1 -1
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +2 -2
- package/dist/base.js.map +1 -1
- package/dist/cli-ui-renderer.js +1 -1
- package/dist/cli-ui-renderer.js.map +1 -1
- package/dist/design-system/index.d.ts +21 -0
- package/dist/design-system/index.d.ts.map +1 -0
- package/dist/design-system/index.js +27 -0
- package/dist/design-system/index.js.map +1 -0
- package/dist/design-system/tokens.d.ts +149 -0
- package/dist/design-system/tokens.d.ts.map +1 -0
- package/dist/design-system/tokens.js +413 -0
- package/dist/design-system/tokens.js.map +1 -0
- package/dist/design-system/transaction-ui.d.ts +70 -0
- package/dist/design-system/transaction-ui.d.ts.map +1 -0
- package/dist/design-system/transaction-ui.js +982 -0
- package/dist/design-system/transaction-ui.js.map +1 -0
- package/dist/generator.d.ts +56 -6
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js.map +1 -1
- package/dist/index.d.ts +6 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -56
- package/dist/index.js.map +1 -1
- package/dist/io.d.ts +103 -2
- package/dist/io.d.ts.map +1 -1
- package/dist/io.js +37 -1
- package/dist/io.js.map +1 -1
- package/dist/rendering/components.d.ts +29 -0
- package/dist/rendering/components.d.ts.map +1 -0
- package/dist/rendering/components.js +773 -0
- package/dist/rendering/components.js.map +1 -0
- package/dist/rendering/field-analyzer.d.ts +48 -0
- package/dist/rendering/field-analyzer.d.ts.map +1 -0
- package/dist/rendering/field-analyzer.js +270 -0
- package/dist/rendering/field-analyzer.js.map +1 -0
- package/dist/rendering/field-renderers.d.ts +64 -0
- package/dist/rendering/field-renderers.d.ts.map +1 -0
- package/dist/rendering/field-renderers.js +317 -0
- package/dist/rendering/field-renderers.js.map +1 -0
- package/dist/rendering/index.d.ts +28 -0
- package/dist/rendering/index.d.ts.map +1 -0
- package/dist/rendering/index.js +60 -0
- package/dist/rendering/index.js.map +1 -0
- package/dist/rendering/layout-selector.d.ts +48 -0
- package/dist/rendering/layout-selector.d.ts.map +1 -0
- package/dist/rendering/layout-selector.js +347 -0
- package/dist/rendering/layout-selector.js.map +1 -0
- package/dist/rendering/template-engine.d.ts +41 -0
- package/dist/rendering/template-engine.d.ts.map +1 -0
- package/dist/rendering/template-engine.js +236 -0
- package/dist/rendering/template-engine.js.map +1 -0
- package/dist/schema-extractor.d.ts +30 -0
- package/dist/schema-extractor.d.ts.map +1 -1
- package/dist/schema-extractor.js +205 -12
- package/dist/schema-extractor.js.map +1 -1
- package/dist/stateful.js +1 -1
- package/dist/stateful.js.map +1 -1
- package/dist/types.d.ts +9 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ucp/ap2/handlers.d.ts +242 -0
- package/dist/ucp/ap2/handlers.d.ts.map +1 -0
- package/dist/ucp/ap2/handlers.js +482 -0
- package/dist/ucp/ap2/handlers.js.map +1 -0
- package/dist/ucp/ap2/mandates.d.ts +95 -0
- package/dist/ucp/ap2/mandates.d.ts.map +1 -0
- package/dist/ucp/ap2/mandates.js +234 -0
- package/dist/ucp/ap2/mandates.js.map +1 -0
- package/dist/ucp/ap2/types.d.ts +305 -0
- package/dist/ucp/ap2/types.d.ts.map +1 -0
- package/dist/ucp/ap2/types.js +8 -0
- package/dist/ucp/ap2/types.js.map +1 -0
- package/dist/ucp/capabilities/checkout.d.ts +118 -0
- package/dist/ucp/capabilities/checkout.d.ts.map +1 -0
- package/dist/ucp/capabilities/checkout.js +344 -0
- package/dist/ucp/capabilities/checkout.js.map +1 -0
- package/dist/ucp/capabilities/identity.d.ts +130 -0
- package/dist/ucp/capabilities/identity.d.ts.map +1 -0
- package/dist/ucp/capabilities/identity.js +290 -0
- package/dist/ucp/capabilities/identity.js.map +1 -0
- package/dist/ucp/capabilities/order.d.ts +142 -0
- package/dist/ucp/capabilities/order.d.ts.map +1 -0
- package/dist/ucp/capabilities/order.js +383 -0
- package/dist/ucp/capabilities/order.js.map +1 -0
- package/dist/ucp/index.d.ts +18 -0
- package/dist/ucp/index.d.ts.map +1 -0
- package/dist/ucp/index.js +19 -0
- package/dist/ucp/index.js.map +1 -0
- package/dist/ucp/manifest.d.ts +62 -0
- package/dist/ucp/manifest.d.ts.map +1 -0
- package/dist/ucp/manifest.js +180 -0
- package/dist/ucp/manifest.js.map +1 -0
- package/dist/ucp/types.d.ts +327 -0
- package/dist/ucp/types.d.ts.map +1 -0
- package/dist/ucp/types.js +8 -0
- package/dist/ucp/types.js.map +1 -0
- package/package.json +3 -4
- package/src/auto-ui.ts +1 -1
- package/src/base.ts +2 -2
- package/src/cli-ui-renderer.ts +1 -1
- package/src/design-system/index.ts +30 -0
- package/src/design-system/tokens.ts +451 -0
- package/src/design-system/transaction-ui.ts +1038 -0
- package/src/generator.ts +58 -2
- package/src/index.ts +135 -124
- package/src/io.ts +108 -3
- package/src/rendering/components.ts +785 -0
- package/src/rendering/field-analyzer.ts +299 -0
- package/src/rendering/field-renderers.ts +356 -0
- package/src/rendering/index.ts +63 -0
- package/src/rendering/layout-selector.ts +390 -0
- package/src/rendering/template-engine.ts +254 -0
- package/src/schema-extractor.ts +225 -12
- package/src/stateful.ts +1 -1
- package/src/types.ts +10 -1
- package/src/ucp/ap2/handlers.ts +779 -0
- package/src/ucp/ap2/mandates.ts +354 -0
- package/src/ucp/ap2/types.ts +441 -0
- package/src/ucp/capabilities/checkout.ts +497 -0
- package/src/ucp/capabilities/identity.ts +425 -0
- package/src/ucp/capabilities/order.ts +549 -0
- package/src/ucp/index.ts +27 -0
- package/src/ucp/manifest.ts +257 -0
- package/src/ucp/types.ts +454 -0
- package/dist/cli-formatter.d.ts +0 -92
- package/dist/cli-formatter.d.ts.map +0 -1
- package/dist/cli-formatter.js +0 -486
- package/dist/cli-formatter.js.map +0 -1
- package/dist/context.d.ts +0 -6
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -3
- package/dist/context.js.map +0 -1
- package/dist/elicit.d.ts +0 -93
- package/dist/elicit.d.ts.map +0 -1
- package/dist/elicit.js +0 -373
- package/dist/elicit.js.map +0 -1
- package/dist/mcp-client.d.ts +0 -218
- package/dist/mcp-client.d.ts.map +0 -1
- package/dist/mcp-client.js +0 -424
- package/dist/mcp-client.js.map +0 -1
- package/dist/mcp-sdk-transport.d.ts +0 -88
- package/dist/mcp-sdk-transport.d.ts.map +0 -1
- package/dist/mcp-sdk-transport.js +0 -360
- package/dist/mcp-sdk-transport.js.map +0 -1
- package/dist/photon-config.d.ts +0 -86
- package/dist/photon-config.d.ts.map +0 -1
- package/dist/photon-config.js +0 -156
- package/dist/photon-config.js.map +0 -1
- package/dist/progress.d.ts +0 -93
- package/dist/progress.d.ts.map +0 -1
- package/dist/progress.js +0 -195
- package/dist/progress.js.map +0 -1
- package/src/cli-formatter.ts +0 -579
- package/src/context.ts +0 -7
- package/src/elicit.ts +0 -438
- package/src/mcp-client.ts +0 -561
- package/src/mcp-sdk-transport.ts +0 -449
- package/src/photon-config.ts +0 -201
- package/src/progress.ts +0 -224
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UCP Manifest Generator
|
|
3
|
+
*
|
|
4
|
+
* Auto-generates /.well-known/ucp manifest from Photon class metadata.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
UCPManifest,
|
|
9
|
+
UCPCapability,
|
|
10
|
+
UCPCapabilityConfig,
|
|
11
|
+
UCPMetadata,
|
|
12
|
+
UCPMethodMetadata
|
|
13
|
+
} from './types.js';
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Manifest Generation
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
export interface GenerateManifestParams {
|
|
20
|
+
merchantId: string;
|
|
21
|
+
merchantName: string;
|
|
22
|
+
merchantLogo?: string;
|
|
23
|
+
supportUrl?: string;
|
|
24
|
+
capabilities: UCPCapability[];
|
|
25
|
+
paymentHandlers?: string[];
|
|
26
|
+
supportedCurrencies?: string[];
|
|
27
|
+
supportedCountries?: string[];
|
|
28
|
+
baseUrl?: string;
|
|
29
|
+
mcpServerName?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Generate UCP manifest from parameters
|
|
34
|
+
*/
|
|
35
|
+
export function generateUCPManifest(params: GenerateManifestParams): UCPManifest {
|
|
36
|
+
const {
|
|
37
|
+
merchantId,
|
|
38
|
+
merchantName,
|
|
39
|
+
merchantLogo,
|
|
40
|
+
supportUrl,
|
|
41
|
+
capabilities,
|
|
42
|
+
paymentHandlers = ['stripe'],
|
|
43
|
+
supportedCurrencies = ['USD'],
|
|
44
|
+
supportedCountries = ['US'],
|
|
45
|
+
baseUrl = '',
|
|
46
|
+
mcpServerName
|
|
47
|
+
} = params;
|
|
48
|
+
|
|
49
|
+
const capabilityConfigs: Record<UCPCapability, UCPCapabilityConfig> = {
|
|
50
|
+
checkout: {
|
|
51
|
+
supported: capabilities.includes('checkout'),
|
|
52
|
+
endpoint: capabilities.includes('checkout') ? `${baseUrl}/ucp/checkout` : undefined,
|
|
53
|
+
webhooks: false
|
|
54
|
+
},
|
|
55
|
+
identity: {
|
|
56
|
+
supported: capabilities.includes('identity'),
|
|
57
|
+
endpoint: capabilities.includes('identity') ? `${baseUrl}/ucp/identity` : undefined
|
|
58
|
+
},
|
|
59
|
+
order: {
|
|
60
|
+
supported: capabilities.includes('order'),
|
|
61
|
+
endpoint: capabilities.includes('order') ? `${baseUrl}/ucp/order` : undefined,
|
|
62
|
+
webhooks: capabilities.includes('order')
|
|
63
|
+
},
|
|
64
|
+
payment_token_exchange: {
|
|
65
|
+
supported: capabilities.includes('payment_token_exchange'),
|
|
66
|
+
endpoint: capabilities.includes('payment_token_exchange')
|
|
67
|
+
? `${baseUrl}/ucp/payment-token`
|
|
68
|
+
: undefined
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const manifest: UCPManifest = {
|
|
73
|
+
ucp_version: '1.0',
|
|
74
|
+
merchant: {
|
|
75
|
+
id: merchantId,
|
|
76
|
+
name: merchantName,
|
|
77
|
+
logo: merchantLogo,
|
|
78
|
+
supportUrl
|
|
79
|
+
},
|
|
80
|
+
capabilities: capabilityConfigs,
|
|
81
|
+
payment_handlers: paymentHandlers,
|
|
82
|
+
supported_currencies: supportedCurrencies,
|
|
83
|
+
supported_countries: supportedCountries
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Add OAuth config if identity capability is enabled
|
|
87
|
+
if (capabilities.includes('identity')) {
|
|
88
|
+
manifest.oauth = {
|
|
89
|
+
authorizationEndpoint: `${baseUrl}/oauth/authorize`,
|
|
90
|
+
tokenEndpoint: `${baseUrl}/oauth/token`,
|
|
91
|
+
revocationEndpoint: `${baseUrl}/oauth/revoke`,
|
|
92
|
+
scopes: ['checkout.read', 'checkout.write', 'order.read', 'order.write']
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Add MCP config if server name provided
|
|
97
|
+
if (mcpServerName) {
|
|
98
|
+
manifest.mcp = {
|
|
99
|
+
server_name: mcpServerName,
|
|
100
|
+
tools_prefix: 'ucp'
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return manifest;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ============================================================================
|
|
108
|
+
// JSDoc Annotation Parsing
|
|
109
|
+
// ============================================================================
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Parse UCP metadata from JSDoc annotations
|
|
113
|
+
*
|
|
114
|
+
* Supports:
|
|
115
|
+
* - @ucp - Enable UCP for class
|
|
116
|
+
* - @capability checkout|identity|order|payment_token_exchange
|
|
117
|
+
* - @ucp.merchant.id <id>
|
|
118
|
+
* - @ucp.merchant.name <name>
|
|
119
|
+
* - @ucp.operation <capability>.<operation>
|
|
120
|
+
*/
|
|
121
|
+
export function parseUCPAnnotations(jsdoc: string): UCPMetadata | null {
|
|
122
|
+
// Check if @ucp is present
|
|
123
|
+
if (!/@ucp\b/.test(jsdoc)) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const capabilities: UCPCapability[] = [];
|
|
128
|
+
|
|
129
|
+
// Parse @capability annotations
|
|
130
|
+
const capabilityMatches = jsdoc.matchAll(/@capability\s+(checkout|identity|order|payment_token_exchange)/g);
|
|
131
|
+
for (const match of capabilityMatches) {
|
|
132
|
+
capabilities.push(match[1] as UCPCapability);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Parse merchant info
|
|
136
|
+
const merchantIdMatch = jsdoc.match(/@ucp\.merchant\.id\s+(\S+)/);
|
|
137
|
+
const merchantNameMatch = jsdoc.match(/@ucp\.merchant\.name\s+(.+?)(?:\n|$)/);
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
enabled: true,
|
|
141
|
+
capabilities,
|
|
142
|
+
merchantId: merchantIdMatch?.[1],
|
|
143
|
+
merchantName: merchantNameMatch?.[1]?.trim()
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Parse UCP operation from method JSDoc
|
|
149
|
+
*/
|
|
150
|
+
export function parseUCPMethodAnnotation(jsdoc: string): UCPMethodMetadata | null {
|
|
151
|
+
const match = jsdoc.match(/@ucp\.operation\s+(checkout|identity|order|payment_token_exchange)\.(\w+)/);
|
|
152
|
+
if (!match) return null;
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
capability: match[1] as UCPCapability,
|
|
156
|
+
operation: match[2]
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// ============================================================================
|
|
161
|
+
// Manifest Extraction from Schema
|
|
162
|
+
// ============================================================================
|
|
163
|
+
|
|
164
|
+
export interface ExtractManifestParams {
|
|
165
|
+
className: string;
|
|
166
|
+
classJsdoc: string;
|
|
167
|
+
methods: {
|
|
168
|
+
name: string;
|
|
169
|
+
jsdoc: string;
|
|
170
|
+
}[];
|
|
171
|
+
baseUrl?: string;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Extract UCP manifest from class schema
|
|
176
|
+
*/
|
|
177
|
+
export function extractManifestFromSchema(params: ExtractManifestParams): UCPManifest | null {
|
|
178
|
+
const { className, classJsdoc, methods, baseUrl } = params;
|
|
179
|
+
|
|
180
|
+
const ucpMeta = parseUCPAnnotations(classJsdoc);
|
|
181
|
+
if (!ucpMeta) return null;
|
|
182
|
+
|
|
183
|
+
// Auto-detect capabilities from method annotations if not explicitly declared
|
|
184
|
+
const detectedCapabilities = new Set(ucpMeta.capabilities);
|
|
185
|
+
|
|
186
|
+
for (const method of methods) {
|
|
187
|
+
const methodMeta = parseUCPMethodAnnotation(method.jsdoc);
|
|
188
|
+
if (methodMeta) {
|
|
189
|
+
detectedCapabilities.add(methodMeta.capability);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Also detect from method names
|
|
194
|
+
const methodNames = methods.map(m => m.name.toLowerCase());
|
|
195
|
+
|
|
196
|
+
if (methodNames.some(n => n.includes('checkout') || n.includes('cart'))) {
|
|
197
|
+
detectedCapabilities.add('checkout');
|
|
198
|
+
}
|
|
199
|
+
if (methodNames.some(n => n.includes('order') || n.includes('shipment') || n.includes('return'))) {
|
|
200
|
+
detectedCapabilities.add('order');
|
|
201
|
+
}
|
|
202
|
+
if (methodNames.some(n => n.includes('oauth') || n.includes('authorize') || n.includes('identity'))) {
|
|
203
|
+
detectedCapabilities.add('identity');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return generateUCPManifest({
|
|
207
|
+
merchantId: ucpMeta.merchantId || className.toLowerCase().replace(/[^a-z0-9]/g, '-'),
|
|
208
|
+
merchantName: ucpMeta.merchantName || className,
|
|
209
|
+
capabilities: Array.from(detectedCapabilities),
|
|
210
|
+
baseUrl,
|
|
211
|
+
mcpServerName: className
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// ============================================================================
|
|
216
|
+
// Well-Known Response
|
|
217
|
+
// ============================================================================
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Generate the /.well-known/ucp response
|
|
221
|
+
*/
|
|
222
|
+
export function generateWellKnownResponse(manifest: UCPManifest): string {
|
|
223
|
+
return JSON.stringify(manifest, null, 2);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Validate UCP manifest
|
|
228
|
+
*/
|
|
229
|
+
export function validateManifest(manifest: UCPManifest): { valid: boolean; errors: string[] } {
|
|
230
|
+
const errors: string[] = [];
|
|
231
|
+
|
|
232
|
+
if (!manifest.ucp_version) {
|
|
233
|
+
errors.push('Missing ucp_version');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (!manifest.merchant?.id) {
|
|
237
|
+
errors.push('Missing merchant.id');
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (!manifest.merchant?.name) {
|
|
241
|
+
errors.push('Missing merchant.name');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const hasAnyCapability = Object.values(manifest.capabilities).some(c => c.supported);
|
|
245
|
+
if (!hasAnyCapability) {
|
|
246
|
+
errors.push('At least one capability must be supported');
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (manifest.payment_handlers.length === 0) {
|
|
250
|
+
errors.push('At least one payment handler must be specified');
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return {
|
|
254
|
+
valid: errors.length === 0,
|
|
255
|
+
errors
|
|
256
|
+
};
|
|
257
|
+
}
|
package/src/ucp/types.ts
ADDED
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal Commerce Protocol (UCP) Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Based on UCP specification from https://ucp.dev/
|
|
5
|
+
* Compatible with MCP transport for Photon integration.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Core Types
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
export interface Money {
|
|
13
|
+
amount: number;
|
|
14
|
+
currency: string; // ISO 4217 currency code
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface Address {
|
|
18
|
+
name?: string;
|
|
19
|
+
organization?: string;
|
|
20
|
+
addressLine1: string;
|
|
21
|
+
addressLine2?: string;
|
|
22
|
+
city: string;
|
|
23
|
+
region?: string; // State/Province
|
|
24
|
+
postalCode: string;
|
|
25
|
+
country: string; // ISO 3166-1 alpha-2
|
|
26
|
+
phone?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface BuyerInfo {
|
|
30
|
+
email: string;
|
|
31
|
+
name?: string;
|
|
32
|
+
phone?: string;
|
|
33
|
+
billingAddress?: Address;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ============================================================================
|
|
37
|
+
// Checkout Types
|
|
38
|
+
// ============================================================================
|
|
39
|
+
|
|
40
|
+
export type CheckoutSessionStatus =
|
|
41
|
+
| 'open' // Session active, can modify cart
|
|
42
|
+
| 'ready_for_complete' // Cart finalized, ready for payment
|
|
43
|
+
| 'processing' // Payment being processed
|
|
44
|
+
| 'completed' // Successfully completed
|
|
45
|
+
| 'expired' // Session timed out
|
|
46
|
+
| 'cancelled'; // User cancelled
|
|
47
|
+
|
|
48
|
+
export interface LineItem {
|
|
49
|
+
id: string;
|
|
50
|
+
sku?: string;
|
|
51
|
+
label: string;
|
|
52
|
+
description?: string;
|
|
53
|
+
quantity: number;
|
|
54
|
+
unitPrice: Money;
|
|
55
|
+
totalPrice: Money;
|
|
56
|
+
productUrl?: string;
|
|
57
|
+
imageUrl?: string;
|
|
58
|
+
metadata?: Record<string, any>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface DiscountAllocation {
|
|
62
|
+
code: string;
|
|
63
|
+
label: string;
|
|
64
|
+
type: 'percentage' | 'fixed' | 'free_shipping';
|
|
65
|
+
value: number;
|
|
66
|
+
appliedAmount: Money;
|
|
67
|
+
lineItemAllocations?: { lineItemId: string; amount: Money }[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface TaxLine {
|
|
71
|
+
label: string;
|
|
72
|
+
rate: number; // Decimal (0.08 = 8%)
|
|
73
|
+
amount: Money;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface Totals {
|
|
77
|
+
subtotal: Money;
|
|
78
|
+
discounts: Money;
|
|
79
|
+
shipping: Money;
|
|
80
|
+
tax: Money;
|
|
81
|
+
total: Money;
|
|
82
|
+
taxLines?: TaxLine[];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface FulfillmentOption {
|
|
86
|
+
id: string;
|
|
87
|
+
label: string;
|
|
88
|
+
description?: string;
|
|
89
|
+
carrier?: string;
|
|
90
|
+
estimatedDelivery?: string;
|
|
91
|
+
price: Money;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface FulfillmentDestination {
|
|
95
|
+
type: 'shipping' | 'pickup' | 'digital';
|
|
96
|
+
address?: Address;
|
|
97
|
+
pickupLocation?: {
|
|
98
|
+
id: string;
|
|
99
|
+
name: string;
|
|
100
|
+
address: Address;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface PaymentMethodInfo {
|
|
105
|
+
id: string;
|
|
106
|
+
type: 'card' | 'bank_transfer' | 'wallet' | 'crypto' | 'other';
|
|
107
|
+
label: string;
|
|
108
|
+
icon?: string;
|
|
109
|
+
lastFour?: string;
|
|
110
|
+
expiryMonth?: number;
|
|
111
|
+
expiryYear?: number;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface CheckoutSession {
|
|
115
|
+
id: string;
|
|
116
|
+
merchantId: string;
|
|
117
|
+
status: CheckoutSessionStatus;
|
|
118
|
+
createdAt: string;
|
|
119
|
+
updatedAt: string;
|
|
120
|
+
expiresAt: string;
|
|
121
|
+
|
|
122
|
+
// Buyer
|
|
123
|
+
buyer?: BuyerInfo;
|
|
124
|
+
|
|
125
|
+
// Cart
|
|
126
|
+
lineItems: LineItem[];
|
|
127
|
+
|
|
128
|
+
// Discounts
|
|
129
|
+
discounts: DiscountAllocation[];
|
|
130
|
+
|
|
131
|
+
// Fulfillment
|
|
132
|
+
fulfillmentOptions: FulfillmentOption[];
|
|
133
|
+
selectedFulfillment?: {
|
|
134
|
+
optionId: string;
|
|
135
|
+
destination: FulfillmentDestination;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// Payment
|
|
139
|
+
availablePaymentMethods: PaymentMethodInfo[];
|
|
140
|
+
selectedPaymentMethod?: PaymentMethodInfo;
|
|
141
|
+
|
|
142
|
+
// Totals
|
|
143
|
+
totals: Totals;
|
|
144
|
+
|
|
145
|
+
// Metadata
|
|
146
|
+
metadata?: Record<string, any>;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ============================================================================
|
|
150
|
+
// Order Types
|
|
151
|
+
// ============================================================================
|
|
152
|
+
|
|
153
|
+
export type OrderStatus =
|
|
154
|
+
| 'pending' // Order created, awaiting confirmation
|
|
155
|
+
| 'confirmed' // Payment confirmed
|
|
156
|
+
| 'processing' // Being prepared
|
|
157
|
+
| 'shipped' // In transit
|
|
158
|
+
| 'delivered' // Successfully delivered
|
|
159
|
+
| 'cancelled' // Cancelled
|
|
160
|
+
| 'refunded'; // Fully refunded
|
|
161
|
+
|
|
162
|
+
export type ShipmentStatus =
|
|
163
|
+
| 'label_created'
|
|
164
|
+
| 'picked_up'
|
|
165
|
+
| 'in_transit'
|
|
166
|
+
| 'out_for_delivery'
|
|
167
|
+
| 'delivered'
|
|
168
|
+
| 'failed_delivery'
|
|
169
|
+
| 'returned';
|
|
170
|
+
|
|
171
|
+
export interface TrackingEvent {
|
|
172
|
+
timestamp: string;
|
|
173
|
+
status: ShipmentStatus;
|
|
174
|
+
location?: string;
|
|
175
|
+
description: string;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface Shipment {
|
|
179
|
+
id: string;
|
|
180
|
+
carrier: string;
|
|
181
|
+
trackingNumber: string;
|
|
182
|
+
trackingUrl?: string;
|
|
183
|
+
status: ShipmentStatus;
|
|
184
|
+
estimatedDelivery?: string;
|
|
185
|
+
events: TrackingEvent[];
|
|
186
|
+
lineItemIds: string[];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface FulfillmentExpectation {
|
|
190
|
+
id: string;
|
|
191
|
+
type: 'shipping' | 'pickup' | 'digital';
|
|
192
|
+
description: string;
|
|
193
|
+
estimatedDate?: string;
|
|
194
|
+
lineItemIds: string[];
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export interface Adjustment {
|
|
198
|
+
id: string;
|
|
199
|
+
type: 'refund' | 'partial_refund' | 'price_adjustment' | 'return';
|
|
200
|
+
amount: Money;
|
|
201
|
+
reason: string;
|
|
202
|
+
createdAt: string;
|
|
203
|
+
lineItemIds?: string[];
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export interface ReturnRequest {
|
|
207
|
+
id: string;
|
|
208
|
+
status: 'requested' | 'approved' | 'rejected' | 'received' | 'refunded';
|
|
209
|
+
items: { lineItemId: string; quantity: number; reason: string }[];
|
|
210
|
+
createdAt: string;
|
|
211
|
+
updatedAt: string;
|
|
212
|
+
refundAmount?: Money;
|
|
213
|
+
returnLabel?: {
|
|
214
|
+
carrier: string;
|
|
215
|
+
trackingNumber: string;
|
|
216
|
+
labelUrl: string;
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface Order {
|
|
221
|
+
id: string;
|
|
222
|
+
checkoutSessionId: string;
|
|
223
|
+
merchantId: string;
|
|
224
|
+
status: OrderStatus;
|
|
225
|
+
createdAt: string;
|
|
226
|
+
updatedAt: string;
|
|
227
|
+
|
|
228
|
+
// Buyer
|
|
229
|
+
buyer: BuyerInfo;
|
|
230
|
+
|
|
231
|
+
// Items
|
|
232
|
+
lineItems: LineItem[];
|
|
233
|
+
|
|
234
|
+
// Fulfillment
|
|
235
|
+
fulfillmentExpectations: FulfillmentExpectation[];
|
|
236
|
+
shipments: Shipment[];
|
|
237
|
+
|
|
238
|
+
// Payment
|
|
239
|
+
paymentMethod: PaymentMethodInfo;
|
|
240
|
+
paymentStatus: 'pending' | 'authorized' | 'captured' | 'refunded' | 'failed';
|
|
241
|
+
|
|
242
|
+
// Totals
|
|
243
|
+
totals: Totals;
|
|
244
|
+
|
|
245
|
+
// Adjustments & Returns
|
|
246
|
+
adjustments: Adjustment[];
|
|
247
|
+
returns: ReturnRequest[];
|
|
248
|
+
|
|
249
|
+
// Metadata
|
|
250
|
+
metadata?: Record<string, any>;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// ============================================================================
|
|
254
|
+
// Identity Linking Types (OAuth 2.0)
|
|
255
|
+
// ============================================================================
|
|
256
|
+
|
|
257
|
+
export interface OAuthConfig {
|
|
258
|
+
authorizationEndpoint: string;
|
|
259
|
+
tokenEndpoint: string;
|
|
260
|
+
revocationEndpoint?: string;
|
|
261
|
+
scopes: string[];
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export interface TokenResponse {
|
|
265
|
+
accessToken: string;
|
|
266
|
+
tokenType: string;
|
|
267
|
+
expiresIn: number;
|
|
268
|
+
refreshToken?: string;
|
|
269
|
+
scope: string;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export interface IdentityLink {
|
|
273
|
+
id: string;
|
|
274
|
+
agentId: string;
|
|
275
|
+
userId: string;
|
|
276
|
+
scopes: string[];
|
|
277
|
+
createdAt: string;
|
|
278
|
+
expiresAt?: string;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// ============================================================================
|
|
282
|
+
// Webhook Types
|
|
283
|
+
// ============================================================================
|
|
284
|
+
|
|
285
|
+
export type WebhookEventType =
|
|
286
|
+
| 'checkout.created'
|
|
287
|
+
| 'checkout.updated'
|
|
288
|
+
| 'checkout.completed'
|
|
289
|
+
| 'order.created'
|
|
290
|
+
| 'order.updated'
|
|
291
|
+
| 'order.cancelled'
|
|
292
|
+
| 'shipment.created'
|
|
293
|
+
| 'shipment.updated'
|
|
294
|
+
| 'delivery.completed'
|
|
295
|
+
| 'return.requested'
|
|
296
|
+
| 'return.approved'
|
|
297
|
+
| 'refund.created';
|
|
298
|
+
|
|
299
|
+
export interface WebhookRegistration {
|
|
300
|
+
id: string;
|
|
301
|
+
url: string;
|
|
302
|
+
events: WebhookEventType[];
|
|
303
|
+
secret: string;
|
|
304
|
+
active: boolean;
|
|
305
|
+
createdAt: string;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export interface WebhookPayload {
|
|
309
|
+
id: string;
|
|
310
|
+
type: WebhookEventType;
|
|
311
|
+
timestamp: string;
|
|
312
|
+
data: any;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// ============================================================================
|
|
316
|
+
// UCP Manifest Types
|
|
317
|
+
// ============================================================================
|
|
318
|
+
|
|
319
|
+
export type UCPCapability = 'checkout' | 'identity' | 'order' | 'payment_token_exchange';
|
|
320
|
+
|
|
321
|
+
export interface UCPCapabilityConfig {
|
|
322
|
+
supported: boolean;
|
|
323
|
+
endpoint?: string;
|
|
324
|
+
webhooks?: boolean;
|
|
325
|
+
extensions?: string[];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export interface UCPManifest {
|
|
329
|
+
ucp_version: string;
|
|
330
|
+
merchant: {
|
|
331
|
+
id: string;
|
|
332
|
+
name: string;
|
|
333
|
+
logo?: string;
|
|
334
|
+
supportUrl?: string;
|
|
335
|
+
};
|
|
336
|
+
capabilities: Record<UCPCapability, UCPCapabilityConfig>;
|
|
337
|
+
payment_handlers: string[];
|
|
338
|
+
supported_currencies: string[];
|
|
339
|
+
supported_countries: string[];
|
|
340
|
+
oauth?: OAuthConfig;
|
|
341
|
+
mcp?: {
|
|
342
|
+
server_name: string;
|
|
343
|
+
tools_prefix?: string;
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// ============================================================================
|
|
348
|
+
// Capability Interfaces
|
|
349
|
+
// ============================================================================
|
|
350
|
+
|
|
351
|
+
export interface CheckoutCapability {
|
|
352
|
+
createSession(params: {
|
|
353
|
+
currency?: string;
|
|
354
|
+
locale?: string;
|
|
355
|
+
metadata?: Record<string, any>;
|
|
356
|
+
}): Promise<CheckoutSession>;
|
|
357
|
+
|
|
358
|
+
getSession(sessionId: string): Promise<CheckoutSession>;
|
|
359
|
+
|
|
360
|
+
updateCart(sessionId: string, updates: {
|
|
361
|
+
add?: Omit<LineItem, 'id' | 'totalPrice'>[];
|
|
362
|
+
remove?: string[];
|
|
363
|
+
update?: { id: string; quantity: number }[];
|
|
364
|
+
}): Promise<CheckoutSession>;
|
|
365
|
+
|
|
366
|
+
setBuyer(sessionId: string, buyer: BuyerInfo): Promise<CheckoutSession>;
|
|
367
|
+
|
|
368
|
+
setFulfillment(sessionId: string, params: {
|
|
369
|
+
optionId: string;
|
|
370
|
+
destination: FulfillmentDestination;
|
|
371
|
+
}): Promise<CheckoutSession>;
|
|
372
|
+
|
|
373
|
+
applyDiscount(sessionId: string, code: string): Promise<{
|
|
374
|
+
success: boolean;
|
|
375
|
+
session: CheckoutSession;
|
|
376
|
+
error?: string;
|
|
377
|
+
}>;
|
|
378
|
+
|
|
379
|
+
removeDiscount(sessionId: string, code: string): Promise<CheckoutSession>;
|
|
380
|
+
|
|
381
|
+
complete(sessionId: string, payment: {
|
|
382
|
+
methodId?: string;
|
|
383
|
+
mandate?: any; // AP2 PaymentMandate
|
|
384
|
+
}): Promise<Order>;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export interface IdentityCapability {
|
|
388
|
+
getOAuthConfig(): Promise<OAuthConfig>;
|
|
389
|
+
|
|
390
|
+
requestAuthorization(params: {
|
|
391
|
+
agentId: string;
|
|
392
|
+
scopes: string[];
|
|
393
|
+
redirectUri: string;
|
|
394
|
+
state?: string;
|
|
395
|
+
}): Promise<{ authorizationUrl: string }>;
|
|
396
|
+
|
|
397
|
+
exchangeCode(params: {
|
|
398
|
+
code: string;
|
|
399
|
+
redirectUri: string;
|
|
400
|
+
}): Promise<TokenResponse>;
|
|
401
|
+
|
|
402
|
+
refreshToken(refreshToken: string): Promise<TokenResponse>;
|
|
403
|
+
|
|
404
|
+
revokeToken(token: string): Promise<void>;
|
|
405
|
+
|
|
406
|
+
getIdentityLink(agentId: string): Promise<IdentityLink | null>;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export interface OrderCapability {
|
|
410
|
+
getOrder(orderId: string): Promise<Order>;
|
|
411
|
+
|
|
412
|
+
listOrders(params?: {
|
|
413
|
+
status?: OrderStatus[];
|
|
414
|
+
limit?: number;
|
|
415
|
+
cursor?: string;
|
|
416
|
+
}): Promise<{ orders: Order[]; nextCursor?: string }>;
|
|
417
|
+
|
|
418
|
+
cancelOrder(orderId: string, reason?: string): Promise<Order>;
|
|
419
|
+
|
|
420
|
+
trackShipment(orderId: string, shipmentId?: string): Promise<Shipment[]>;
|
|
421
|
+
|
|
422
|
+
initiateReturn(orderId: string, params: {
|
|
423
|
+
items: { lineItemId: string; quantity: number; reason: string }[];
|
|
424
|
+
}): Promise<ReturnRequest>;
|
|
425
|
+
|
|
426
|
+
getReturn(orderId: string, returnId: string): Promise<ReturnRequest>;
|
|
427
|
+
|
|
428
|
+
// Webhooks
|
|
429
|
+
registerWebhook(params: {
|
|
430
|
+
url: string;
|
|
431
|
+
events: WebhookEventType[];
|
|
432
|
+
secret: string;
|
|
433
|
+
}): Promise<WebhookRegistration>;
|
|
434
|
+
|
|
435
|
+
listWebhooks(): Promise<WebhookRegistration[]>;
|
|
436
|
+
|
|
437
|
+
deleteWebhook(webhookId: string): Promise<void>;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// ============================================================================
|
|
441
|
+
// UCP Class Decorator Metadata
|
|
442
|
+
// ============================================================================
|
|
443
|
+
|
|
444
|
+
export interface UCPMetadata {
|
|
445
|
+
enabled: boolean;
|
|
446
|
+
capabilities: UCPCapability[];
|
|
447
|
+
merchantId?: string;
|
|
448
|
+
merchantName?: string;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export interface UCPMethodMetadata {
|
|
452
|
+
capability: UCPCapability;
|
|
453
|
+
operation: string;
|
|
454
|
+
}
|