mcp4openapi 0.2.4 → 0.2.5

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 (60) hide show
  1. package/README.md +14 -1
  2. package/dist/scripts/validate-profile.js +3 -1
  3. package/dist/scripts/validate-profile.js.map +1 -1
  4. package/dist/src/composite-executor.d.ts.map +1 -1
  5. package/dist/src/composite-executor.js +1 -3
  6. package/dist/src/composite-executor.js.map +1 -1
  7. package/dist/src/errors.js +0 -2
  8. package/dist/src/errors.js.map +1 -1
  9. package/dist/src/generated-schemas.d.ts +217 -30
  10. package/dist/src/generated-schemas.d.ts.map +1 -1
  11. package/dist/src/generated-schemas.js +15 -2
  12. package/dist/src/generated-schemas.js.map +1 -1
  13. package/dist/src/http-client-factory.js +3 -2
  14. package/dist/src/http-client-factory.js.map +1 -1
  15. package/dist/src/http-transport.d.ts +9 -2
  16. package/dist/src/http-transport.d.ts.map +1 -1
  17. package/dist/src/http-transport.js +133 -36
  18. package/dist/src/http-transport.js.map +1 -1
  19. package/dist/src/interceptors.d.ts +34 -0
  20. package/dist/src/interceptors.d.ts.map +1 -1
  21. package/dist/src/interceptors.js +90 -6
  22. package/dist/src/interceptors.js.map +1 -1
  23. package/dist/src/logger.js +0 -4
  24. package/dist/src/logger.js.map +1 -1
  25. package/dist/src/mcp-server.d.ts +7 -0
  26. package/dist/src/mcp-server.d.ts.map +1 -1
  27. package/dist/src/mcp-server.js +74 -20
  28. package/dist/src/mcp-server.js.map +1 -1
  29. package/dist/src/metrics.js +0 -17
  30. package/dist/src/metrics.js.map +1 -1
  31. package/dist/src/oauth-provider.d.ts +29 -0
  32. package/dist/src/oauth-provider.d.ts.map +1 -1
  33. package/dist/src/oauth-provider.js +177 -22
  34. package/dist/src/oauth-provider.js.map +1 -1
  35. package/dist/src/openapi-parser.d.ts.map +1 -1
  36. package/dist/src/openapi-parser.js +4 -3
  37. package/dist/src/openapi-parser.js.map +1 -1
  38. package/dist/src/profile-loader.d.ts.map +1 -1
  39. package/dist/src/profile-loader.js +8 -0
  40. package/dist/src/profile-loader.js.map +1 -1
  41. package/dist/src/proxy-executor.d.ts +56 -0
  42. package/dist/src/proxy-executor.d.ts.map +1 -0
  43. package/dist/src/proxy-executor.js +155 -0
  44. package/dist/src/proxy-executor.js.map +1 -0
  45. package/dist/src/testing/mock-youtrack-server.d.ts +11 -0
  46. package/dist/src/testing/mock-youtrack-server.d.ts.map +1 -0
  47. package/dist/src/testing/mock-youtrack-server.js +138 -0
  48. package/dist/src/testing/mock-youtrack-server.js.map +1 -0
  49. package/dist/src/testing/test-http-utils.js +1 -3
  50. package/dist/src/testing/test-http-utils.js.map +1 -1
  51. package/dist/src/testing/test-types.d.ts +26 -1
  52. package/dist/src/testing/test-types.d.ts.map +1 -1
  53. package/dist/src/tool-generator.d.ts +23 -0
  54. package/dist/src/tool-generator.d.ts.map +1 -1
  55. package/dist/src/tool-generator.js +55 -5
  56. package/dist/src/tool-generator.js.map +1 -1
  57. package/dist/src/types/profile.d.ts +41 -3
  58. package/dist/src/types/profile.d.ts.map +1 -1
  59. package/package.json +1 -1
  60. package/profile-schema.json +70 -2
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Proxy download executor for fetching binary content through API
3
+ *
4
+ * Why: LLM needs file content but URLs require authentication.
5
+ * This executor fetches metadata, extracts URL, downloads content,
6
+ * and returns base64-encoded result.
7
+ */
8
+ import type { ProxyDownloadOperation } from './types/profile.js';
9
+ import type { ResponseContext, AuthCredentials } from './interceptors.js';
10
+ export interface HttpClient {
11
+ request(method: string, url: string, options?: {
12
+ headers?: Record<string, string>;
13
+ body?: unknown;
14
+ }): Promise<ResponseContext>;
15
+ }
16
+ export interface ProxyDownloadResult {
17
+ /** Original metadata from API */
18
+ metadata: Record<string, unknown>;
19
+ /** Base64-encoded file content */
20
+ content: string;
21
+ /** MIME type of the file */
22
+ mimeType: string;
23
+ /** File size in bytes */
24
+ size: number;
25
+ /** Original filename if available */
26
+ fileName?: string;
27
+ }
28
+ export declare class ProxyDownloadExecutor {
29
+ private httpClient;
30
+ constructor(httpClient: HttpClient);
31
+ /**
32
+ * Execute proxy download operation
33
+ *
34
+ * @param operation Proxy download configuration
35
+ * @param path API path with substituted parameters
36
+ * @param authCredentials Auth credentials (headers + query params) for download
37
+ */
38
+ execute(operation: ProxyDownloadOperation, path: string, authCredentials: AuthCredentials): Promise<ProxyDownloadResult>;
39
+ private resolveMaxSize;
40
+ /**
41
+ * Extract URL from metadata using dot-notation path
42
+ */
43
+ private extractUrl;
44
+ /**
45
+ * Check if MIME type matches whitelist (supports wildcards like 'image/*')
46
+ */
47
+ private isMimeTypeAllowed;
48
+ /**
49
+ * Download binary content and return base64
50
+ *
51
+ * @param skipAuth If true, download URL is fetched without authentication headers/params
52
+ * Metadata endpoint still requires auth, only the final download is unauthenticated
53
+ */
54
+ private downloadWithAuth;
55
+ }
56
+ //# sourceMappingURL=proxy-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy-executor.d.ts","sourceRoot":"","sources":["../../src/proxy-executor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAG1E,MAAM,WAAW,UAAU;IACzB,OAAO,CACL,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,GACA,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAElC,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAEhB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IAEjB,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IAEb,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD,qBAAa,qBAAqB;IACpB,OAAO,CAAC,UAAU;gBAAV,UAAU,EAAE,UAAU;IAE1C;;;;;;OAMG;IACG,OAAO,CACX,SAAS,EAAE,sBAAsB,EACjC,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,mBAAmB,CAAC;IAsD/B,OAAO,CAAC,cAAc;IAyBtB;;OAEG;IACH,OAAO,CAAC,UAAU;IAclB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;;OAKG;YACW,gBAAgB;CAsE/B"}
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Proxy download executor for fetching binary content through API
3
+ *
4
+ * Why: LLM needs file content but URLs require authentication.
5
+ * This executor fetches metadata, extracts URL, downloads content,
6
+ * and returns base64-encoded result.
7
+ */
8
+ import { NetworkError, ValidationError } from './errors.js';
9
+ const DEFAULT_MAX_SIZE = 10 * 1024 * 1024; // 10MB
10
+ const DEFAULT_TIMEOUT = 30000; // 30s
11
+ export class ProxyDownloadExecutor {
12
+ constructor(httpClient) {
13
+ this.httpClient = httpClient;
14
+ }
15
+ /**
16
+ * Execute proxy download operation
17
+ *
18
+ * @param operation Proxy download configuration
19
+ * @param path API path with substituted parameters
20
+ * @param authCredentials Auth credentials (headers + query params) for download
21
+ */
22
+ async execute(operation, path, authCredentials) {
23
+ const maxSize = this.resolveMaxSize(operation);
24
+ const timeout = operation.timeout_ms ?? DEFAULT_TIMEOUT;
25
+ const urlField = operation.url_field ?? 'url';
26
+ // Step 1: Fetch metadata
27
+ const metadataResponse = await this.httpClient.request('GET', path);
28
+ const metadata = metadataResponse.body;
29
+ // Step 2: Extract URL from metadata
30
+ const url = this.extractUrl(metadata, urlField);
31
+ if (!url) {
32
+ throw new ValidationError(`URL field '${urlField}' not found in metadata response`);
33
+ }
34
+ // Step 3: Check MIME type whitelist (from metadata if available)
35
+ const mimeType = metadata['mimeType'] || 'application/octet-stream';
36
+ if (operation.allowed_mime_types) {
37
+ if (!this.isMimeTypeAllowed(mimeType, operation.allowed_mime_types)) {
38
+ throw new ValidationError(`MIME type '${mimeType}' not in whitelist: ${operation.allowed_mime_types.join(', ')}`);
39
+ }
40
+ }
41
+ // Step 4: Check file size (from metadata if available)
42
+ const reportedSize = metadata['size'];
43
+ if (reportedSize && reportedSize > maxSize) {
44
+ throw new ValidationError(`File size ${reportedSize} exceeds maximum ${maxSize} bytes`);
45
+ }
46
+ // Step 5: Download binary content
47
+ const skipAuth = operation.skip_auth ?? false;
48
+ const { content, size } = await this.downloadWithAuth(url, authCredentials, maxSize, timeout, skipAuth);
49
+ return {
50
+ metadata,
51
+ content,
52
+ mimeType,
53
+ size,
54
+ fileName: metadata['name'],
55
+ };
56
+ }
57
+ resolveMaxSize(operation) {
58
+ const envKeys = [operation.max_size_bytes_from_env, 'MCP4_PROXY_MAX_BYTES'].filter(Boolean);
59
+ for (const key of envKeys) {
60
+ const rawValue = process.env[key];
61
+ if (rawValue !== undefined) {
62
+ const parsed = Number(rawValue);
63
+ if (!Number.isInteger(parsed) || parsed <= 0) {
64
+ throw new ValidationError(`Invalid max size from env ${key}: expected positive integer, got '${rawValue}'`);
65
+ }
66
+ return parsed;
67
+ }
68
+ }
69
+ if (operation.max_size_bytes !== undefined) {
70
+ return operation.max_size_bytes;
71
+ }
72
+ return DEFAULT_MAX_SIZE;
73
+ }
74
+ /**
75
+ * Extract URL from metadata using dot-notation path
76
+ */
77
+ extractUrl(metadata, urlField) {
78
+ const parts = urlField.split('.');
79
+ let current = metadata;
80
+ for (const part of parts) {
81
+ if (current === null || typeof current !== 'object') {
82
+ return null;
83
+ }
84
+ current = current[part];
85
+ }
86
+ return typeof current === 'string' ? current : null;
87
+ }
88
+ /**
89
+ * Check if MIME type matches whitelist (supports wildcards like 'image/*')
90
+ */
91
+ isMimeTypeAllowed(mimeType, whitelist) {
92
+ return whitelist.some(pattern => {
93
+ if (pattern.endsWith('/*')) {
94
+ const prefix = pattern.slice(0, -1); // 'image/*' -> 'image/'
95
+ return mimeType.startsWith(prefix);
96
+ }
97
+ return mimeType === pattern;
98
+ });
99
+ }
100
+ /**
101
+ * Download binary content and return base64
102
+ *
103
+ * @param skipAuth If true, download URL is fetched without authentication headers/params
104
+ * Metadata endpoint still requires auth, only the final download is unauthenticated
105
+ */
106
+ async downloadWithAuth(url, authCredentials, maxSize, timeout, skipAuth = false) {
107
+ const controller = new AbortController();
108
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
109
+ try {
110
+ // Build download URL, adding query auth param if needed (and not skipping auth)
111
+ let downloadUrl = url;
112
+ if (!skipAuth && authCredentials.queryParams) {
113
+ const urlObj = new URL(url);
114
+ const { key, value } = authCredentials.queryParams;
115
+ // Only add if not already present (URL may have pre-signed token)
116
+ if (!urlObj.searchParams.has(key)) {
117
+ urlObj.searchParams.set(key, value);
118
+ downloadUrl = urlObj.toString();
119
+ }
120
+ }
121
+ const response = await fetch(downloadUrl, {
122
+ headers: skipAuth ? {} : authCredentials.headers,
123
+ signal: controller.signal,
124
+ });
125
+ if (!response.ok) {
126
+ throw new NetworkError(`Download failed: HTTP ${response.status}`, response.status);
127
+ }
128
+ // Check content-length header
129
+ const contentLength = response.headers.get('content-length');
130
+ if (contentLength && parseInt(contentLength, 10) > maxSize) {
131
+ throw new ValidationError(`File size ${contentLength} exceeds maximum ${maxSize} bytes`);
132
+ }
133
+ const arrayBuffer = await response.arrayBuffer();
134
+ // Final size check
135
+ if (arrayBuffer.byteLength > maxSize) {
136
+ throw new ValidationError(`Downloaded file size ${arrayBuffer.byteLength} exceeds maximum ${maxSize} bytes`);
137
+ }
138
+ // Convert to base64
139
+ const bytes = new Uint8Array(arrayBuffer);
140
+ let binary = '';
141
+ for (let i = 0; i < bytes.byteLength; i++) {
142
+ binary += String.fromCharCode(bytes[i]);
143
+ }
144
+ const content = btoa(binary);
145
+ return {
146
+ content,
147
+ size: arrayBuffer.byteLength,
148
+ };
149
+ }
150
+ finally {
151
+ clearTimeout(timeoutId);
152
+ }
153
+ }
154
+ }
155
+ //# sourceMappingURL=proxy-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy-executor.js","sourceRoot":"","sources":["../../src/proxy-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { RequestHandler } from 'msw';
2
+ declare const DEFAULT_BASE_URL = "http://localhost/api";
3
+ export interface RequestLogEntry {
4
+ method: string;
5
+ url: string;
6
+ query: Record<string, string | string[]>;
7
+ }
8
+ export declare function createYoutrackHandlers(baseUrl?: string, requestLog?: RequestLogEntry[]): RequestHandler[];
9
+ export declare function createYoutrackMockServer(baseUrl?: string, requestLog?: RequestLogEntry[]): import("msw/node").SetupServerApi;
10
+ export { DEFAULT_BASE_URL as YOU_TRACK_DEFAULT_BASE_URL };
11
+ //# sourceMappingURL=mock-youtrack-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-youtrack-server.d.ts","sourceRoot":"","sources":["../../../src/testing/mock-youtrack-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,cAAc,EAAE,MAAM,KAAK,CAAC;AAGzD,QAAA,MAAM,gBAAgB,yBAAyB,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;CAC1C;AAuDD,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,MAAyB,EAClC,UAAU,CAAC,EAAE,eAAe,EAAE,GAC7B,cAAc,EAAE,CAwIlB;AAED,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,MAAyB,EAAE,UAAU,CAAC,EAAE,eAAe,EAAE,qCAG1G;AAED,OAAO,EAAE,gBAAgB,IAAI,0BAA0B,EAAE,CAAC"}
@@ -0,0 +1,138 @@
1
+ import { http, HttpResponse } from 'msw';
2
+ import { setupServer } from 'msw/node';
3
+ const DEFAULT_BASE_URL = 'http://localhost/api';
4
+ const baseIssue = {
5
+ id: 'YT-123',
6
+ idReadable: 'YT-123',
7
+ summary: 'Mock issue summary',
8
+ description: 'Mock issue description',
9
+ resolved: false,
10
+ };
11
+ const baseArticle = {
12
+ id: 'article-1',
13
+ title: 'Mock article',
14
+ summary: 'Mock summary',
15
+ content: 'Mock content',
16
+ };
17
+ const baseTag = { id: 'tag-1', name: 'Bug', color: '#ff0000' };
18
+ const baseUser = { id: 'user-1', login: 'mock-user', fullName: 'Mock User', email: 'user@example.com' };
19
+ function queryToRecord(searchParams) {
20
+ const entries = {};
21
+ for (const [key, value] of searchParams.entries()) {
22
+ if (entries[key]) {
23
+ const existing = entries[key];
24
+ entries[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];
25
+ }
26
+ else {
27
+ entries[key] = value;
28
+ }
29
+ }
30
+ return entries;
31
+ }
32
+ function createEchoResponse(request, payload = {}, requestLog) {
33
+ const url = new URL(request.url);
34
+ const query = queryToRecord(url.searchParams);
35
+ if (requestLog) {
36
+ requestLog.push({
37
+ method: request.method,
38
+ url: url.toString(),
39
+ query,
40
+ });
41
+ }
42
+ return {
43
+ path: url.pathname,
44
+ query,
45
+ method: request.method,
46
+ data: payload,
47
+ };
48
+ }
49
+ export function createYoutrackHandlers(baseUrl = DEFAULT_BASE_URL, requestLog) {
50
+ const withBase = (path) => typeof path === 'string' ? `${baseUrl}${path}` : new RegExp(`${baseUrl}${path.source}`);
51
+ const issueAttachment = {
52
+ id: 'att-1',
53
+ name: 'issue.txt',
54
+ mimeType: 'text/plain',
55
+ size: 12,
56
+ };
57
+ const articleAttachment = {
58
+ id: 'aat-1',
59
+ name: 'article.txt',
60
+ mimeType: 'text/plain',
61
+ size: 18,
62
+ };
63
+ const handlers = [
64
+ // Content retrieval
65
+ http.get(withBase('/issues'), ({ request }) => HttpResponse.json([createEchoResponse(request, baseIssue, requestLog)])),
66
+ http.get(withBase('/issues/:id'), ({ request, params }) => HttpResponse.json({ ...createEchoResponse(request, { ...baseIssue, id: params.id }, requestLog), comments: [], attachments: [] })),
67
+ http.get(withBase('/issues/:id/comments'), ({ request }) => HttpResponse.json([createEchoResponse(request, { id: 'c-1', text: 'mock comment', attachments: [] }, requestLog)])),
68
+ http.get(withBase('/issues/:id/comments/:commentId'), ({ request, params }) => HttpResponse.json(createEchoResponse(request, { id: params.commentId, text: 'comment detail', attachments: [] }, requestLog))),
69
+ http.get(withBase('/issues/:id/attachments'), ({ request }) => HttpResponse.json([createEchoResponse(request, issueAttachment, requestLog)])),
70
+ http.get(withBase('/issues/:id/attachments/:attachmentId'), ({ request, params }) => HttpResponse.json({
71
+ ...createEchoResponse(request, { ...issueAttachment, id: params.attachmentId }, requestLog),
72
+ url: `${baseUrl}/downloads/issues/${params.id}/${params.attachmentId}`,
73
+ })),
74
+ http.get(withBase('/issues/:id/tags'), ({ request }) => HttpResponse.json([createEchoResponse(request, baseTag, requestLog)])),
75
+ http.get(withBase('/issues/:id/links'), ({ request }) => HttpResponse.json([createEchoResponse(request, { id: 'link-1', direction: 'OUTWARD' }, requestLog)])),
76
+ http.get(withBase('/issues/:id/links/:linkId'), ({ request, params }) => HttpResponse.json(createEchoResponse(request, { id: params.linkId, direction: 'OUTWARD' }, requestLog))),
77
+ http.get(withBase('/issues/:id/links/:linkId/issues'), ({ request }) => HttpResponse.json([createEchoResponse(request, baseIssue, requestLog)])),
78
+ http.get(withBase('/workItems'), ({ request }) => HttpResponse.json([createEchoResponse(request, { id: 'work-1' }, requestLog)])),
79
+ http.get(withBase('/articles'), ({ request }) => HttpResponse.json([createEchoResponse(request, baseArticle, requestLog)])),
80
+ http.get(withBase('/articles/:id'), ({ request, params }) => HttpResponse.json({ ...createEchoResponse(request, { ...baseArticle, id: params.id }, requestLog), comments: [], attachments: [] })),
81
+ http.get(withBase('/articles/:id/comments'), ({ request, params }) => HttpResponse.json([createEchoResponse(request, { id: `ac-${params.id}`, text: 'article comment' }, requestLog)])),
82
+ http.get(withBase('/articles/:id/attachments'), ({ request }) => HttpResponse.json([createEchoResponse(request, articleAttachment, requestLog)])),
83
+ http.get(withBase('/articles/:id/attachments/:attachmentId'), ({ request, params }) => HttpResponse.json({
84
+ ...createEchoResponse(request, { ...articleAttachment, id: params.attachmentId }, requestLog),
85
+ url: `data:text/plain;base64,${Buffer.from('article attachment content').toString('base64')}`,
86
+ })),
87
+ http.get(withBase('/tags'), ({ request }) => HttpResponse.json([createEchoResponse(request, baseTag, requestLog)])),
88
+ http.get(withBase('/tags/:id'), ({ request, params }) => HttpResponse.json(createEchoResponse(request, { ...baseTag, id: params.id }, requestLog))),
89
+ http.get(withBase('/savedQueries'), ({ request }) => HttpResponse.json([createEchoResponse(request, { id: 'q-1' }, requestLog)])),
90
+ http.get(withBase('/agiles'), ({ request }) => HttpResponse.json([createEchoResponse(request, { id: 'agile-1' }, requestLog)])),
91
+ http.get(withBase('/agiles/:id'), ({ request, params }) => HttpResponse.json(createEchoResponse(request, { id: params.id, name: 'Agile Board' }, requestLog))),
92
+ http.get(withBase('/agiles/:id/sprints'), ({ request }) => HttpResponse.json([createEchoResponse(request, { id: 'sprint-1', name: 'Sprint' }, requestLog)])),
93
+ http.get(withBase('/users'), ({ request }) => HttpResponse.json([createEchoResponse(request, baseUser, requestLog)])),
94
+ http.get(withBase('/users/:id'), ({ request, params }) => HttpResponse.json(createEchoResponse(request, { ...baseUser, id: params.id }, requestLog))),
95
+ http.get(withBase('/groups'), ({ request }) => HttpResponse.json([createEchoResponse(request, { id: 'group-1', name: 'Mock Group' }, requestLog)])),
96
+ // Activity/history endpoints
97
+ http.get(withBase('/activities'), ({ request }) => HttpResponse.json([createEchoResponse(request, { id: 'act-1' }, requestLog)])),
98
+ http.get(withBase('/activities/:id'), ({ request, params }) => HttpResponse.json(createEchoResponse(request, { id: params.id, category: 'update' }, requestLog))),
99
+ http.get(withBase('/activitiesPage'), ({ request }) => HttpResponse.json([createEchoResponse(request, { id: 'page-1' }, requestLog)])),
100
+ http.get(withBase('/issues/:id/activities'), ({ request }) => HttpResponse.json([createEchoResponse(request, { id: 'act-issue-1' }, requestLog)])),
101
+ // Mutations
102
+ http.post(new RegExp(`${baseUrl}/.*`), async ({ request }) => {
103
+ const body = await request.json().catch(() => ({}));
104
+ return HttpResponse.json(createEchoResponse(request, body, requestLog), { status: 201 });
105
+ }),
106
+ http.put(new RegExp(`${baseUrl}/.*`), async ({ request }) => {
107
+ const body = await request.json().catch(() => ({}));
108
+ return HttpResponse.json(createEchoResponse(request, body, requestLog));
109
+ }),
110
+ http.patch(new RegExp(`${baseUrl}/.*`), async ({ request }) => {
111
+ const body = await request.json().catch(() => ({}));
112
+ return HttpResponse.json(createEchoResponse(request, body, requestLog));
113
+ }),
114
+ http.delete(new RegExp(`${baseUrl}/.*`), ({ request }) => HttpResponse.json(createEchoResponse(request, {}, requestLog))),
115
+ // Download endpoints (for proxy_download operations)
116
+ http.get(withBase('/downloads/issues/:id/:attachmentId'), () => HttpResponse.text('issue attachment content', {
117
+ headers: {
118
+ 'content-type': 'text/plain',
119
+ 'content-length': '24',
120
+ },
121
+ })),
122
+ http.get(withBase('/downloads/articles/:id/:attachmentId'), () => HttpResponse.text('article attachment content', {
123
+ headers: {
124
+ 'content-type': 'text/plain',
125
+ 'content-length': '27',
126
+ },
127
+ })),
128
+ ];
129
+ // Generic GET fallback to avoid 404s for any missing endpoint
130
+ handlers.push(http.get(new RegExp(`${baseUrl}/.*`), ({ request }) => HttpResponse.json(createEchoResponse(request, {}, requestLog))));
131
+ return handlers;
132
+ }
133
+ export function createYoutrackMockServer(baseUrl = DEFAULT_BASE_URL, requestLog) {
134
+ const handlers = createYoutrackHandlers(baseUrl, requestLog);
135
+ return setupServer(...handlers);
136
+ }
137
+ export { DEFAULT_BASE_URL as YOU_TRACK_DEFAULT_BASE_URL };
138
+ //# sourceMappingURL=mock-youtrack-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-youtrack-server.js","sourceRoot":"","sources":["../../../src/testing/mock-youtrack-server.ts"],"names":[],"mappings":"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"}
@@ -60,12 +60,10 @@ export function restoreFetch() {
60
60
  * Test helper for HTTP client tests
61
61
  */
62
62
  export class HttpTestHelper {
63
- baseUrl;
64
- interceptors;
65
- capturedHeaders = {};
66
63
  constructor(baseUrl = 'https://api.example.com', interceptors = {}) {
67
64
  this.baseUrl = baseUrl;
68
65
  this.interceptors = interceptors;
66
+ this.capturedHeaders = {};
69
67
  this.setupMock();
70
68
  }
71
69
  setupMock() {
@@ -1 +1 @@
1
- {"version":3,"file":"test-http-utils.js","sourceRoot":"","sources":["../../../src/testing/test-http-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAMlE;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,UAAwB,yBAAyB,EACjD,eAAkC,EAAE;IAEpC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC5D,OAAO,IAAI,UAAU,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,eAAoB,EAAE,EAAE,EAAE,IAAI,EAAE,EAChC,kBAAgC,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,EAAE;IAEhG,MAAM,eAAe,GAAuC,EAAE,CAAC;IAE/D,MAAM,CAAC,KAAK,GAAG,KAAK,EAAE,GAAuB,EAAE,IAAkB,EAAE,EAAE;QACnE,oCAAoC;QACpC,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,OAA6C,IAAI,EAAE,CAAC,CAAC;QAC1F,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,eAAe,CAAC,CAAC;IACrE,CAAC,CAAC;IAEF,OAAO,EAAE,eAAe,EAAE,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB,GAAG,EAAE,UAAwB,uBAAuB;IACvG,MAAM,CAAC,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;QACnE,MAAM;QACN,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B;IACxC,MAAM,CAAC,KAAK,GAAG,KAAK,IAAI,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,CAAC,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE;QAC5C,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;KACjC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAQ,MAAc,CAAC,KAAK,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,cAAc;IAIf;IACA;IAJF,eAAe,GAAuC,EAAE,CAAC;IAEjE,YACU,UAAwB,yBAAyB,EACjD,eAAkC,EAAE;QADpC,YAAO,GAAP,OAAO,CAA0C;QACjD,iBAAY,GAAZ,YAAY,CAAwB;QAE5C,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAEO,SAAS;QACf,MAAM,CAAC,KAAK,GAAG,KAAK,EAAE,GAAuB,EAAE,IAAkB,EAAE,EAAE;YACnE,IAAI,CAAC,eAAe,GAAG,IAAI,EAAE,OAA6C,CAAC;YAC3E,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;gBAChD,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;aAChD,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;IAED,SAAS;QACP,OAAO,oBAAoB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAC/D,CAAC;IAED,kBAAkB;QAChB,OAAO,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;IACrC,CAAC;IAED,WAAW,CAAC,YAAiB,EAAE,OAAsB;QACnD,MAAM,CAAC,KAAK,GAAG,KAAK,EAAE,GAAuB,EAAE,IAAkB,EAAE,EAAE;YACnE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE,OAA6C,IAAI,EAAE,CAAC,CAAC;YAC/F,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE;gBAChD,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,GAAG,OAAO;aACX,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;IAED,gBAAgB,CAAC,MAAc,EAAE,OAAqB;QACpD,MAAM,CAAC,KAAK,GAAG,KAAK,EAAE,GAAuB,EAAE,IAAkB,EAAE,EAAE;YACnE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE,OAA6C,IAAI,EAAE,CAAC,CAAC;YAC/F,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;gBAC/C,MAAM;gBACN,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;aAChD,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,YAAY,EAAE,CAAC;IACjB,CAAC;CACF"}
1
+ {"version":3,"file":"test-http-utils.js","sourceRoot":"","sources":["../../../src/testing/test-http-utils.ts"],"names":[],"mappings":"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"}
@@ -61,12 +61,37 @@ export interface MergeRequest {
61
61
  created_at: string;
62
62
  updated_at: string;
63
63
  }
64
+ export interface Issue {
65
+ id: number;
66
+ iid: number;
67
+ project_id: number;
68
+ title: string;
69
+ description: string;
70
+ state: string;
71
+ created_at: string;
72
+ updated_at: string;
73
+ closed_at: null;
74
+ closed_by: null;
75
+ labels: string[];
76
+ milestone: null;
77
+ assignees: any[];
78
+ author: {
79
+ id: number;
80
+ username: string;
81
+ name: string;
82
+ avatar_url: string;
83
+ };
84
+ web_url: string;
85
+ confidential: boolean;
86
+ discussion_locked: boolean;
87
+ }
64
88
  export interface CompositeResult {
65
89
  data: Record<string, unknown>;
66
90
  completed_steps: number;
67
91
  total_steps: number;
68
92
  errors?: Array<{
69
- step: string;
93
+ step_index: number;
94
+ step_call: string;
70
95
  error: string;
71
96
  }>;
72
97
  }
@@ -1 +1 @@
1
- {"version":3,"file":"test-types.d.ts","sourceRoot":"","sources":["../../../src/testing/test-types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AAED,MAAM,MAAM,aAAa,GACrB,KAAK,EAAE,GACP,KAAK,GACL,MAAM,EAAE,GACR,MAAM,GACN,aAAa,EAAE,GACf,aAAa,GACb,GAAG,EAAE,GACL,GAAG,GACH,YAAY,EAAE,GACd,YAAY,GACZ,eAAe,GACf;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"test-types.d.ts","sourceRoot":"","sources":["../../../src/testing/test-types.ts"],"names":[],"mappings":"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"}
@@ -32,12 +32,35 @@ export declare class ToolGenerator {
32
32
  * which JSON Schema can't express directly.
33
33
  */
34
34
  validateArguments(toolDef: ToolDefinition, args: Record<string, unknown>): void;
35
+ /**
36
+ * Get operation definition (string or ProxyDownloadOperation) for action
37
+ *
38
+ * Why: Tools can have string operationIds OR proxy_download configs.
39
+ * This returns the raw definition before extracting operationId.
40
+ */
41
+ getOperationDefinition(toolDef: ToolDefinition, args: Record<string, unknown>): import("./types/profile.js").OperationDefinition | undefined;
35
42
  /**
36
43
  * Map tool action to OpenAPI operation ID
37
44
  *
38
45
  * Why: Single tool with 'action' parameter maps to multiple operations.
39
46
  * Example: manage_badges + action=create => postApiV4ProjectsIdBadges
47
+ *
48
+ * Note: Returns undefined for ProxyDownloadOperation (not a direct operationId)
40
49
  */
41
50
  mapActionToOperation(toolDef: ToolDefinition, args: Record<string, unknown>): string | undefined;
51
+ /**
52
+ * Check if operation requires multipart/form-data
53
+ *
54
+ * Why: Some operations (file uploads) need FormData instead of JSON body.
55
+ * Detected from OpenAPI requestBody.content['multipart/form-data'].
56
+ */
57
+ isMultipartOperation(operationId: string): boolean;
58
+ /**
59
+ * Build FormData body for file upload
60
+ *
61
+ * @param args Tool arguments including base64Content or filePath
62
+ * @param fileFieldName Field name in FormData (default: 'files[0]')
63
+ */
64
+ buildFormDataBody(args: Record<string, unknown>, fileFieldName?: string): FormData;
42
65
  }
43
66
  //# sourceMappingURL=tool-generator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-generator.d.ts","sourceRoot":"","sources":["../../src/tool-generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,qBAAa,aAAa;IACZ,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEzC;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAU3C;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAqB7B;;;;;OAKG;IACH,iBAAiB,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IA4B/E;;;;;OAKG;IACH,oBAAoB,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS;CAwBjG"}
1
+ {"version":3,"file":"tool-generator.d.ts","sourceRoot":"","sources":["../../src/tool-generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,qBAAa,aAAa;IACZ,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEzC;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAU3C;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA0B7B;;;;;OAKG;IACH,iBAAiB,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IA4B/E;;;;;OAKG;IACH,sBAAsB,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAyB7E;;;;;;;OAOG;IACH,oBAAoB,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS;IAKhG;;;;;OAKG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAMlD;;;;;OAKG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,SAAa,GAAG,QAAQ;CAoBvF"}
@@ -5,7 +5,6 @@
5
5
  * simple (single operation) and composite (multi-step) tools.
6
6
  */
7
7
  export class ToolGenerator {
8
- parser;
9
8
  constructor(parser) {
10
9
  this.parser = parser;
11
10
  }
@@ -65,6 +64,10 @@ export class ToolGenerator {
65
64
  if (param.type === 'array' && param.items) {
66
65
  schema.items = { type: param.items.type };
67
66
  }
67
+ if (param.type === 'object') {
68
+ // Always include properties for object type (empty {} = free-form object)
69
+ schema.properties = param.properties || {};
70
+ }
68
71
  return schema;
69
72
  }
70
73
  /**
@@ -94,12 +97,12 @@ export class ToolGenerator {
94
97
  }
95
98
  }
96
99
  /**
97
- * Map tool action to OpenAPI operation ID
100
+ * Get operation definition (string or ProxyDownloadOperation) for action
98
101
  *
99
- * Why: Single tool with 'action' parameter maps to multiple operations.
100
- * Example: manage_badges + action=create => postApiV4ProjectsIdBadges
102
+ * Why: Tools can have string operationIds OR proxy_download configs.
103
+ * This returns the raw definition before extracting operationId.
101
104
  */
102
- mapActionToOperation(toolDef, args) {
105
+ getOperationDefinition(toolDef, args) {
103
106
  if (!toolDef.operations)
104
107
  return undefined;
105
108
  const action = args['action'];
@@ -119,5 +122,52 @@ export class ToolGenerator {
119
122
  }
120
123
  return toolDef.operations[action];
121
124
  }
125
+ /**
126
+ * Map tool action to OpenAPI operation ID
127
+ *
128
+ * Why: Single tool with 'action' parameter maps to multiple operations.
129
+ * Example: manage_badges + action=create => postApiV4ProjectsIdBadges
130
+ *
131
+ * Note: Returns undefined for ProxyDownloadOperation (not a direct operationId)
132
+ */
133
+ mapActionToOperation(toolDef, args) {
134
+ const op = this.getOperationDefinition(toolDef, args);
135
+ return typeof op === 'string' ? op : undefined;
136
+ }
137
+ /**
138
+ * Check if operation requires multipart/form-data
139
+ *
140
+ * Why: Some operations (file uploads) need FormData instead of JSON body.
141
+ * Detected from OpenAPI requestBody.content['multipart/form-data'].
142
+ */
143
+ isMultipartOperation(operationId) {
144
+ const operation = this.parser.getOperation(operationId);
145
+ if (!operation?.requestBody?.content)
146
+ return false;
147
+ return 'multipart/form-data' in operation.requestBody.content;
148
+ }
149
+ /**
150
+ * Build FormData body for file upload
151
+ *
152
+ * @param args Tool arguments including base64Content or filePath
153
+ * @param fileFieldName Field name in FormData (default: 'files[0]')
154
+ */
155
+ buildFormDataBody(args, fileFieldName = 'files[0]') {
156
+ const formData = new FormData();
157
+ const base64Content = args['base64Content'];
158
+ const fileName = args['fileName'] || 'upload';
159
+ const mimeType = args['mimeType'] || 'application/octet-stream';
160
+ if (base64Content) {
161
+ // Convert base64 to Blob
162
+ const binaryString = atob(base64Content);
163
+ const bytes = new Uint8Array(binaryString.length);
164
+ for (let i = 0; i < binaryString.length; i++) {
165
+ bytes[i] = binaryString.charCodeAt(i);
166
+ }
167
+ const blob = new Blob([bytes], { type: mimeType });
168
+ formData.append(fileFieldName, blob, fileName);
169
+ }
170
+ return formData;
171
+ }
122
172
  }
123
173
  //# sourceMappingURL=tool-generator.js.map