ebay-mcp 1.18.0 → 1.18.2

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 (161) hide show
  1. package/README.md +24 -35
  2. package/build/api/account-management/accountV2.js +22 -22
  3. package/build/api/account-management/finances.js +10 -10
  4. package/build/api/analytics-and-report/analytics.js +1 -1
  5. package/build/api/{client.js → client/ebayApiClient.js} +37 -41
  6. package/build/api/{clientTrading.js → client/tradingApiClient.js} +22 -22
  7. package/build/api/communication/feedback.js +21 -21
  8. package/build/api/communication/message.js +23 -23
  9. package/build/api/communication/negotiation.js +7 -7
  10. package/build/api/communication/notification.js +52 -52
  11. package/build/api/developer/developer.js +3 -3
  12. package/build/api/{index.js → ebaySellerApi.js} +4 -4
  13. package/build/api/listing-management/feedReportTasks.js +6 -6
  14. package/build/api/listing-management/feedRequest.js +6 -6
  15. package/build/api/listing-management/feedSchedules.js +4 -4
  16. package/build/api/listing-management/feedTasks.js +2 -2
  17. package/build/api/listing-management/items.js +22 -22
  18. package/build/api/listing-management/locations.js +4 -4
  19. package/build/api/listing-management/media.js +14 -14
  20. package/build/api/listing-management/mediaAttach.js +14 -14
  21. package/build/api/listing-management/mediaResources.js +15 -13
  22. package/build/api/listing-management/offerFormat.js +1 -1
  23. package/build/api/listing-management/offers.js +23 -23
  24. package/build/api/listing-management/stores.js +9 -9
  25. package/build/api/listing-metadata/metadata.js +10 -10
  26. package/build/api/marketing-and-promotions/ads.js +34 -34
  27. package/build/api/marketing-and-promotions/campaigns.js +19 -19
  28. package/build/api/marketing-and-promotions/promotions.js +22 -22
  29. package/build/api/marketing-and-promotions/reports.js +7 -7
  30. package/build/api/order-management/dispute.js +11 -9
  31. package/build/api/order-management/fulfillment.js +4 -4
  32. package/build/api/order-management/logistics.js +7 -7
  33. package/build/api/other/browseMappers.js +15 -13
  34. package/build/api/other/browseValidators.js +4 -4
  35. package/build/api/other/edelivery.js +19 -19
  36. package/build/api/other/finding.js +13 -13
  37. package/build/api/other/translation.js +2 -2
  38. package/build/api/other/vero.js +2 -2
  39. package/build/api/shared/download.js +7 -7
  40. package/build/api/shared/request.js +28 -19
  41. package/build/api/trading/listingFormat.js +37 -30
  42. package/build/api/trading/trading.js +33 -33
  43. package/build/auth/credentialSession.js +5 -5
  44. package/build/auth/oauth.js +3 -3
  45. package/build/auth/oauthHelper.js +24 -24
  46. package/build/auth/oauthMetadata.js +4 -4
  47. package/build/auth/oauthMiddleware.js +16 -16
  48. package/build/auth/scopeUtils.js +2 -2
  49. package/build/auth/tokenVerifier.js +23 -23
  50. package/build/config/environment.js +4 -45
  51. package/build/config/oauthScopes.js +132 -0
  52. package/build/index.js +5 -5
  53. package/build/mcp/httpTransport.js +32 -20
  54. package/build/mcp/runtime.js +12 -12
  55. package/build/mcp/toolGating.js +6 -12
  56. package/build/mcp/uiBridge.js +3 -3
  57. package/build/schemas/account-management/account.js +2 -52
  58. package/build/schemas/account-management/accountV2.js +2 -2
  59. package/build/schemas/account-management/finances.js +1 -1
  60. package/build/schemas/analytics/analytics.js +2 -48
  61. package/build/schemas/communication/messages.js +2 -46
  62. package/build/schemas/developer/developer.js +1 -27
  63. package/build/schemas/fulfillment/logistics.js +1 -1
  64. package/build/schemas/fulfillment/orders.js +2 -47
  65. package/build/schemas/inventory-management/feed.js +1 -1
  66. package/build/schemas/inventory-management/inventory.js +2 -50
  67. package/build/schemas/inventory-management/media.js +2 -2
  68. package/build/schemas/inventory-management/mediaDocuments.js +1 -1
  69. package/build/schemas/inventory-management/stores.js +1 -1
  70. package/build/schemas/marketing/ads.js +2 -2
  71. package/build/schemas/marketing/campaigns.js +2 -2
  72. package/build/schemas/marketing/common.js +2 -2
  73. package/build/schemas/marketing/marketing.js +0 -1
  74. package/build/schemas/marketing/promotions.js +2 -2
  75. package/build/schemas/marketing/reports.js +2 -2
  76. package/build/schemas/metadata/metadata.js +2 -90
  77. package/build/schemas/metadata/shipping.js +1 -1
  78. package/build/schemas/other/browse.js +2 -2
  79. package/build/schemas/other/finding.js +2 -2
  80. package/build/schemas/other/otherApis.js +2 -114
  81. package/build/schemas/taxonomy/categoryTree.js +1 -1
  82. package/build/schemas/taxonomy/charity.js +1 -1
  83. package/build/schemas/taxonomy/taxonomy.js +2 -69
  84. package/build/scripts/autoSetup.js +3 -3
  85. package/build/scripts/{buildUi.js → buildMcpApps.js} +13 -13
  86. package/build/scripts/devSync.js +19 -68
  87. package/build/scripts/diagnostics.js +15 -16
  88. package/build/scripts/interactiveSetup.js +25 -25
  89. package/build/scripts/scopeHelper.js +2 -2
  90. package/build/scripts/securityChecker.js +20 -20
  91. package/build/scripts/setup.js +76 -76
  92. package/build/scripts/setupShared.js +5 -30
  93. package/build/scripts/setupValidator.js +9 -9
  94. package/build/scripts/setupWizard.js +23 -23
  95. package/build/scripts/skills.js +14 -17
  96. package/build/scripts/specRefs.js +1 -1
  97. package/build/scripts/specSources.js +144 -0
  98. package/build/serverHttp.js +4 -7
  99. package/build/skills/content.js +13 -13
  100. package/build/skills/install.js +9 -9
  101. package/build/skills/render.js +2 -2
  102. package/build/tools/categories/communication.js +1 -1
  103. package/build/tools/categories/connector.js +19 -16
  104. package/build/tools/categories/fulfillment.js +4 -4
  105. package/build/tools/categories/inventory.js +1 -1
  106. package/build/tools/categories/metadata.js +1 -1
  107. package/build/tools/categories/taxonomy.js +1 -1
  108. package/build/tools/categories/tokenManagement.js +8 -8
  109. package/build/tools/contracts.js +2 -2
  110. package/build/tools/defineTool.js +27 -12
  111. package/build/tools/registry.js +2 -2
  112. package/build/tools/schemas.js +2 -2
  113. package/build/tools/ui/mapHelpers.js +12 -12
  114. package/build/tools/ui/maps.js +101 -97
  115. package/build/tools/ui/viewModels.js +2 -2
  116. package/build/utils/apiStatusFeed.js +12 -12
  117. package/build/utils/communication/feedback.js +3 -3
  118. package/build/utils/communication/message.js +3 -3
  119. package/build/utils/communication/negotiation.js +3 -3
  120. package/build/utils/communication/notification.js +3 -3
  121. package/build/utils/entryModule.js +33 -0
  122. package/build/utils/envFile.js +47 -0
  123. package/build/utils/envParser.js +5 -5
  124. package/build/utils/errors.js +4 -4
  125. package/build/utils/http.js +38 -38
  126. package/build/utils/localFeedFiles.js +3 -3
  127. package/build/utils/logRedaction.js +21 -0
  128. package/build/utils/logger.js +49 -35
  129. package/build/utils/other/compliance.js +3 -3
  130. package/build/utils/other/identity.js +3 -3
  131. package/build/utils/other/translation.js +3 -3
  132. package/build/utils/other/vero.js +3 -3
  133. package/build/utils/schemaHelpers.js +2 -2
  134. package/build/utils/tokenUtils.js +2 -2
  135. package/build/utils/trading/trading.js +1 -1
  136. package/build/utils/version.js +1 -1
  137. package/build/utils/zodIssues.js +14 -0
  138. package/package.json +8 -11
  139. package/README.de.md +0 -426
  140. package/README.es.md +0 -426
  141. package/README.fr.md +0 -426
  142. package/README.ja.md +0 -426
  143. package/README.ko.md +0 -426
  144. package/README.pt-BR.md +0 -426
  145. package/README.ru.md +0 -426
  146. package/README.zh-CN.md +0 -426
  147. package/build/schemas/index.js +0 -76
  148. package/build/schemas/marketing/jsonSchemas.js +0 -118
  149. package/build/scripts/downloadSpecs.js +0 -117
  150. package/build/scripts/updateApiStatusDoc.js +0 -71
  151. package/build/utils/effectSchema.js +0 -203
  152. package/build/utils/effectSchemaAdapter.js +0 -121
  153. package/build/utils/effectSchemaChainMethods.js +0 -146
  154. package/build/utils/effectSchemaRefinements.js +0 -104
  155. package/build/utils/effectSchemaStringMethods.js +0 -63
  156. package/build/utils/effectSchemaTypes.js +0 -47
  157. package/docs/auth/production_scopes.json +0 -111
  158. package/docs/auth/sandbox_scopes.json +0 -142
  159. /package/build/api/{clientRequestError.js → client/ebayClientRequestError.js} +0 -0
  160. /package/build/api/{rateLimitTracker.js → client/rateLimitTracker.js} +0 -0
  161. /package/build/api/{clientTradingError.js → client/tradingApiFailure.js} +0 -0
@@ -1,117 +0,0 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
- import { getErrorMessage } from '../utils/errors.js';
4
- import { httpRequest } from '../utils/http.js';
5
- import { Effect, Either } from 'effect';
6
- import { fileURLToPath } from 'url';
7
- import { dirname } from 'path';
8
- const __filename = fileURLToPath(import.meta.url);
9
- const __dirname = dirname(__filename);
10
- const DOCS_DIR = path.resolve(__dirname, '../../docs');
11
- const README_PATH = path.resolve(__dirname, '../../docs/sell-apps/README.md');
12
- const getUrlsFromReadme = (content) => {
13
- // Regex to find URLs that end with .json, specifically for OpenAPI specs
14
- // This assumes the README will directly link to the JSON spec files, but is less strict to allow for variations.
15
- const urlRegex = /(https:\/\/[^\s)]+\.json)/g;
16
- const urls = Array.from(content.matchAll(urlRegex)).map((match) => match[1]);
17
- console.log('Found URLs:', urls);
18
- return urls;
19
- };
20
- const getFolderName = (specUrl) => {
21
- const fileName = path.basename(specUrl);
22
- // mapping from file name to folder name
23
- // This mapping is based on the README.md structure and common API groupings
24
- const folderMap = {
25
- // Application Settings
26
- 'developer_analytics_v1_beta_oas3.json': 'application-settings',
27
- 'developer_key_management_v1_oas3.json': 'application-settings',
28
- 'developer_client_registration_v1_oas3.json': 'application-settings',
29
- // Selling Apps - Listing Management
30
- 'sell_inventory_v1_oas3.json': 'sell-apps/listing-management',
31
- 'sell_feed_v1_oas3.json': 'sell-apps/listing-management',
32
- 'commerce_media_v1_beta_oas3.json': 'sell-apps/listing-management',
33
- 'sell_stores_v1_oas3.json': 'sell-apps/listing-management',
34
- // Selling Apps - Listing Metadata & Taxonomy
35
- 'sell_metadata_v1_oas3.json': 'sell-apps/listing-metadata',
36
- 'commerce_taxonomy_v1_oas3.json': 'sell-apps/listing-metadata',
37
- 'commerce_charity_v1_oas3.json': 'sell-apps/listing-metadata',
38
- // Selling Apps - Account Management
39
- 'sell_account_v1_oas3.json': 'sell-apps/account-management',
40
- 'sell_account_v2_oas3.json': 'sell-apps/account-management',
41
- 'sell_finances_v1_oas3.json': 'sell-apps/account-management',
42
- // Selling Apps - Communication & Negotiation
43
- 'commerce_message_v1_oas3.json': 'sell-apps/communication',
44
- 'commerce_notification_v1_oas3.json': 'sell-apps/communication',
45
- 'sell_negotiation_v1_oas3.json': 'sell-apps/communication',
46
- 'commerce_feedback_v1_beta_oas3.json': 'sell-apps/communication',
47
- // Selling Apps - Order Management
48
- 'sell_fulfillment_v1_oas3.json': 'sell-apps/order-management',
49
- 'sell_logistics_v1_oas3.json': 'sell-apps/order-management',
50
- // Selling Apps - Marketing & Promotions
51
- 'sell_marketing_v1_oas3.json': 'sell-apps/marketing-and-promotions',
52
- 'sell_recommendation_v1_oas3.json': 'sell-apps/marketing-and-promotions',
53
- 'sell_analytics_v1_oas3.json': 'sell-apps/analytics-and-report',
54
- // Selling Apps - Other Selling APIs
55
- 'commerce_translation_v1_beta_oas3.json': 'sell-apps/other-apis',
56
- 'sell_compliance_v1_oas3.json': 'sell-apps/other-apis',
57
- 'commerce_identity_v1_oas3.json': 'sell-apps/other-apis',
58
- 'sell_edelivery_international_shipping_oas3.json': 'sell-apps/other-apis',
59
- 'commerce_vero_v1_oas3.json': 'sell-apps/other-apis',
60
- // Buying Apps - Inventory Discovery & Refresh
61
- 'buy_browse_v1_oas3.json': 'buy-apps/inventory-discovery',
62
- 'buy_feed_v1_beta_oas3.json': 'buy-apps/inventory-discovery',
63
- 'buy_feed_v1_oas3.json': 'buy-apps/inventory-discovery',
64
- // commerce_notification_v1_oas3.json is already mapped under sell-apps,
65
- // but it's also relevant here. We'll prioritize the first mapping or create a symlink if needed.
66
- // Buying Apps - Marketing & Discounts
67
- 'buy_deal_v1_oas3.json': 'buy-apps/marketing-and-discounts',
68
- 'buy_marketing_v1_beta_oas3.json': 'buy-apps/marketing-and-discounts',
69
- // Buying Apps - Marketplace Metadata
70
- // commerce_taxonomy_v1_oas3.json is already mapped under sell-apps
71
- 'commerce_catalog_v1_beta_oas3.json': 'buy-apps/marketplace-metadata',
72
- // commerce_charity_v1_oas3.json is already mapped under sell-apps
73
- // Buying Apps - Checkout & Bidding
74
- 'buy_order_v2_oas3.json': 'buy-apps/checkout-and-bidding',
75
- 'buy_offer_v1_beta_oas3.json': 'buy-apps/checkout-and-bidding',
76
- // Buying Apps - Other Buying APIs
77
- // commerce_translation_v1_beta_oas3.json is already mapped under sell-apps
78
- // commerce_identity_v1_oas3.json is already mapped under sell-apps
79
- };
80
- // Default to 'other-apis' if not found in map, or use the mapped folder
81
- return folderMap[fileName] || 'other-apis';
82
- };
83
- const downloadFile = async (url, folderPath, fileName) => {
84
- const downloaded = await Effect.runPromise(Effect.either(Effect.tryPromise({
85
- try: async () => {
86
- const response = await httpRequest({ url, responseType: 'arraybuffer' });
87
- const filePath = path.join(folderPath, fileName);
88
- fs.mkdirSync(folderPath, { recursive: true });
89
- fs.writeFileSync(filePath, response.data);
90
- },
91
- catch: (error) => error,
92
- })));
93
- if (Either.isLeft(downloaded)) {
94
- console.error(`Failed to download ${url}:`, getErrorMessage(downloaded.left));
95
- return;
96
- }
97
- console.log(`Downloaded ${fileName} to ${folderPath}`);
98
- };
99
- const main = async () => {
100
- const readme = Effect.runSync(Effect.either(Effect.try({
101
- try: () => fs.readFileSync(README_PATH, 'utf-8'),
102
- catch: (error) => error,
103
- })));
104
- if (Either.isLeft(readme)) {
105
- console.error('Failed to read README.md:', getErrorMessage(readme.left));
106
- return;
107
- }
108
- const urls = getUrlsFromReadme(readme.right);
109
- for (const url of urls) {
110
- console.log(`Processing URL: ${url}`);
111
- const fileName = path.basename(url);
112
- const folderName = getFolderName(url);
113
- const folderPath = path.join(DOCS_DIR, folderName);
114
- await downloadFile(url, folderPath, fileName);
115
- }
116
- };
117
- void main();
@@ -1,71 +0,0 @@
1
- /**
2
- * Fetches the eBay API Status RSS feed and writes the latest items to docs/API_STATUS.md.
3
- * Used by the GitHub Action to keep an in-repo snapshot. Run with: npx tsx src/scripts/updateApiStatusDoc.ts
4
- */
5
- import { writeFileSync } from 'node:fs';
6
- import { join } from 'node:path';
7
- import { getApiStatusFeed } from '../utils/apiStatusFeed.js';
8
- import { getErrorMessage } from '../utils/errors.js';
9
- import { Data, Effect, Either } from 'effect';
10
- import process from 'node:process';
11
- const DEFAULT_LIMIT = 15;
12
- const OUT_PATH = join(process.cwd(), 'docs', 'API_STATUS.md');
13
- /** Tagged failure raised while updating the checked-in API status snapshot. */
14
- class ApiStatusDocUpdateError extends Data.TaggedError('ApiStatusDocUpdateError') {
15
- }
16
- function escapeCell(s) {
17
- return s.replace(/\|/g, '\\|').replace(/\n/g, ' ');
18
- }
19
- function buildMarkdown(items) {
20
- const lines = [
21
- '# eBay API Status (latest)',
22
- '',
23
- 'Auto-updated snapshot from the [eBay API Status RSS feed](https://developer.ebay.com/rss/api-status).',
24
- 'Full list: [developer.ebay.com/support/api-status](https://developer.ebay.com/support/api-status).',
25
- '',
26
- `*Last updated: ${new Date().toISOString()}*`,
27
- '',
28
- '| Title | API | Site | Status | Last updated | Link |',
29
- '|-------|-----|------|--------|--------------|------|',
30
- ];
31
- for (const item of items) {
32
- const link = item.link ? `[Details](${item.link})` : '';
33
- lines.push(`| ${escapeCell(item.title)} | ${escapeCell(item.api)} | ${escapeCell(item.site)} | ${escapeCell(item.status)} | ${escapeCell(item.lastUpdated)} | ${link} |`);
34
- }
35
- lines.push('', '---', '', '*Generated by [ebay-mcp](https://github.com/YosefHayim/ebay-mcp) API status sync.*');
36
- return lines.join('\n');
37
- }
38
- const updateApiStatusDoc = () => Effect.gen(function* () {
39
- const { items, error } = yield* getApiStatusFeed({ limit: DEFAULT_LIMIT }).pipe(Effect.mapError((cause) => new ApiStatusDocUpdateError({
40
- message: 'Failed to fetch API status feed',
41
- cause,
42
- })));
43
- if (error && items.length === 0) {
44
- return yield* Effect.fail(new ApiStatusDocUpdateError({
45
- message: `Failed to fetch API status feed: ${error}`,
46
- cause: error,
47
- }));
48
- }
49
- const markdown = buildMarkdown(items);
50
- yield* Effect.try({
51
- try: () => writeFileSync(OUT_PATH, markdown, 'utf8'),
52
- catch: (cause) => new ApiStatusDocUpdateError({
53
- message: `Failed to write API status doc to ${OUT_PATH}`,
54
- cause,
55
- }),
56
- });
57
- return items.length;
58
- });
59
- async function main() {
60
- const count = await Effect.runPromise(updateApiStatusDoc());
61
- console.log(`Wrote ${count} items to ${OUT_PATH}`);
62
- }
63
- void Effect.runPromise(Effect.either(Effect.tryPromise({
64
- try: main,
65
- catch: (error) => error,
66
- }))).then((result) => {
67
- if (Either.isLeft(result)) {
68
- console.error(getErrorMessage(result.left, String(result.left)));
69
- process.exitCode = 1;
70
- }
71
- });
@@ -1,203 +0,0 @@
1
- import { Effect, Schema } from 'effect';
2
- import { z as zod } from 'zod';
3
- import { attachEffectSchema, enumValues, getRequiredEffectSchema, literalUnion, objectEffectSchema, } from './effectSchemaAdapter.js';
4
- import { EffectSchemaDecodeError, getParseMessage, getState, } from './effectSchemaTypes.js';
5
- /**
6
- * Returns true when a schema was created by this module and carries Effect metadata.
7
- *
8
- * @param schema - Unknown schema-like value to inspect.
9
- * @returns Whether the value has an attached Effect Schema.
10
- *
11
- * @example
12
- * ```ts
13
- * const backed = isEffectBackedSchema(z.string());
14
- * ```
15
- */
16
- export const isEffectBackedSchema = (schema) => getState(schema) !== undefined;
17
- /**
18
- * Reads the Effect Schema attached to a schema created by this module.
19
- *
20
- * @param schema - Effect-backed schema whose Effect metadata should be returned.
21
- * @returns The attached Effect Schema, or `undefined` when the value is not backed.
22
- *
23
- * @example
24
- * ```ts
25
- * const schema = getEffectSchema(z.string());
26
- * ```
27
- */
28
- export const getEffectSchema = (schema) => getState(schema)?.schema;
29
- /**
30
- * Builds an Effect object schema from an MCP raw-shape object.
31
- *
32
- * @param shape - Tool input raw shape where every field was created by this module.
33
- * @returns Effect Schema that decodes the whole argument object.
34
- *
35
- * @example
36
- * ```ts
37
- * const argsSchema = effectStructFromShape({ sku: z.string() });
38
- * ```
39
- */
40
- export const effectStructFromShape = (shape) => objectEffectSchema(shape);
41
- /**
42
- * Decodes unknown input through the Effect Schema attached to a schema value.
43
- *
44
- * @param schema - Effect-backed schema to decode with.
45
- * @param value - Unknown runtime value from the MCP/client boundary.
46
- * @returns Effect producing the decoded value or a tagged decode error.
47
- *
48
- * @example
49
- * ```ts
50
- * const decoded = await Effect.runPromise(decodeEffectSchema(z.object({ sku: z.string() }), args));
51
- * ```
52
- */
53
- export const decodeEffectSchema = (schema, value) => {
54
- const effectSchema = getEffectSchema(schema);
55
- if (!effectSchema || Schema.isPropertySignature(effectSchema)) {
56
- return Effect.fail(new EffectSchemaDecodeError({
57
- cause: schema,
58
- message: 'Schema does not carry a decodable Effect Schema',
59
- }));
60
- }
61
- const decodableSchema = effectSchema;
62
- return Schema.decodeUnknown(decodableSchema)(value).pipe(Effect.map((decoded) => decoded), Effect.mapError((error) => new EffectSchemaDecodeError({
63
- cause: error,
64
- message: getParseMessage(error),
65
- })));
66
- };
67
- /**
68
- * Synchronously decodes unknown input through an attached Effect Schema.
69
- *
70
- * @param schema - Effect-backed schema to decode with.
71
- * @param value - Unknown runtime value from the MCP/client boundary.
72
- * @returns Decoded value produced by the attached Effect Schema.
73
- *
74
- * @example
75
- * ```ts
76
- * const args = decodeEffectSchemaSync(z.object({ sku: z.string() }), rawArgs);
77
- * ```
78
- */
79
- export const decodeEffectSchemaSync = (schema, value) => Effect.runSync(decodeEffectSchema(schema, value));
80
- /**
81
- * Zod-shaped schema factory backed by Effect Schema metadata.
82
- *
83
- * @example
84
- * ```ts
85
- * const schema = z.object({
86
- * sku: z.string().describe('Seller-defined SKU'),
87
- * limit: z.number().int().positive().optional(),
88
- * });
89
- * ```
90
- */
91
- export const z = {
92
- array(schema, options) {
93
- const effectSchema = Schema.Array(getRequiredEffectSchema(schema));
94
- const baseSchema = options?.description
95
- ? effectSchema.annotations({ description: options.description })
96
- : effectSchema;
97
- return attachEffectSchema(zod.array(schema, options), {
98
- kind: 'array',
99
- requiredSchema: baseSchema,
100
- schema: baseSchema,
101
- });
102
- },
103
- boolean(options) {
104
- const baseSchema = options?.description
105
- ? Schema.Boolean.annotations({ description: options.description })
106
- : Schema.Boolean;
107
- return attachEffectSchema(zod.boolean(options), {
108
- kind: 'boolean',
109
- requiredSchema: baseSchema,
110
- schema: baseSchema,
111
- });
112
- },
113
- custom(check, params) {
114
- const effectSchema = check
115
- ? Schema.filter((value) => check(value))(Schema.Unknown)
116
- : Schema.Unknown;
117
- return attachEffectSchema(zod.custom(check, params), {
118
- kind: 'unknown',
119
- requiredSchema: effectSchema,
120
- schema: effectSchema,
121
- });
122
- },
123
- enum(values) {
124
- const effectSchema = literalUnion(values);
125
- return attachEffectSchema(zod.enum(values), {
126
- kind: 'string',
127
- requiredSchema: effectSchema,
128
- schema: effectSchema,
129
- });
130
- },
131
- nativeEnum(enumLike) {
132
- const effectSchema = literalUnion(enumValues(enumLike));
133
- return attachEffectSchema(zod.nativeEnum(enumLike), {
134
- kind: 'string',
135
- requiredSchema: effectSchema,
136
- schema: effectSchema,
137
- });
138
- },
139
- never() {
140
- const effectSchema = Schema.Never;
141
- return attachEffectSchema(zod.never(), {
142
- kind: 'unknown',
143
- requiredSchema: effectSchema,
144
- schema: effectSchema,
145
- });
146
- },
147
- number(options) {
148
- const effectSchema = Schema.Number;
149
- return attachEffectSchema(zod.number(options), {
150
- kind: 'number',
151
- requiredSchema: effectSchema,
152
- schema: effectSchema,
153
- });
154
- },
155
- object(shape, options) {
156
- const effectSchema = objectEffectSchema(shape);
157
- const baseSchema = options?.description
158
- ? effectSchema.annotations({ description: options.description })
159
- : effectSchema;
160
- return attachEffectSchema(zod.object(shape, options), {
161
- kind: 'object',
162
- requiredSchema: baseSchema,
163
- schema: baseSchema,
164
- });
165
- },
166
- record(keyOrValue, valueSchema) {
167
- const schema = valueSchema ?? keyOrValue;
168
- const effectSchema = Schema.Record({
169
- key: valueSchema ? getRequiredEffectSchema(keyOrValue) : Schema.String,
170
- value: getRequiredEffectSchema(schema),
171
- });
172
- return attachEffectSchema(valueSchema ? zod.record(keyOrValue, valueSchema) : zod.record(schema), {
173
- kind: 'record',
174
- requiredSchema: effectSchema,
175
- schema: effectSchema,
176
- });
177
- },
178
- string(options) {
179
- const baseSchema = options?.description
180
- ? Schema.String.annotations({ description: options.description })
181
- : Schema.String;
182
- return attachEffectSchema(zod.string(options), {
183
- kind: 'string',
184
- requiredSchema: baseSchema,
185
- schema: baseSchema,
186
- });
187
- },
188
- union(options) {
189
- const effectSchema = Schema.Union(...options.map((option) => getRequiredEffectSchema(option)));
190
- return attachEffectSchema(zod.union(options), {
191
- kind: 'unknown',
192
- requiredSchema: effectSchema,
193
- schema: effectSchema,
194
- });
195
- },
196
- unknown() {
197
- return attachEffectSchema(zod.unknown(), {
198
- kind: 'unknown',
199
- requiredSchema: Schema.Unknown,
200
- schema: Schema.Unknown,
201
- });
202
- },
203
- };
@@ -1,121 +0,0 @@
1
- import { Schema } from 'effect';
2
- import { attachChainableEffectMethods } from './effectSchemaChainMethods.js';
3
- import { EFFECT_SCHEMA_STATE, } from './effectSchemaTypes.js';
4
- const getEffectState = (schema) => {
5
- if (!(typeof schema === 'object' && schema !== null && EFFECT_SCHEMA_STATE in schema)) {
6
- return;
7
- }
8
- return schema[EFFECT_SCHEMA_STATE];
9
- };
10
- const buildObjectEffectSchema = (shape) => {
11
- const effectShape = {};
12
- for (const [key, fieldSchema] of Object.entries(shape)) {
13
- effectShape[key] = getFieldEffectSchema(fieldSchema);
14
- }
15
- return Schema.Struct(effectShape);
16
- };
17
- /**
18
- * Reads the required Effect Schema for an adapter-backed schema value.
19
- *
20
- * @param schema - Schema value created by the adapter.
21
- * @returns Required Effect Schema, or `Schema.Unknown` when metadata is missing.
22
- *
23
- * @example
24
- * ```ts
25
- * const effectSchema = getRequiredEffectSchema(z.string().optional());
26
- * ```
27
- */
28
- export const getRequiredEffectSchema = (schema) => {
29
- const state = getEffectState(schema);
30
- if (!state) {
31
- return Schema.Unknown;
32
- }
33
- return state.requiredSchema;
34
- };
35
- /**
36
- * Reads the field-level Effect Schema for an adapter-backed schema value.
37
- *
38
- * @param schema - Schema value created by the adapter.
39
- * @returns Current field Effect Schema, preserving optional/default wrappers when present.
40
- *
41
- * @example
42
- * ```ts
43
- * const fieldSchema = getFieldEffectSchema(z.string().optional());
44
- * ```
45
- */
46
- export const getFieldEffectSchema = (schema) => {
47
- const state = getEffectState(schema);
48
- if (!state) {
49
- return Schema.Unknown;
50
- }
51
- return state.schema;
52
- };
53
- /**
54
- * Builds an Effect object schema from an adapter-backed raw shape.
55
- *
56
- * @param shape - Zod-compatible raw shape whose fields carry Effect metadata.
57
- * @returns Effect Schema struct for the object shape.
58
- *
59
- * @example
60
- * ```ts
61
- * const effectSchema = objectEffectSchema({ sku: z.string() });
62
- * ```
63
- */
64
- export const objectEffectSchema = (shape) => buildObjectEffectSchema(shape);
65
- /**
66
- * Extracts string values from a TypeScript enum-like object.
67
- *
68
- * @param enumLike - Enum-like object accepted by `z.nativeEnum`.
69
- * @returns Non-empty tuple of unique string enum values.
70
- *
71
- * @example
72
- * ```ts
73
- * const values = enumValues(MarketplaceId);
74
- * ```
75
- */
76
- export const enumValues = (enumLike) => {
77
- const values = Object.values(enumLike).filter((value) => typeof value === 'string');
78
- const [first, ...rest] = [...new Set(values)];
79
- if (!first) {
80
- return [''];
81
- }
82
- return [first, ...rest];
83
- };
84
- /**
85
- * Builds an Effect literal union from string values.
86
- *
87
- * @param values - Non-empty list of literal string values.
88
- * @returns Effect Schema accepting exactly those values.
89
- *
90
- * @example
91
- * ```ts
92
- * const schema = literalUnion(['ACTIVE', 'PAUSED']);
93
- * ```
94
- */
95
- export const literalUnion = (values) => Schema.Literal(...values);
96
- /**
97
- * Attaches Effect Schema metadata to a Zod-compatible schema carrier.
98
- *
99
- * @param zodSchema - Zod schema object exposed to MCP SDK and JSON-schema tooling.
100
- * @param state - Effect metadata used for runtime decode and chained refinements.
101
- * @returns The same schema carrier with hidden Effect metadata attached.
102
- *
103
- * @example
104
- * ```ts
105
- * const schema = attachEffectSchema(zod.string(), {
106
- * kind: 'string',
107
- * requiredSchema: Schema.String,
108
- * schema: Schema.String,
109
- * });
110
- * ```
111
- */
112
- export const attachEffectSchema = (zodSchema, state) => {
113
- const schema = zodSchema;
114
- Object.defineProperty(schema, EFFECT_SCHEMA_STATE, {
115
- configurable: false,
116
- enumerable: false,
117
- value: state,
118
- });
119
- attachChainableEffectMethods(schema, state, attachEffectSchema, buildObjectEffectSchema);
120
- return schema;
121
- };
@@ -1,146 +0,0 @@
1
- import { Schema } from 'effect';
2
- import { annotateSchema, defaultValueGetter, refineInt, refineMax, refineMin, refinePositive, } from './effectSchemaRefinements.js';
3
- import { attachStringEffectMethods } from './effectSchemaStringMethods.js';
4
- const patchDescribeMethod = (schema, state, attachEffectSchema) => {
5
- if (typeof schema.describe !== 'function') {
6
- return;
7
- }
8
- const describe = schema.describe.bind(schema);
9
- schema.describe = (description) => attachEffectSchema(describe(description), {
10
- ...state,
11
- requiredSchema: annotateSchema(state.requiredSchema, description),
12
- schema: annotateSchema(state.schema, description),
13
- });
14
- };
15
- const patchOptionalMethod = (schema, state, attachEffectSchema) => {
16
- if (typeof schema.optional !== 'function') {
17
- return;
18
- }
19
- const optional = schema.optional.bind(schema);
20
- schema.optional = () => attachEffectSchema(optional(), {
21
- ...state,
22
- schema: Schema.optional(state.requiredSchema),
23
- });
24
- };
25
- const patchDefaultMethod = (schema, state, attachEffectSchema) => {
26
- if (typeof schema.default !== 'function') {
27
- return;
28
- }
29
- const defaultSchema = schema.default.bind(schema);
30
- schema.default = (value) => attachEffectSchema(defaultSchema(value), {
31
- ...state,
32
- schema: Schema.optionalWith(state.requiredSchema, { default: defaultValueGetter(value) }),
33
- });
34
- };
35
- const patchPassthroughMethod = (schema, state, attachEffectSchema) => {
36
- if (typeof schema.passthrough !== 'function') {
37
- return;
38
- }
39
- const passthrough = schema.passthrough.bind(schema);
40
- schema.passthrough = () => {
41
- const passthroughEffectSchema = Schema.extend(state.requiredSchema, Schema.Record({ key: Schema.String, value: Schema.Unknown }));
42
- return attachEffectSchema(passthrough(), {
43
- kind: state.kind,
44
- requiredSchema: passthroughEffectSchema,
45
- schema: passthroughEffectSchema,
46
- });
47
- };
48
- };
49
- const patchExtendMethod = (schema, state, attachEffectSchema, buildObjectEffectSchema) => {
50
- if (typeof schema.extend !== 'function') {
51
- return;
52
- }
53
- const extend = schema.extend.bind(schema);
54
- schema.extend = (shape) => {
55
- const extensionEffectSchema = buildObjectEffectSchema(shape);
56
- const effectSchema = Schema.extend(state.requiredSchema, extensionEffectSchema);
57
- return attachEffectSchema(extend(shape), {
58
- kind: state.kind,
59
- requiredSchema: effectSchema,
60
- schema: effectSchema,
61
- });
62
- };
63
- };
64
- const patchMinMethod = (schema, state, attachEffectSchema) => {
65
- if (typeof schema.min !== 'function') {
66
- return;
67
- }
68
- const min = schema.min.bind(schema);
69
- schema.min = (value, message) => {
70
- const effectSchema = refineMin(state.requiredSchema, state.kind, value);
71
- return attachEffectSchema(min(value, message), {
72
- ...state,
73
- requiredSchema: effectSchema,
74
- schema: effectSchema,
75
- });
76
- };
77
- };
78
- const patchMaxMethod = (schema, state, attachEffectSchema) => {
79
- if (typeof schema.max !== 'function') {
80
- return;
81
- }
82
- const max = schema.max.bind(schema);
83
- schema.max = (value, message) => {
84
- const effectSchema = refineMax(state.requiredSchema, state.kind, value);
85
- return attachEffectSchema(max(value, message), {
86
- ...state,
87
- requiredSchema: effectSchema,
88
- schema: effectSchema,
89
- });
90
- };
91
- };
92
- const patchPositiveMethod = (schema, state, attachEffectSchema) => {
93
- if (typeof schema.positive !== 'function') {
94
- return;
95
- }
96
- const positive = schema.positive.bind(schema);
97
- schema.positive = (message) => {
98
- const effectSchema = refinePositive(state.requiredSchema, state.kind);
99
- return attachEffectSchema(positive(message), {
100
- ...state,
101
- requiredSchema: effectSchema,
102
- schema: effectSchema,
103
- });
104
- };
105
- };
106
- const patchIntMethod = (schema, state, attachEffectSchema) => {
107
- if (typeof schema.int !== 'function') {
108
- return;
109
- }
110
- const int = schema.int.bind(schema);
111
- schema.int = (message) => {
112
- const effectSchema = refineInt(state.requiredSchema, state.kind);
113
- return attachEffectSchema(int(message), {
114
- ...state,
115
- requiredSchema: effectSchema,
116
- schema: effectSchema,
117
- });
118
- };
119
- };
120
- /**
121
- * Rebinds chainable Zod compatibility methods so Effect metadata stays attached.
122
- *
123
- * @param schemaCarrier - Zod-compatible schema carrier receiving patched chain methods.
124
- * @param state - Effect metadata that belongs to the current schema carrier.
125
- * @param attachEffectSchema - Adapter function used to attach metadata to returned schemas.
126
- * @param buildObjectEffectSchema - Object-shape builder used by `.extend()`.
127
- * @returns Nothing; the schema carrier is patched in place.
128
- *
129
- * @example
130
- * ```ts
131
- * attachChainableEffectMethods(schema, state, attachEffectSchema, objectEffectSchema);
132
- * ```
133
- */
134
- export const attachChainableEffectMethods = (schemaCarrier, state, attachEffectSchema, buildObjectEffectSchema) => {
135
- const schema = schemaCarrier;
136
- patchDescribeMethod(schema, state, attachEffectSchema);
137
- patchOptionalMethod(schema, state, attachEffectSchema);
138
- patchDefaultMethod(schema, state, attachEffectSchema);
139
- patchPassthroughMethod(schema, state, attachEffectSchema);
140
- patchExtendMethod(schema, state, attachEffectSchema, buildObjectEffectSchema);
141
- patchMinMethod(schema, state, attachEffectSchema);
142
- patchMaxMethod(schema, state, attachEffectSchema);
143
- patchPositiveMethod(schema, state, attachEffectSchema);
144
- patchIntMethod(schema, state, attachEffectSchema);
145
- attachStringEffectMethods(schema, state, attachEffectSchema);
146
- };