ebay-mcp 1.13.2 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/README.de.md +3 -3
  2. package/README.es.md +3 -3
  3. package/README.fr.md +3 -3
  4. package/README.ja.md +3 -3
  5. package/README.ko.md +3 -3
  6. package/README.md +163 -41
  7. package/README.pt-BR.md +3 -3
  8. package/README.ru.md +3 -3
  9. package/README.zh-CN.md +3 -3
  10. package/build/api/account-management/account.js +633 -297
  11. package/build/api/analytics-and-report/analytics.js +111 -65
  12. package/build/api/client.js +199 -140
  13. package/build/api/clientRequestError.js +23 -0
  14. package/build/api/clientTrading.js +213 -0
  15. package/build/api/clientTradingError.js +4 -0
  16. package/build/api/communication/feedback.js +147 -59
  17. package/build/api/communication/message.js +134 -81
  18. package/build/api/communication/negotiation.js +65 -53
  19. package/build/api/communication/notification.js +458 -164
  20. package/build/api/developer/developer.js +99 -45
  21. package/build/api/index.js +23 -8
  22. package/build/api/listing-management/inventory.js +884 -338
  23. package/build/api/listing-metadata/metadata.js +416 -170
  24. package/build/api/listing-metadata/taxonomy.js +187 -42
  25. package/build/api/marketing-and-promotions/marketing.js +1392 -598
  26. package/build/api/marketing-and-promotions/recommendation.js +49 -24
  27. package/build/api/order-management/dispute.js +226 -45
  28. package/build/api/order-management/fulfillment.js +144 -71
  29. package/build/api/order-management/orderIssueHelpers.js +61 -0
  30. package/build/api/other/compliance.js +50 -38
  31. package/build/api/other/edelivery.js +603 -159
  32. package/build/api/other/finding.js +280 -0
  33. package/build/api/other/identity.js +30 -15
  34. package/build/api/other/translation.js +29 -14
  35. package/build/api/other/vero.js +113 -27
  36. package/build/api/rateLimitTracker.js +55 -0
  37. package/build/api/shared/request.js +189 -98
  38. package/build/api/trading/trading.js +154 -87
  39. package/build/auth/credentialSession.js +250 -0
  40. package/build/auth/oauth.js +298 -171
  41. package/build/auth/{oauth-metadata.js → oauthMetadata.js} +22 -6
  42. package/build/auth/oauthMiddleware.js +104 -0
  43. package/build/auth/{scope-utils.js → scopeUtils.js} +101 -28
  44. package/build/auth/tokenVerifier.js +243 -0
  45. package/build/auth/tokenVerifierError.js +21 -0
  46. package/build/config/environment.js +148 -113
  47. package/build/config/{tool-families.js → toolFamilies.js} +30 -14
  48. package/build/index.js +25 -19
  49. package/build/mcp/{http-transport.js → httpTransport.js} +102 -52
  50. package/build/mcp/readOnlyFilter.js +67 -0
  51. package/build/mcp/runtime.js +31 -13
  52. package/build/mcp/{tool-gating.js → toolGating.js} +77 -49
  53. package/build/mcp/{ui-bridge.js → uiBridge.js} +80 -23
  54. package/build/schemas/account-management/account.js +144 -6
  55. package/build/schemas/analytics/analytics.js +33 -19
  56. package/build/schemas/communication/messages.js +12 -42
  57. package/build/schemas/developer/developer.js +135 -0
  58. package/build/schemas/fulfillment/orders.js +183 -21
  59. package/build/schemas/index.js +27 -19
  60. package/build/schemas/inventory-management/inventory.js +17 -9
  61. package/build/schemas/marketing/marketing.js +480 -25
  62. package/build/schemas/metadata/metadata.js +11 -6
  63. package/build/schemas/other/finding.js +27 -0
  64. package/build/schemas/other/otherApis.js +424 -0
  65. package/build/schemas/taxonomy/taxonomy.js +11 -5
  66. package/build/scripts/{auto-setup.js → autoSetup.js} +87 -74
  67. package/build/scripts/{build-ui.js → buildUi.js} +6 -1
  68. package/build/scripts/{dev-sync.js → devSync.js} +169 -110
  69. package/build/scripts/diagnostics.js +52 -44
  70. package/build/scripts/{download-specs.js → downloadSpecs.js} +29 -21
  71. package/build/scripts/{interactive-setup.js → interactiveSetup.js} +84 -78
  72. package/build/scripts/setup.js +241 -178
  73. package/build/scripts/{setup-shared.js → setupShared.js} +29 -7
  74. package/build/scripts/skills.js +35 -27
  75. package/build/scripts/updateApiStatusDoc.js +71 -0
  76. package/build/serverHttp.js +90 -0
  77. package/build/skills/content.js +124 -118
  78. package/build/skills/index.js +22 -10
  79. package/build/skills/install.js +21 -10
  80. package/build/skills/markers.js +50 -15
  81. package/build/skills/{registry-snapshot.js → registrySnapshot.js} +8 -2
  82. package/build/skills/render.js +41 -14
  83. package/build/skills/targets.js +49 -17
  84. package/build/tools/categories/account.js +166 -264
  85. package/build/tools/categories/analytics.js +11 -22
  86. package/build/tools/categories/browse.js +17 -0
  87. package/build/tools/categories/communication.js +124 -399
  88. package/build/tools/categories/connector.js +23 -20
  89. package/build/tools/categories/developer.js +46 -159
  90. package/build/tools/categories/fulfillment.js +84 -215
  91. package/build/tools/categories/index.js +6 -14
  92. package/build/tools/categories/inventory.js +238 -293
  93. package/build/tools/categories/marketing.js +677 -39
  94. package/build/tools/categories/metadata.js +190 -117
  95. package/build/tools/categories/other.js +81 -208
  96. package/build/tools/categories/taxonomy.js +29 -20
  97. package/build/tools/categories/{token-management.js → tokenManagement.js} +187 -192
  98. package/build/tools/categories/trading.js +16 -47
  99. package/build/tools/contracts.js +34 -24
  100. package/build/tools/{define-tool.js → defineTool.js} +44 -29
  101. package/build/tools/registry.js +87 -29
  102. package/build/tools/schemas.js +3 -57
  103. package/build/tools/ui/archetypes.js +1 -0
  104. package/build/tools/ui/{map-helpers.js → mapHelpers.js} +69 -19
  105. package/build/tools/ui/maps.js +294 -80
  106. package/build/types/index.js +1 -1
  107. package/build/ui/card.html +14 -14
  108. package/build/ui/chart.html +14 -14
  109. package/build/ui/stat.html +87 -0
  110. package/build/ui/table.html +14 -14
  111. package/build/utils/apiStatusFeed.js +95 -0
  112. package/build/utils/cliOutput.js +15 -0
  113. package/build/utils/cliUi.js +108 -0
  114. package/build/utils/communication/feedback.js +57 -77
  115. package/build/utils/communication/message.js +69 -98
  116. package/build/utils/communication/negotiation.js +30 -57
  117. package/build/utils/communication/notification.js +112 -252
  118. package/build/utils/{date-converter.js → dateConverter.js} +62 -30
  119. package/build/utils/effectSchema.js +203 -0
  120. package/build/utils/effectSchemaAdapter.js +121 -0
  121. package/build/utils/effectSchemaChainMethods.js +146 -0
  122. package/build/utils/effectSchemaRefinements.js +104 -0
  123. package/build/utils/effectSchemaStringMethods.js +63 -0
  124. package/build/utils/effectSchemaTypes.js +47 -0
  125. package/build/utils/{env-parser.js → envParser.js} +10 -2
  126. package/build/utils/errors.js +7 -3
  127. package/build/utils/http.js +148 -89
  128. package/build/utils/{llm-client-detector.js → llmClientDetector.js} +295 -274
  129. package/build/utils/logger.js +127 -51
  130. package/build/utils/{oauth-helper.js → oauthHelper.js} +127 -90
  131. package/build/utils/other/compliance.js +18 -38
  132. package/build/utils/other/identity.js +2 -2
  133. package/build/utils/other/translation.js +4 -4
  134. package/build/utils/other/vero.js +36 -20
  135. package/build/utils/schemaHelpers.js +22 -0
  136. package/build/utils/scopeHelper.js +270 -0
  137. package/build/utils/securityChecker.js +316 -0
  138. package/build/utils/{setup-validator.js → setupValidator.js} +113 -94
  139. package/build/utils/{setup-wizard.js → setupWizard.js} +57 -46
  140. package/build/utils/{token-utils.js → tokenUtils.js} +2 -2
  141. package/build/utils/trading/trading.js +35 -0
  142. package/build/utils/typeGuards.js +12 -0
  143. package/build/utils/version.js +65 -29
  144. package/package.json +10 -8
  145. package/build/api/client-trading.js +0 -124
  146. package/build/api/communication/shared.js +0 -59
  147. package/build/api/shared/query-params.js +0 -16
  148. package/build/auth/credential-session.js +0 -166
  149. package/build/auth/oauth-middleware.js +0 -100
  150. package/build/auth/token-verifier.js +0 -186
  151. package/build/schemas/other/other-apis.js +0 -390
  152. package/build/scripts/update-api-status-doc.js +0 -44
  153. package/build/server-http.js +0 -85
  154. package/build/tools/definitions/marketing.js +0 -1381
  155. package/build/tools/tool-handlers/marketing.js +0 -312
  156. package/build/utils/account-management/account.js +0 -818
  157. package/build/utils/api-status-feed.js +0 -84
  158. package/build/utils/cli-ui.js +0 -47
  159. package/build/utils/order-management/dispute.js +0 -369
  160. package/build/utils/order-management/fulfillment.js +0 -205
  161. package/build/utils/other/edelivery.js +0 -235
  162. package/build/utils/schema-helpers.js +0 -13
  163. package/build/utils/scope-helper.js +0 -207
  164. package/build/utils/security-checker.js +0 -248
  165. package/build/utils/type-guards.js +0 -6
  166. /package/build/auth/{oauth-types.js → oauthTypes.js} +0 -0
  167. /package/build/{server-http.d.ts → serverHttp.d.ts} +0 -0
  168. /package/build/tools/ui/{view-models.js → viewModels.js} +0 -0
  169. /package/build/types/{ebay-enums.js → ebayEnums.js} +0 -0
@@ -1,110 +1,101 @@
1
- import { z } from 'zod';
2
- import { idSchema } from '../schema-helpers.js';
1
+ import { z } from '../../utils/effectSchema.js';
2
+ import { idSchema } from '../../utils/schemaHelpers.js';
3
3
  /**
4
- * Zod schemas for Notification API input validation
5
- * Based on: src/api/communication/notification.ts
4
+ * Effect-backed schemas for Notification API input validation.
6
5
  * OpenAPI spec: docs/sell-apps/communication/commerce_notification_v1_oas3.json
7
- * Types from: src/types/commerce_notification_v1_oas3.ts
8
6
  */
9
- // Reusable schema for limit parameter (string in API)
7
+ /** Optional positive page size accepted by Notification list endpoints. */
10
8
  const limitSchema = z
11
- .string({
12
- invalid_type_error: 'limit must be a string',
9
+ .number({
10
+ invalid_type_error: 'limit must be a number',
13
11
  description: 'Maximum number of items to return per page (10-100)',
14
12
  })
13
+ .positive('limit must be a positive number')
15
14
  .optional();
16
- // Reusable schema for continuation token parameter
15
+ /** Optional continuation cursor accepted by Notification list endpoints. */
17
16
  const continuationTokenSchema = z
18
17
  .string({
19
18
  message: 'Continuation token must be a string',
20
- invalid_type_error: 'continuation_token must be a string',
19
+ invalid_type_error: 'continuationToken must be a string',
21
20
  description: 'Token for pagination',
22
21
  })
23
22
  .optional();
24
- // Reusable schema for object data parameters
25
- const _objectDataSchema = (name, description) => z.record(z.unknown(), {
26
- message: `${name} is required`,
27
- required_error: `${name.toLowerCase().replace(/\s+/g, '_')} is required`,
28
- invalid_type_error: `${name.toLowerCase().replace(/\s+/g, '_')} must be an object`,
29
- description,
30
- });
31
- /**
32
- * Schema for getPublicKey method
33
- * Endpoint: GET /public_key/{public_key_id}
34
- * Path: GetPublicKeyParams - public_key_id (required)
35
- */
23
+ /** Destination delivery configuration schema shared by destination write tools. */
24
+ const deliveryConfigSchema = z
25
+ .object({
26
+ endpoint: z
27
+ .string({
28
+ invalid_type_error: 'endpoint must be a string',
29
+ description: 'HTTPS endpoint URL',
30
+ })
31
+ .url({
32
+ message: 'endpoint must be a valid URL',
33
+ })
34
+ .optional(),
35
+ verificationToken: z
36
+ .string({
37
+ invalid_type_error: 'verificationToken must be a string',
38
+ description: 'Verification token (32-80 alphanumeric, underscore, hyphen characters)',
39
+ })
40
+ .min(32, 'verificationToken must be at least 32 characters')
41
+ .max(80, 'verificationToken must be at most 80 characters')
42
+ .regex(/^[a-zA-Z0-9_-]+$/, 'verificationToken can only contain alphanumeric, underscore, and hyphen characters')
43
+ .optional(),
44
+ })
45
+ .optional();
46
+ /** Subscription payload detail schema shared by subscription write tools. */
47
+ const payloadSchema = z
48
+ .object({
49
+ deliveryProtocol: z
50
+ .string({
51
+ invalid_type_error: 'deliveryProtocol must be a string',
52
+ description: 'Delivery protocol',
53
+ })
54
+ .optional(),
55
+ format: z
56
+ .string({
57
+ invalid_type_error: 'format must be a string',
58
+ description: 'Payload format',
59
+ })
60
+ .optional(),
61
+ schemaVersion: z
62
+ .string({
63
+ invalid_type_error: 'schemaVersion must be a string',
64
+ description: 'Schema version for the notification topic',
65
+ })
66
+ .optional(),
67
+ })
68
+ .optional();
69
+ /** Schema for getPublicKey input. */
36
70
  export const getPublicKeySchema = z.object({
37
- public_key_id: idSchema('Public key ID', 'The unique identifier for the public key'),
71
+ publicKeyId: idSchema('Public key ID', 'The unique identifier for the public key'),
38
72
  });
39
- /**
40
- * Schema for getConfig method
41
- * Endpoint: GET /config
42
- */
73
+ /** Schema for getConfig input. */
43
74
  export const getConfigSchema = z.object({});
44
- /**
45
- * Schema for updateConfig method
46
- * Endpoint: PUT /config
47
- * Body: ConfigType - alertEmail
48
- */
75
+ /** Schema for updateConfig input. */
49
76
  export const updateConfigSchema = z.object({
50
- alert_email: z
77
+ alertEmail: z
51
78
  .string({
52
- invalid_type_error: 'alert_email must be a string',
79
+ invalid_type_error: 'alertEmail must be a string',
53
80
  description: 'Email address for Notification API alerts',
54
81
  })
55
82
  .email({
56
- message: 'alert_email must be a valid email address',
83
+ message: 'alertEmail must be a valid email address',
57
84
  })
58
85
  .optional(),
59
86
  });
60
- /**
61
- * Schema for getDestinations method
62
- * Endpoint: GET /destination
63
- * Query: DestinationParams - continuation_token, limit
64
- */
87
+ /** Schema for getDestinations input. */
65
88
  export const getDestinationsSchema = z.object({
66
- continuation_token: continuationTokenSchema,
89
+ continuationToken: continuationTokenSchema,
67
90
  limit: limitSchema,
68
91
  });
69
- /**
70
- * Schema for getDestination method
71
- * Endpoint: GET /destination/{destination_id}
72
- * Path: destination_id (required)
73
- */
92
+ /** Schema for getDestination input. */
74
93
  export const getDestinationSchema = z.object({
75
- destination_id: idSchema('Destination ID', 'The unique identifier for the destination'),
94
+ destinationId: idSchema('Destination ID', 'The unique identifier for the destination'),
76
95
  });
77
- /**
78
- * Schema for createDestination method
79
- * Endpoint: POST /destination
80
- * Body: DestinationRequest - deliveryConfig, name, status
81
- */
96
+ /** Schema for createDestination input. */
82
97
  export const createDestinationSchema = z.object({
83
- delivery_config: z
84
- .object({
85
- endpoint: z
86
- .string({
87
- invalid_type_error: 'endpoint must be a string',
88
- description: 'HTTPS endpoint URL (no internal IPs or localhost)',
89
- })
90
- .url({
91
- message: 'endpoint must be a valid URL',
92
- })
93
- .optional(),
94
- verification_token: z
95
- .string({
96
- invalid_type_error: 'verification_token must be a string',
97
- description: 'Verification token (32-80 alphanumeric, underscore, hyphen characters)',
98
- })
99
- .min(32, 'verification_token must be at least 32 characters')
100
- .max(80, 'verification_token must be at most 80 characters')
101
- .regex(/^[a-zA-Z0-9_-]+$/, 'verification_token can only contain alphanumeric, underscore, and hyphen characters')
102
- .optional(),
103
- }, {
104
- invalid_type_error: 'delivery_config must be an object',
105
- description: 'Delivery configuration with endpoint and verification token',
106
- })
107
- .optional(),
98
+ deliveryConfig: deliveryConfigSchema,
108
99
  name: z
109
100
  .string({
110
101
  invalid_type_error: 'name must be a string',
@@ -118,36 +109,10 @@ export const createDestinationSchema = z.object({
118
109
  })
119
110
  .optional(),
120
111
  });
121
- /**
122
- * Schema for updateDestination method
123
- * Endpoint: PUT /destination/{destination_id}
124
- * Path: destination_id (required)
125
- * Body: DestinationRequest
126
- */
112
+ /** Schema for updateDestination input. */
127
113
  export const updateDestinationSchema = z.object({
128
- destination_id: idSchema('Destination ID', 'The unique identifier for the destination'),
129
- delivery_config: z
130
- .object({
131
- endpoint: z
132
- .string({
133
- invalid_type_error: 'endpoint must be a string',
134
- description: 'HTTPS endpoint URL',
135
- })
136
- .url({
137
- message: 'endpoint must be a valid URL',
138
- })
139
- .optional(),
140
- verification_token: z
141
- .string({
142
- invalid_type_error: 'verification_token must be a string',
143
- description: 'Verification token (32-80 characters)',
144
- })
145
- .min(32)
146
- .max(80)
147
- .regex(/^[a-zA-Z0-9_-]+$/)
148
- .optional(),
149
- })
150
- .optional(),
114
+ destinationId: idSchema('Destination ID', 'The unique identifier for the destination'),
115
+ deliveryConfig: deliveryConfigSchema,
151
116
  name: z
152
117
  .string({
153
118
  invalid_type_error: 'name must be a string',
@@ -161,117 +126,51 @@ export const updateDestinationSchema = z.object({
161
126
  })
162
127
  .optional(),
163
128
  });
164
- /**
165
- * Schema for deleteDestination method
166
- * Endpoint: DELETE /destination/{destination_id}
167
- * Path: destination_id (required)
168
- */
129
+ /** Schema for deleteDestination input. */
169
130
  export const deleteDestinationSchema = z.object({
170
- destination_id: idSchema('Destination ID', 'The unique identifier for the destination'),
131
+ destinationId: idSchema('Destination ID', 'The unique identifier for the destination'),
171
132
  });
172
- /**
173
- * Schema for getSubscriptions method
174
- * Endpoint: GET /subscription
175
- * Query: SubscriptionParams - continuation_token, limit
176
- */
133
+ /** Schema for getSubscriptions input. */
177
134
  export const getSubscriptionsSchema = z.object({
178
135
  limit: limitSchema,
179
- continuation_token: continuationTokenSchema,
136
+ continuationToken: continuationTokenSchema,
180
137
  });
181
- /**
182
- * Schema for createSubscription method
183
- * Endpoint: POST /subscription
184
- * Body: CreateSubscriptionRequest - destinationId, payload, status, topicId
185
- */
138
+ /** Schema for createSubscription input. */
186
139
  export const createSubscriptionSchema = z.object({
187
- destination_id: z
140
+ destinationId: z
188
141
  .string({
189
- invalid_type_error: 'destination_id must be a string',
142
+ invalid_type_error: 'destinationId must be a string',
190
143
  description: 'The unique identifier of the destination endpoint',
191
144
  })
192
145
  .optional(),
193
- payload: z
194
- .object({
195
- delivery_protocol: z
196
- .string({
197
- invalid_type_error: 'delivery_protocol must be a string',
198
- description: 'Delivery protocol (currently only HTTPS is supported)',
199
- })
200
- .optional(),
201
- format: z
202
- .string({
203
- invalid_type_error: 'format must be a string',
204
- description: 'Payload format (currently only JSON is supported)',
205
- })
206
- .optional(),
207
- schema_version: z
208
- .string({
209
- invalid_type_error: 'schema_version must be a string',
210
- description: 'Schema version for the notification topic',
211
- })
212
- .optional(),
213
- }, {
214
- invalid_type_error: 'payload must be an object',
215
- description: 'Payload configuration',
216
- })
217
- .optional(),
146
+ payload: payloadSchema,
218
147
  status: z
219
148
  .string({
220
149
  invalid_type_error: 'status must be a string',
221
150
  description: 'Status: ENABLED or DISABLED',
222
151
  })
223
152
  .optional(),
224
- topic_id: z
153
+ topicId: z
225
154
  .string({
226
- invalid_type_error: 'topic_id must be a string',
155
+ invalid_type_error: 'topicId must be a string',
227
156
  description: 'The unique identifier of the notification topic',
228
157
  })
229
158
  .optional(),
230
159
  });
231
- /**
232
- * Schema for getSubscription method
233
- * Endpoint: GET /subscription/{subscription_id}
234
- * Path: subscription_id (required)
235
- */
160
+ /** Schema for getSubscription input. */
236
161
  export const getSubscriptionSchema = z.object({
237
- subscription_id: idSchema('Subscription ID', 'The unique identifier for the subscription'),
162
+ subscriptionId: idSchema('Subscription ID', 'The unique identifier for the subscription'),
238
163
  });
239
- /**
240
- * Schema for updateSubscription method
241
- * Endpoint: PUT /subscription/{subscription_id}
242
- * Path: subscription_id (required)
243
- * Body: UpdateSubscriptionRequest - destinationId, payload, status
244
- */
164
+ /** Schema for updateSubscription input. */
245
165
  export const updateSubscriptionSchema = z.object({
246
- subscription_id: idSchema('Subscription ID', 'The unique identifier for the subscription'),
247
- destination_id: z
166
+ subscriptionId: idSchema('Subscription ID', 'The unique identifier for the subscription'),
167
+ destinationId: z
248
168
  .string({
249
- invalid_type_error: 'destination_id must be a string',
169
+ invalid_type_error: 'destinationId must be a string',
250
170
  description: 'The unique identifier of the destination',
251
171
  })
252
172
  .optional(),
253
- payload: z
254
- .object({
255
- delivery_protocol: z
256
- .string({
257
- invalid_type_error: 'delivery_protocol must be a string',
258
- description: 'Delivery protocol',
259
- })
260
- .optional(),
261
- format: z
262
- .string({
263
- invalid_type_error: 'format must be a string',
264
- description: 'Payload format',
265
- })
266
- .optional(),
267
- schema_version: z
268
- .string({
269
- invalid_type_error: 'schema_version must be a string',
270
- description: 'Schema version',
271
- })
272
- .optional(),
273
- })
274
- .optional(),
173
+ payload: payloadSchema,
275
174
  status: z
276
175
  .string({
277
176
  invalid_type_error: 'status must be a string',
@@ -279,85 +178,46 @@ export const updateSubscriptionSchema = z.object({
279
178
  })
280
179
  .optional(),
281
180
  });
282
- /**
283
- * Schema for deleteSubscription method
284
- * Endpoint: DELETE /subscription/{subscription_id}
285
- * Path: subscription_id (required)
286
- */
181
+ /** Schema for deleteSubscription input. */
287
182
  export const deleteSubscriptionSchema = z.object({
288
- subscription_id: idSchema('Subscription ID', 'The unique identifier for the subscription'),
183
+ subscriptionId: idSchema('Subscription ID', 'The unique identifier for the subscription'),
289
184
  });
290
- /**
291
- * Schema for disableSubscription method
292
- * Endpoint: POST /subscription/{subscription_id}/disable
293
- * Path: subscription_id (required)
294
- */
185
+ /** Schema for disableSubscription input. */
295
186
  export const disableSubscriptionSchema = z.object({
296
- subscription_id: idSchema('Subscription ID', 'The unique identifier for the subscription'),
187
+ subscriptionId: idSchema('Subscription ID', 'The unique identifier for the subscription'),
297
188
  });
298
- /**
299
- * Schema for enableSubscription method
300
- * Endpoint: POST /subscription/{subscription_id}/enable
301
- * Path: subscription_id (required)
302
- */
189
+ /** Schema for enableSubscription input. */
303
190
  export const enableSubscriptionSchema = z.object({
304
- subscription_id: idSchema('Subscription ID', 'The unique identifier for the subscription'),
191
+ subscriptionId: idSchema('Subscription ID', 'The unique identifier for the subscription'),
305
192
  });
306
- /**
307
- * Schema for testSubscription method
308
- * Endpoint: POST /subscription/{subscription_id}/test
309
- * Path: subscription_id (required)
310
- */
193
+ /** Schema for testSubscription input. */
311
194
  export const testSubscriptionSchema = z.object({
312
- subscription_id: idSchema('Subscription ID', 'The unique identifier for the subscription'),
195
+ subscriptionId: idSchema('Subscription ID', 'The unique identifier for the subscription'),
313
196
  });
314
- /**
315
- * Schema for getTopic method
316
- * Endpoint: GET /topic/{topic_id}
317
- * Path: topic_id (required)
318
- */
197
+ /** Schema for getTopic input. */
319
198
  export const getTopicSchema = z.object({
320
- topic_id: idSchema('Topic ID', 'The unique identifier for the topic'),
199
+ topicId: idSchema('Topic ID', 'The unique identifier for the topic'),
321
200
  });
322
- /**
323
- * Schema for getTopics method
324
- * Endpoint: GET /topic
325
- * Query: TopicParams - continuation_token, limit
326
- */
201
+ /** Schema for getTopics input. */
327
202
  export const getTopicsSchema = z.object({
328
203
  limit: limitSchema,
329
- continuation_token: continuationTokenSchema,
204
+ continuationToken: continuationTokenSchema,
330
205
  });
331
- /**
332
- * Schema for createSubscriptionFilter method
333
- * Endpoint: POST /subscription/{subscription_id}/filter
334
- * Path: subscription_id (required)
335
- * Body: CreateSubscriptionFilterRequest - filterSchema
336
- */
206
+ /** Schema for createSubscriptionFilter input. */
337
207
  export const createSubscriptionFilterSchema = z.object({
338
- subscription_id: idSchema('Subscription ID', 'The unique identifier for the subscription'),
339
- filter_schema: z
340
- .record(z.unknown(), {
341
- invalid_type_error: 'filter_schema must be an object',
342
- description: 'Valid JSON Schema Core document (version 2020-12 or later) to filter notifications',
343
- })
344
- .optional(),
208
+ subscriptionId: idSchema('Subscription ID', 'The unique identifier for the subscription'),
209
+ filterSchema: z
210
+ .record(z.string(), z.unknown())
211
+ .optional()
212
+ .describe('Valid JSON Schema Core document (version 2020-12 or later) to filter notifications'),
345
213
  });
346
- /**
347
- * Schema for getSubscriptionFilter method
348
- * Endpoint: GET /subscription/{subscription_id}/filter/{filter_id}
349
- * Path: subscription_id (required), filter_id (required)
350
- */
214
+ /** Schema for getSubscriptionFilter input. */
351
215
  export const getSubscriptionFilterSchema = z.object({
352
- subscription_id: idSchema('Subscription ID', 'The unique identifier for the subscription'),
353
- filter_id: idSchema('Filter ID', 'The unique identifier for the filter'),
216
+ subscriptionId: idSchema('Subscription ID', 'The unique identifier for the subscription'),
217
+ filterId: idSchema('Filter ID', 'The unique identifier for the filter'),
354
218
  });
355
- /**
356
- * Schema for deleteSubscriptionFilter method
357
- * Endpoint: DELETE /subscription/{subscription_id}/filter/{filter_id}
358
- * Path: subscription_id (required), filter_id (required)
359
- */
219
+ /** Schema for deleteSubscriptionFilter input. */
360
220
  export const deleteSubscriptionFilterSchema = z.object({
361
- subscription_id: idSchema('Subscription ID', 'The unique identifier for the subscription'),
362
- filter_id: idSchema('Filter ID', 'The unique identifier for the filter'),
221
+ subscriptionId: idSchema('Subscription ID', 'The unique identifier for the subscription'),
222
+ filterId: idSchema('Filter ID', 'The unique identifier for the filter'),
363
223
  });
@@ -1,8 +1,12 @@
1
+ import { Data, Effect } from 'effect';
2
+ /** Utility functions for date/timestamp conversion and validation. */
3
+ /** Tagged failure returned when user-supplied date input cannot be parsed. */
4
+ export class DateConversionError extends Data.TaggedError('DateConversionError') {
5
+ }
6
+ /** Return a tagged date-conversion failure for invalid user input. */
7
+ const invalidDateInput = (input, message) => Effect.fail(new DateConversionError({ input, message }));
1
8
  /**
2
- * Utility functions for date/timestamp conversion and validation
3
- */
4
- /**
5
- * Convert a date string or Date object to Unix timestamp (milliseconds)
9
+ * Convert a date string or Date object to Unix timestamp (milliseconds).
6
10
  *
7
11
  * Supported formats:
8
12
  * - ISO 8601: "2025-01-15T10:30:00Z" or "2025-01-15T10:30:00.000Z"
@@ -12,39 +16,43 @@
12
16
  * - Relative time: "in 2 hours", "in 7200 seconds"
13
17
  *
14
18
  * @param dateInput - Date string, Date object, or Unix timestamp
15
- * @returns Unix timestamp in milliseconds
16
- * @throws Error if date format is invalid
19
+ * @returns An Effect that succeeds with a Unix timestamp in milliseconds.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const timestamp = await Effect.runPromise(convertToTimestamp('2026-01-15T10:30:00Z'));
24
+ * ```
17
25
  */
18
- export function convertToTimestamp(dateInput) {
26
+ export const convertToTimestamp = (dateInput) => {
19
27
  // If already a number, handle as timestamp
20
28
  if (typeof dateInput === 'number') {
21
29
  // If appears to be seconds (less than year 2100 in milliseconds)
22
- if (dateInput < 4102444800000) {
30
+ if (dateInput < 4_102_444_800_000) {
23
31
  // Could be seconds, check if reasonable
24
32
  const now = Date.now();
25
33
  const asSeconds = dateInput * 1000;
26
34
  // If multiplying by 1000 gives reasonable future date, it's seconds
27
35
  if (asSeconds > now - 100 * 365 * 24 * 60 * 60 * 1000) {
28
- return Math.floor(asSeconds);
36
+ return Effect.succeed(Math.floor(asSeconds));
29
37
  }
30
38
  }
31
39
  // Already milliseconds
32
- return Math.floor(dateInput);
40
+ return Effect.succeed(Math.floor(dateInput));
33
41
  }
34
42
  // If Date object
35
43
  if (dateInput instanceof Date) {
36
44
  const timestamp = dateInput.getTime();
37
- if (isNaN(timestamp)) {
38
- throw new Error('Invalid Date object');
45
+ if (Number.isNaN(timestamp)) {
46
+ return invalidDateInput(dateInput, 'Invalid Date object');
39
47
  }
40
- return timestamp;
48
+ return Effect.succeed(timestamp);
41
49
  }
42
50
  // If string, try parsing
43
51
  if (typeof dateInput === 'string') {
44
52
  // Handle relative time: "in X hours/minutes/seconds"
45
53
  const relativeMatch = /^in\s+(\d+)\s+(hours?|minutes?|seconds?|days?)$/i.exec(dateInput);
46
54
  if (relativeMatch) {
47
- const amount = parseInt(relativeMatch[1], 10);
55
+ const amount = Number.parseInt(relativeMatch[1], 10);
48
56
  const unit = relativeMatch[2].toLowerCase();
49
57
  let multiplier = 1000; // Default to seconds
50
58
  if (unit.startsWith('minute'))
@@ -53,17 +61,17 @@ export function convertToTimestamp(dateInput) {
53
61
  multiplier = 60 * 60 * 1000;
54
62
  else if (unit.startsWith('day'))
55
63
  multiplier = 24 * 60 * 60 * 1000;
56
- return Date.now() + amount * multiplier;
64
+ return Effect.succeed(Date.now() + amount * multiplier);
57
65
  }
58
66
  // Try parsing as ISO date or other standard format
59
67
  const parsed = Date.parse(dateInput);
60
- if (isNaN(parsed)) {
61
- throw new Error(`Invalid date format: ${dateInput}. Supported formats: ISO 8601, Unix timestamp, or relative time (e.g., "in 2 hours")`);
68
+ if (Number.isNaN(parsed)) {
69
+ return invalidDateInput(dateInput, `Invalid date format: ${dateInput}. Supported formats: ISO 8601, Unix timestamp, or relative time (e.g., "in 2 hours")`);
62
70
  }
63
- return parsed;
71
+ return Effect.succeed(parsed);
64
72
  }
65
- throw new Error(`Unsupported date input type: ${typeof dateInput}`);
66
- }
73
+ return invalidDateInput(dateInput, `Unsupported date input type: ${typeof dateInput}`);
74
+ };
67
75
  /**
68
76
  * Calculate expiry timestamp from duration in seconds
69
77
  * Useful for eBay token responses which provide expires_in in seconds
@@ -71,30 +79,45 @@ export function convertToTimestamp(dateInput) {
71
79
  * @param expiresInSeconds - Duration in seconds (e.g., 7200 for 2 hours)
72
80
  * @param fromTimestamp - Optional base timestamp (defaults to now)
73
81
  * @returns Expiry timestamp in milliseconds
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * const expiry = calculateExpiry(7200, Date.UTC(2026, 0, 1));
86
+ * ```
74
87
  */
75
- export function calculateExpiry(expiresInSeconds, fromTimestamp) {
88
+ export const calculateExpiry = (expiresInSeconds, fromTimestamp) => {
76
89
  const baseTime = fromTimestamp ?? Date.now();
77
90
  return baseTime + expiresInSeconds * 1000;
78
- }
91
+ };
79
92
  /**
80
93
  * Check if a timestamp is expired
81
94
  *
82
95
  * @param expiryTimestamp - Expiry timestamp in milliseconds
83
96
  * @param bufferSeconds - Optional buffer time in seconds (default: 60)
84
97
  * @returns true if expired (or will expire within buffer time)
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * const expired = isExpired(Date.now() - 1, 0);
102
+ * ```
85
103
  */
86
- export function isExpired(expiryTimestamp, bufferSeconds = 60) {
104
+ export const isExpired = (expiryTimestamp, bufferSeconds = 60) => {
87
105
  const now = Date.now();
88
106
  const buffer = bufferSeconds * 1000;
89
107
  return now + buffer >= expiryTimestamp;
90
- }
108
+ };
91
109
  /**
92
110
  * Get human-readable time remaining until expiry
93
111
  *
94
112
  * @param expiryTimestamp - Expiry timestamp in milliseconds
95
113
  * @returns Human-readable string (e.g., "2 hours 15 minutes")
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * const remaining = getTimeRemaining(Date.now() + 120_000);
118
+ * ```
96
119
  */
97
- export function getTimeRemaining(expiryTimestamp) {
120
+ export const getTimeRemaining = (expiryTimestamp) => {
98
121
  const now = Date.now();
99
122
  const diff = expiryTimestamp - now;
100
123
  if (diff <= 0) {
@@ -117,17 +140,26 @@ export function getTimeRemaining(expiryTimestamp) {
117
140
  return `${minutes} minute${minutes > 1 ? 's' : ''}${remainingSeconds > 0 ? ` ${remainingSeconds} second${remainingSeconds > 1 ? 's' : ''}` : ''}`;
118
141
  }
119
142
  return `${seconds} second${seconds > 1 ? 's' : ''}`;
120
- }
143
+ };
121
144
  /**
122
145
  * Validate access and refresh token expiry timestamps and return renewal guidance.
146
+ *
147
+ * @param accessTokenExpiry - Access-token expiry timestamp in milliseconds.
148
+ * @param refreshTokenExpiry - Refresh-token expiry timestamp in milliseconds.
149
+ * @returns Token validity flags, remaining-time labels, warnings, and recommendations.
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * const validation = validateTokenExpiry(accessTokenExpiry, refreshTokenExpiry);
154
+ * ```
123
155
  */
124
- export function validateTokenExpiry(accessTokenExpiry, refreshTokenExpiry) {
156
+ export const validateTokenExpiry = (accessTokenExpiry, refreshTokenExpiry) => {
125
157
  const warnings = [];
126
158
  const recommendations = [];
127
159
  const accessExpired = isExpired(accessTokenExpiry, 0);
128
160
  const accessExpiringSoon = isExpired(accessTokenExpiry, 300); // 5 minutes
129
161
  const refreshExpired = isExpired(refreshTokenExpiry, 0);
130
- const refreshExpiringSoon = isExpired(refreshTokenExpiry, 86400); // 1 day
162
+ const refreshExpiringSoon = isExpired(refreshTokenExpiry, 86_400); // 1 day
131
163
  let accessTokenStatus = 'valid';
132
164
  let refreshTokenStatus = 'valid';
133
165
  if (accessExpired) {
@@ -152,7 +184,7 @@ export function validateTokenExpiry(accessTokenExpiry, refreshTokenExpiry) {
152
184
  recommendations.push('Consider prompting user to re-authorize before refresh token expires');
153
185
  }
154
186
  return {
155
- valid: !accessExpired && !refreshExpired,
187
+ valid: !(accessExpired || refreshExpired),
156
188
  accessTokenStatus,
157
189
  refreshTokenStatus,
158
190
  accessTokenRemaining: getTimeRemaining(accessTokenExpiry),
@@ -160,4 +192,4 @@ export function validateTokenExpiry(accessTokenExpiry, refreshTokenExpiry) {
160
192
  warnings,
161
193
  recommendations,
162
194
  };
163
- }
195
+ };