@commandable/mcp-core 0.2.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 (157) hide show
  1. package/LICENSE +10 -0
  2. package/README.md +8 -0
  3. package/dist/config/configApply.d.ts +16 -0
  4. package/dist/config/configApply.d.ts.map +1 -0
  5. package/dist/config/configApply.js +77 -0
  6. package/dist/config/configApply.js.map +1 -0
  7. package/dist/config/configLoader.d.ts +9 -0
  8. package/dist/config/configLoader.d.ts.map +1 -0
  9. package/dist/config/configLoader.js +75 -0
  10. package/dist/config/configLoader.js.map +1 -0
  11. package/dist/config/configSchema.d.ts +45 -0
  12. package/dist/config/configSchema.d.ts.map +1 -0
  13. package/dist/config/configSchema.js +23 -0
  14. package/dist/config/configSchema.js.map +1 -0
  15. package/dist/crypto/encryption.d.ts +3 -0
  16. package/dist/crypto/encryption.d.ts.map +1 -0
  17. package/dist/crypto/encryption.js +29 -0
  18. package/dist/crypto/encryption.js.map +1 -0
  19. package/dist/db/client.d.ts +24 -0
  20. package/dist/db/client.d.ts.map +1 -0
  21. package/dist/db/client.js +50 -0
  22. package/dist/db/client.js.map +1 -0
  23. package/dist/db/credentialStore.d.ts +15 -0
  24. package/dist/db/credentialStore.d.ts.map +1 -0
  25. package/dist/db/credentialStore.js +56 -0
  26. package/dist/db/credentialStore.js.map +1 -0
  27. package/dist/db/integrationStore.d.ts +14 -0
  28. package/dist/db/integrationStore.d.ts.map +1 -0
  29. package/dist/db/integrationStore.js +128 -0
  30. package/dist/db/integrationStore.js.map +1 -0
  31. package/dist/db/integrationTypeConfigStore.d.ts +7 -0
  32. package/dist/db/integrationTypeConfigStore.d.ts.map +1 -0
  33. package/dist/db/integrationTypeConfigStore.js +101 -0
  34. package/dist/db/integrationTypeConfigStore.js.map +1 -0
  35. package/dist/db/migrate.d.ts +3 -0
  36. package/dist/db/migrate.d.ts.map +1 -0
  37. package/dist/db/migrate.js +11 -0
  38. package/dist/db/migrate.js.map +1 -0
  39. package/dist/db/migrations/pg/0000_initial.sql +74 -0
  40. package/dist/db/migrations/pg/meta/_journal.json +13 -0
  41. package/dist/db/migrations/sqlite/0000_initial.sql +74 -0
  42. package/dist/db/migrations/sqlite/meta/_journal.json +13 -0
  43. package/dist/db/schema.d.ts +1863 -0
  44. package/dist/db/schema.d.ts.map +1 -0
  45. package/dist/db/schema.js +133 -0
  46. package/dist/db/schema.js.map +1 -0
  47. package/dist/db/toolDefinitionStore.d.ts +9 -0
  48. package/dist/db/toolDefinitionStore.d.ts.map +1 -0
  49. package/dist/db/toolDefinitionStore.js +117 -0
  50. package/dist/db/toolDefinitionStore.js.map +1 -0
  51. package/dist/errors/httpError.d.ts +6 -0
  52. package/dist/errors/httpError.d.ts.map +1 -0
  53. package/dist/errors/httpError.js +11 -0
  54. package/dist/errors/httpError.js.map +1 -0
  55. package/dist/index.d.ts +34 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +34 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/integrations/actionsFactory.d.ts +16 -0
  60. package/dist/integrations/actionsFactory.d.ts.map +1 -0
  61. package/dist/integrations/actionsFactory.js +98 -0
  62. package/dist/integrations/actionsFactory.js.map +1 -0
  63. package/dist/integrations/catalog.d.ts +8 -0
  64. package/dist/integrations/catalog.d.ts.map +1 -0
  65. package/dist/integrations/catalog.js +45 -0
  66. package/dist/integrations/catalog.js.map +1 -0
  67. package/dist/integrations/customToolFactory.d.ts +13 -0
  68. package/dist/integrations/customToolFactory.d.ts.map +1 -0
  69. package/dist/integrations/customToolFactory.js +31 -0
  70. package/dist/integrations/customToolFactory.js.map +1 -0
  71. package/dist/integrations/dataLoader.d.ts +3 -0
  72. package/dist/integrations/dataLoader.d.ts.map +1 -0
  73. package/dist/integrations/dataLoader.js +2 -0
  74. package/dist/integrations/dataLoader.js.map +1 -0
  75. package/dist/integrations/fileIntegrationTypeConfigStore.d.ts +7 -0
  76. package/dist/integrations/fileIntegrationTypeConfigStore.d.ts.map +1 -0
  77. package/dist/integrations/fileIntegrationTypeConfigStore.js +34 -0
  78. package/dist/integrations/fileIntegrationTypeConfigStore.js.map +1 -0
  79. package/dist/integrations/getIntegration.d.ts +14 -0
  80. package/dist/integrations/getIntegration.d.ts.map +1 -0
  81. package/dist/integrations/getIntegration.js +30 -0
  82. package/dist/integrations/getIntegration.js.map +1 -0
  83. package/dist/integrations/googleServiceAccount.d.ts +6 -0
  84. package/dist/integrations/googleServiceAccount.d.ts.map +1 -0
  85. package/dist/integrations/googleServiceAccount.js +54 -0
  86. package/dist/integrations/googleServiceAccount.js.map +1 -0
  87. package/dist/integrations/health.d.ts +20 -0
  88. package/dist/integrations/health.d.ts.map +1 -0
  89. package/dist/integrations/health.js +43 -0
  90. package/dist/integrations/health.js.map +1 -0
  91. package/dist/integrations/integrationTypeConfigLookup.d.ts +12 -0
  92. package/dist/integrations/integrationTypeConfigLookup.d.ts.map +1 -0
  93. package/dist/integrations/integrationTypeConfigLookup.js +11 -0
  94. package/dist/integrations/integrationTypeConfigLookup.js.map +1 -0
  95. package/dist/integrations/providerRegistry.d.ts +2 -0
  96. package/dist/integrations/providerRegistry.d.ts.map +1 -0
  97. package/dist/integrations/providerRegistry.js +72 -0
  98. package/dist/integrations/providerRegistry.js.map +1 -0
  99. package/dist/integrations/proxy.d.ts +19 -0
  100. package/dist/integrations/proxy.d.ts.map +1 -0
  101. package/dist/integrations/proxy.js +377 -0
  102. package/dist/integrations/proxy.js.map +1 -0
  103. package/dist/integrations/sandbox.d.ts +8 -0
  104. package/dist/integrations/sandbox.d.ts.map +1 -0
  105. package/dist/integrations/sandbox.js +221 -0
  106. package/dist/integrations/sandbox.js.map +1 -0
  107. package/dist/integrations/sandboxUtils.d.ts +15 -0
  108. package/dist/integrations/sandboxUtils.d.ts.map +1 -0
  109. package/dist/integrations/sandboxUtils.js +489 -0
  110. package/dist/integrations/sandboxUtils.js.map +1 -0
  111. package/dist/integrations/tools.d.ts +3 -0
  112. package/dist/integrations/tools.d.ts.map +1 -0
  113. package/dist/integrations/tools.js +70 -0
  114. package/dist/integrations/tools.js.map +1 -0
  115. package/dist/mcp/abilityCatalog.d.ts +51 -0
  116. package/dist/mcp/abilityCatalog.d.ts.map +1 -0
  117. package/dist/mcp/abilityCatalog.js +300 -0
  118. package/dist/mcp/abilityCatalog.js.map +1 -0
  119. package/dist/mcp/auth.d.ts +18 -0
  120. package/dist/mcp/auth.d.ts.map +1 -0
  121. package/dist/mcp/auth.js +45 -0
  122. package/dist/mcp/auth.js.map +1 -0
  123. package/dist/mcp/builder_guide.md +441 -0
  124. package/dist/mcp/commandable_readme.md +29 -0
  125. package/dist/mcp/handlers.d.ts +21 -0
  126. package/dist/mcp/handlers.d.ts.map +1 -0
  127. package/dist/mcp/handlers.js +86 -0
  128. package/dist/mcp/handlers.js.map +1 -0
  129. package/dist/mcp/metaTools.d.ts +79 -0
  130. package/dist/mcp/metaTools.d.ts.map +1 -0
  131. package/dist/mcp/metaTools.js +901 -0
  132. package/dist/mcp/metaTools.js.map +1 -0
  133. package/dist/mcp/server.d.ts +25 -0
  134. package/dist/mcp/server.d.ts.map +1 -0
  135. package/dist/mcp/server.js +14 -0
  136. package/dist/mcp/server.js.map +1 -0
  137. package/dist/mcp/sessionState.d.ts +19 -0
  138. package/dist/mcp/sessionState.d.ts.map +1 -0
  139. package/dist/mcp/sessionState.js +79 -0
  140. package/dist/mcp/sessionState.js.map +1 -0
  141. package/dist/mcp/toolAdapter.d.ts +34 -0
  142. package/dist/mcp/toolAdapter.d.ts.map +1 -0
  143. package/dist/mcp/toolAdapter.js +24 -0
  144. package/dist/mcp/toolAdapter.js.map +1 -0
  145. package/dist/runtime/credentialManager.d.ts +19 -0
  146. package/dist/runtime/credentialManager.d.ts.map +1 -0
  147. package/dist/runtime/credentialManager.js +82 -0
  148. package/dist/runtime/credentialManager.js.map +1 -0
  149. package/dist/runtime/stdioSession.d.ts +8 -0
  150. package/dist/runtime/stdioSession.d.ts.map +1 -0
  151. package/dist/runtime/stdioSession.js +79 -0
  152. package/dist/runtime/stdioSession.js.map +1 -0
  153. package/dist/types.d.ts +92 -0
  154. package/dist/types.d.ts.map +1 -0
  155. package/dist/types.js +2 -0
  156. package/dist/types.js.map +1 -0
  157. package/package.json +64 -0
@@ -0,0 +1,377 @@
1
+ import { Buffer } from 'node:buffer';
2
+ import { HttpError } from '../errors/httpError.js';
3
+ import { PROVIDERS } from './providerRegistry.js';
4
+ import { getBuiltInIntegrationTypeConfig } from './fileIntegrationTypeConfigStore.js';
5
+ import { getGoogleAccessToken } from './googleServiceAccount.js';
6
+ function getErrorHint(status, provider, bodyText) {
7
+ const isGoogle = provider.startsWith('google-');
8
+ if (status === 401) {
9
+ if (isGoogle)
10
+ return 'Authentication failed. Check that the credential token is valid and not expired. For service accounts, verify the service account has been granted access to the resource.';
11
+ return 'Authentication failed. Check that the credential is valid and not expired.';
12
+ }
13
+ if (status === 403) {
14
+ if (isGoogle)
15
+ return 'Permission denied. The credential does not have sufficient scopes or access to this resource. Ensure the required API scopes are enabled and the service account has been shared access to the resource.';
16
+ return 'Permission denied. The credential does not have sufficient scopes or access to this resource.';
17
+ }
18
+ if (status === 404) {
19
+ if (isGoogle)
20
+ return 'Resource not found. The ID may be invalid or the resource may have been deleted. Use the appropriate list or search tool to find valid IDs. For Google Drive, ensure the service account has been granted access to the file or folder.';
21
+ return 'Resource not found. Verify the ID is correct and the resource exists.';
22
+ }
23
+ if (status === 409)
24
+ return 'Conflict. The resource already exists or there is a version conflict. Try fetching the current state before retrying.';
25
+ if (status === 429)
26
+ return 'Rate limit exceeded. The API quota has been reached. Wait a moment before retrying the request.';
27
+ if (status === 400) {
28
+ if (bodyText.includes('invalidQuery') || bodyText.includes('Invalid query'))
29
+ return 'Invalid query syntax. Check the query parameter format for this API.';
30
+ if (bodyText.includes('Invalid value') || bodyText.includes('invalid value'))
31
+ return 'A parameter value is invalid. Check enum values, required fields, and data formats (e.g. RFC3339 for dates).';
32
+ if (bodyText.includes('required'))
33
+ return 'A required parameter is missing. Check that all required fields are provided.';
34
+ return 'Bad request. Check that all required parameters are provided, values are in the correct format, and the request body matches the expected schema.';
35
+ }
36
+ if (status === 500 || status === 503)
37
+ return 'The upstream API returned a server error. This is likely a temporary issue -- retry the request after a short delay.';
38
+ return '';
39
+ }
40
+ function buildCredentialUrl(integrationId) {
41
+ const portRaw = process.env.COMMANDABLE_UI_PORT;
42
+ const port = portRaw && /^\d+$/.test(portRaw) ? Number(portRaw) : 23432;
43
+ return `http://127.0.0.1:${port}/integrations/${encodeURIComponent(integrationId)}`;
44
+ }
45
+ export class IntegrationProxy {
46
+ opts;
47
+ constructor(opts = {}) {
48
+ this.opts = opts;
49
+ }
50
+ async call(integration, path, init = {}) {
51
+ const { type: provider, connectionId } = integration;
52
+ if (!provider || !path)
53
+ throw new HttpError(400, 'provider and path are required.');
54
+ const joinWithoutDuplicateSegments = (baseUrl, rawPath) => {
55
+ let pathOnly = rawPath || '';
56
+ let queryPart = '';
57
+ const qIndex = pathOnly.indexOf('?');
58
+ if (qIndex >= 0) {
59
+ queryPart = pathOnly.slice(qIndex + 1);
60
+ pathOnly = pathOnly.slice(0, qIndex);
61
+ }
62
+ try {
63
+ const base = new URL(baseUrl);
64
+ const baseSegs = base.pathname.split('/').filter(Boolean);
65
+ const pathSegs = (pathOnly || '/').split('/').filter(Boolean);
66
+ let overlap = 0;
67
+ const maxK = Math.min(baseSegs.length, pathSegs.length);
68
+ for (let k = maxK; k >= 1; k--) {
69
+ let ok = true;
70
+ for (let i = 0; i < k; i++) {
71
+ if (baseSegs[baseSegs.length - k + i] !== pathSegs[i]) {
72
+ ok = false;
73
+ break;
74
+ }
75
+ }
76
+ if (ok) {
77
+ overlap = k;
78
+ break;
79
+ }
80
+ }
81
+ const normalizedPath = `/${[...baseSegs, ...pathSegs.slice(overlap)].join('/')}`;
82
+ const baseOrigin = base.origin;
83
+ const urlNoQuery = `${baseOrigin}${normalizedPath}`;
84
+ return queryPart ? `${urlNoQuery}?${queryPart}` : urlNoQuery;
85
+ }
86
+ catch {
87
+ const cleanedBase = baseUrl.replace(/\/+$/, '');
88
+ const cleanedPath = (`/${(pathOnly || '').replace(/^\/+/, '')}`);
89
+ const baseParts = cleanedBase.split('/').filter(Boolean);
90
+ const pathParts = cleanedPath.split('/').filter(Boolean);
91
+ let overlap = 0;
92
+ const maxK = Math.min(baseParts.length, pathParts.length);
93
+ for (let k = maxK; k >= 1; k--) {
94
+ let ok = true;
95
+ for (let i = 0; i < k; i++) {
96
+ if (baseParts[baseParts.length - k + i] !== pathParts[i]) {
97
+ ok = false;
98
+ break;
99
+ }
100
+ }
101
+ if (ok) {
102
+ overlap = k;
103
+ break;
104
+ }
105
+ }
106
+ const joined = `/${[...baseParts, ...pathParts.slice(overlap)].join('/')}`;
107
+ return queryPart ? `${joined}?${queryPart}` : joined;
108
+ }
109
+ };
110
+ const usesCredentials = integration.connectionMethod === 'credentials';
111
+ if (usesCredentials) {
112
+ if (!this.opts.credentialStore)
113
+ throw new HttpError(500, 'Credential storage is not configured.');
114
+ const spaceId = integration.spaceId;
115
+ if (!spaceId)
116
+ throw new HttpError(400, 'spaceId is required for credentials-based integrations.');
117
+ const credentialId = integration.credentialId;
118
+ if (!credentialId)
119
+ throw new HttpError(400, 'credentialId is required for credentials-based integrations.');
120
+ // Resolve integration type config — file-backed built-ins first, then in-memory DB cache.
121
+ const fileTypeCfg = getBuiltInIntegrationTypeConfig(provider);
122
+ const typeCfg = fileTypeCfg
123
+ ?? (this.opts.integrationTypeConfigsRef?.current.find(c => c.spaceId === spaceId && c.typeSlug === provider) ?? null);
124
+ if (!typeCfg)
125
+ throw new HttpError(501, `Provider '${provider}' does not support credentials-based auth yet.`);
126
+ const variantKey = integration.credentialVariant || typeCfg.defaultVariant;
127
+ const variant = typeCfg.variants[variantKey]
128
+ ?? typeCfg.variants[typeCfg.defaultVariant];
129
+ if (!variant)
130
+ throw new HttpError(501, `Variant '${variantKey}' not found for provider '${provider}'.`);
131
+ const creds = await this.opts.credentialStore.getCredentials(spaceId, credentialId);
132
+ if (!creds) {
133
+ const credentialUrl = buildCredentialUrl(integration.id);
134
+ throw new HttpError(400, `No credentials are configured for this integration. Open ${credentialUrl} to configure them.`, {
135
+ reason: 'missing_credentials',
136
+ credential_url: credentialUrl,
137
+ });
138
+ }
139
+ const resolveTemplate = (template) => {
140
+ return String(template).replace(/\{\{\s*([^}]+?)\s*\}\}/g, (_m, expr) => {
141
+ const trimmed = expr.trim();
142
+ // base64(...) transform: supports field refs and string literals joined with +
143
+ // e.g. {{base64(email + ":" + apiToken)}}
144
+ const base64Match = trimmed.match(/^base64\((.+)\)$/);
145
+ if (base64Match) {
146
+ const base64Expr = base64Match[1];
147
+ if (base64Expr === undefined)
148
+ throw new HttpError(400, `Invalid base64 template expression '${trimmed}'.`);
149
+ const parts = base64Expr.split(/\s*\+\s*/);
150
+ const resolved = parts.map(part => {
151
+ const p = part.trim();
152
+ if ((p.startsWith('"') && p.endsWith('"')) || (p.startsWith("'") && p.endsWith("'")))
153
+ return p.slice(1, -1);
154
+ const v = creds[p];
155
+ if (v === undefined || v === null)
156
+ throw new HttpError(400, `Missing credential field '${p}'.`);
157
+ return String(v);
158
+ }).join('');
159
+ return Buffer.from(resolved).toString('base64');
160
+ }
161
+ // Simple field reference
162
+ const v = creds[trimmed];
163
+ if (v === undefined || v === null)
164
+ throw new HttpError(400, `Missing credential field '${trimmed}'.`);
165
+ return String(v);
166
+ });
167
+ };
168
+ // Resolve base URL: template takes priority over fixed URL, then PROVIDERS registry fallback.
169
+ const baseUrl = (() => {
170
+ if (variant.baseUrlTemplate)
171
+ return resolveTemplate(variant.baseUrlTemplate);
172
+ if (variant.baseUrl)
173
+ return variant.baseUrl;
174
+ // Fallback: PROVIDERS registry (used by built-ins that derive URL from provider config).
175
+ const providerCfg = PROVIDERS[provider];
176
+ if (providerCfg) {
177
+ return typeof providerCfg.baseUrl === 'function'
178
+ ? providerCfg.baseUrl(integration, creds, variant)
179
+ : providerCfg.baseUrl;
180
+ }
181
+ throw new HttpError(501, `No base URL configured for provider '${provider}'.`);
182
+ })();
183
+ const typeConfig = { baseUrl, auth: variant.auth, preprocess: variant.preprocess ?? null };
184
+ // Preprocess steps (e.g. service account token exchange, Basic Auth encoding).
185
+ if (typeConfig.preprocess === 'google_service_account') {
186
+ const serviceAccountJson = creds.serviceAccountJson;
187
+ if (!serviceAccountJson)
188
+ throw new HttpError(400, `Integration '${provider}' requires a 'serviceAccountJson' credential for the service_account variant.`);
189
+ const subject = typeof creds.subject === 'string' ? creds.subject : undefined;
190
+ const rawScopes = creds.scopes;
191
+ const scopesFromCreds = Array.isArray(rawScopes)
192
+ ? rawScopes.map((s) => String(s)).filter(Boolean)
193
+ : (typeof rawScopes === 'string'
194
+ ? rawScopes.split(/[,\s]+/g).map(s => s.trim()).filter(Boolean)
195
+ : []);
196
+ const defaultScopes = {
197
+ 'google-sheet': ['https://www.googleapis.com/auth/spreadsheets'],
198
+ 'google-docs': ['https://www.googleapis.com/auth/documents', 'https://www.googleapis.com/auth/drive'],
199
+ 'google-slides': ['https://www.googleapis.com/auth/presentations', 'https://www.googleapis.com/auth/drive'],
200
+ 'google-calendar': ['https://www.googleapis.com/auth/calendar'],
201
+ 'google-drive': ['https://www.googleapis.com/auth/drive'],
202
+ 'google-gmail': ['https://mail.google.com/'],
203
+ };
204
+ const scopes = scopesFromCreds.length ? scopesFromCreds : (defaultScopes[provider] || []);
205
+ if (!scopes.length)
206
+ throw new HttpError(400, `Missing OAuth scopes for Google integration '${provider}'.`);
207
+ const token = await getGoogleAccessToken({ serviceAccountJson, scopes, subject });
208
+ creds.token = token;
209
+ }
210
+ const resolvedHeaders = {};
211
+ const resolvedQuery = new URLSearchParams();
212
+ if (typeConfig.auth.kind === 'basic') {
213
+ const username = creds[typeConfig.auth.usernameField];
214
+ const password = creds[typeConfig.auth.passwordField];
215
+ if (username == null || password == null) {
216
+ throw new HttpError(400, `Missing credential fields for basic auth: '${typeConfig.auth.usernameField}' and/or '${typeConfig.auth.passwordField}'.`);
217
+ }
218
+ const token = Buffer.from(`${username}:${password}`).toString('base64');
219
+ resolvedHeaders.Authorization = `Basic ${token}`;
220
+ }
221
+ else {
222
+ for (const [k, v] of Object.entries(typeConfig.auth.injection?.headers || {}))
223
+ resolvedHeaders[k] = resolveTemplate(v);
224
+ for (const [k, v] of Object.entries(typeConfig.auth.injection?.query || {}))
225
+ resolvedQuery.set(k, resolveTemplate(v));
226
+ }
227
+ let finalUrl = joinWithoutDuplicateSegments(typeConfig.baseUrl, path);
228
+ const queryString = resolvedQuery.toString();
229
+ if (queryString)
230
+ finalUrl = finalUrl + (finalUrl.includes('?') ? '&' : '?') + queryString;
231
+ const preparedInit = { ...init };
232
+ if (preparedInit.body !== undefined && typeof preparedInit.body !== 'string') {
233
+ preparedInit.body = JSON.stringify(preparedInit.body);
234
+ preparedInit.headers = {
235
+ 'Content-Type': 'application/json',
236
+ ...preparedInit.headers,
237
+ };
238
+ }
239
+ const redact = (s) => {
240
+ let out = s;
241
+ for (const val of Object.values(creds)) {
242
+ if (typeof val === 'string' && val.length)
243
+ out = out.split(val).join('***');
244
+ }
245
+ return out;
246
+ };
247
+ const response = await fetch(finalUrl, {
248
+ ...preparedInit,
249
+ method: preparedInit.method || 'GET',
250
+ headers: {
251
+ ...preparedInit.headers,
252
+ ...resolvedHeaders,
253
+ },
254
+ });
255
+ if (!response.ok) {
256
+ const contentType = response.headers.get('content-type') || '';
257
+ let bodyText = '';
258
+ try {
259
+ bodyText = contentType.includes('json') ? JSON.stringify(await response.json()) : await response.text();
260
+ }
261
+ catch { }
262
+ const hint = getErrorHint(response.status, provider, bodyText);
263
+ const hintSuffix = hint ? ` ${hint}` : '';
264
+ const credentialUrl = buildCredentialUrl(integration.id);
265
+ const hintWithUrl = response.status === 401
266
+ ? `${hint} Open ${credentialUrl} to reconfigure.`
267
+ : hint;
268
+ const hintWithUrlSuffix = hintWithUrl ? ` ${hintWithUrl}` : '';
269
+ throw new HttpError(response.status, `Failed to proxy request to ${provider} (${response.status})${bodyText ? `: ${bodyText.slice(0, 500)}` : ''}.${response.status === 401 ? hintWithUrlSuffix : hintSuffix}`, {
270
+ status: response.status,
271
+ url: redact(finalUrl),
272
+ contentType,
273
+ body: bodyText?.slice(0, 4000),
274
+ ...(response.status === 401 ? { reason: 'invalid_credentials', credential_url: credentialUrl } : {}),
275
+ });
276
+ }
277
+ return response;
278
+ }
279
+ // Managed OAuth branch: used by hosted deployments / CI.
280
+ if (!connectionId)
281
+ throw new HttpError(400, 'connectionId is required.');
282
+ if (!this.opts.managedOAuthBaseUrl || !this.opts.managedOAuthSecretKey)
283
+ throw new HttpError(501, 'Managed OAuth is not configured for this server.');
284
+ let managedConnection;
285
+ try {
286
+ const managedUrl = `${this.opts.managedOAuthBaseUrl}/connection/${encodeURIComponent(connectionId)}?provider_config_key=${encodeURIComponent(provider)}`;
287
+ const resp = await fetch(managedUrl, {
288
+ headers: { Authorization: `Bearer ${this.opts.managedOAuthSecretKey}` },
289
+ });
290
+ if (!resp.ok)
291
+ throw new Error(`Managed OAuth connection lookup failed (${resp.status})`);
292
+ managedConnection = await resp.json();
293
+ }
294
+ catch (error) {
295
+ console.error('Failed to fetch connection details from managed OAuth gateway:', error);
296
+ throw new HttpError(502, 'Failed to retrieve connection details from managed OAuth gateway.');
297
+ }
298
+ const providerId = provider;
299
+ const providerCfg = PROVIDERS[providerId];
300
+ const creds = managedConnection.credentials || {};
301
+ const userAccessToken = creds.access_token || creds.oauth_token || creds.token;
302
+ if (!providerCfg)
303
+ throw new HttpError(501, `Provider '${providerId}' is not configured in the server proxy.`);
304
+ const baseUrl = typeof providerCfg.baseUrl === 'function'
305
+ ? providerCfg.baseUrl(integration, creds)
306
+ : providerCfg.baseUrl;
307
+ const finalUrl = joinWithoutDuplicateSegments(baseUrl, path);
308
+ try {
309
+ const preparedInit = { ...init };
310
+ if (preparedInit.body !== undefined && typeof preparedInit.body !== 'string') {
311
+ preparedInit.body = JSON.stringify(preparedInit.body);
312
+ preparedInit.headers = {
313
+ 'Content-Type': 'application/json',
314
+ ...preparedInit.headers,
315
+ };
316
+ }
317
+ if (providerId === 'trello') {
318
+ if (!this.opts.trelloApiKey)
319
+ throw new HttpError(500, 'Trello API key is not configured.');
320
+ const queryParams = new URLSearchParams({
321
+ ...providerCfg.makeAuth(userAccessToken, this.opts.trelloApiKey),
322
+ }).toString();
323
+ const urlWithAuth = finalUrl + (finalUrl.includes('?') ? '&' : '?') + queryParams;
324
+ const response = await fetch(urlWithAuth, { ...preparedInit, method: preparedInit.method || 'GET' });
325
+ if (!response.ok) {
326
+ const contentType = response.headers.get('content-type') || '';
327
+ let bodyText = '';
328
+ try {
329
+ bodyText = contentType.includes('json') ? JSON.stringify(await response.json()) : await response.text();
330
+ }
331
+ catch { }
332
+ const hint = getErrorHint(response.status, providerId, bodyText);
333
+ const hintSuffix = hint ? ` ${hint}` : '';
334
+ throw new HttpError(response.status, `Failed to proxy request to ${providerId}.${hintSuffix}`, {
335
+ status: response.status,
336
+ url: urlWithAuth,
337
+ contentType,
338
+ body: bodyText?.slice(0, 4000),
339
+ });
340
+ }
341
+ return response;
342
+ }
343
+ const response = await fetch(finalUrl, {
344
+ ...preparedInit,
345
+ method: preparedInit.method || 'GET',
346
+ headers: {
347
+ ...preparedInit.headers,
348
+ ...providerCfg.makeAuth(userAccessToken),
349
+ },
350
+ });
351
+ if (!response.ok) {
352
+ const contentType = response.headers.get('content-type') || '';
353
+ let bodyText = '';
354
+ try {
355
+ bodyText = contentType.includes('json') ? JSON.stringify(await response.json()) : await response.text();
356
+ }
357
+ catch { }
358
+ const hint = getErrorHint(response.status, providerId, bodyText);
359
+ const hintSuffix = hint ? ` ${hint}` : '';
360
+ throw new HttpError(response.status, `Failed to proxy request to ${providerId}.${hintSuffix}`, {
361
+ status: response.status,
362
+ url: finalUrl,
363
+ contentType,
364
+ body: bodyText?.slice(0, 4000),
365
+ });
366
+ }
367
+ return response;
368
+ }
369
+ catch (error) {
370
+ console.error(`Error proxying request to ${providerId}:`, error);
371
+ if (error && typeof error === 'object' && 'statusCode' in error)
372
+ throw error;
373
+ throw new HttpError(500, `Failed to proxy request to ${providerId}.`, error?.message);
374
+ }
375
+ }
376
+ }
377
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/integrations/proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { SandboxUtils } from './sandboxUtils.js';
2
+ export declare function loadWorkflowModule(source: string, getIntegration?: Function): Promise<any>;
3
+ export declare function createSafeHandlerFromString(handlerString: string, getIntegration: Function, utils?: SandboxUtils): (args: any) => Promise<{
4
+ success: boolean;
5
+ result: any;
6
+ logs: string[];
7
+ }>;
8
+ //# sourceMappingURL=sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/integrations/sandbox.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAerD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAkFhG;AAED,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,QAAQ,EACxB,KAAK,CAAC,EAAE,YAAY,GACnB,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA0E3E"}
@@ -0,0 +1,221 @@
1
+ import { URL, URLSearchParams } from 'node:url';
2
+ import vm from 'node:vm';
3
+ import * as zodLib from 'zod';
4
+ function makeSyntheticFromObject(pkg, context) {
5
+ const exportNames = Array.from(new Set(['default', ...Object.keys(pkg)]));
6
+ return new vm.SyntheticModule(exportNames, function () {
7
+ this.setExport('default', pkg);
8
+ for (const key of Object.keys(pkg))
9
+ this.setExport(key, pkg[key]);
10
+ }, { context });
11
+ }
12
+ const ALLOWED_PACKAGES = {
13
+ zod: zodLib,
14
+ };
15
+ export async function loadWorkflowModule(source, getIntegration) {
16
+ const realConsole = console;
17
+ const isolatedConsole = {
18
+ log: (...args) => realConsole.log(...args),
19
+ info: (...args) => realConsole.info(...args),
20
+ warn: (...args) => realConsole.warn(...args),
21
+ error: (...args) => realConsole.error(...args),
22
+ debug: (...args) => realConsole.debug?.(...args) ?? realConsole.log(...args),
23
+ };
24
+ const safeAtob = (base64String) => {
25
+ if (typeof base64String !== 'string')
26
+ throw new TypeError('atob expects a string');
27
+ try {
28
+ const buffer = Buffer.from(base64String, 'base64');
29
+ return buffer.toString('binary');
30
+ }
31
+ catch {
32
+ throw new Error('Invalid base64 string');
33
+ }
34
+ };
35
+ const safeEscape = (str) => {
36
+ return encodeURIComponent(str).replace(/[!'()*]/g, (c) => {
37
+ return `%${c.charCodeAt(0).toString(16).toUpperCase()}`;
38
+ });
39
+ };
40
+ const safeBtoa = (binaryString) => {
41
+ if (typeof binaryString !== 'string')
42
+ throw new TypeError('btoa expects a string');
43
+ try {
44
+ const buffer = Buffer.from(binaryString, 'binary');
45
+ return buffer.toString('base64');
46
+ }
47
+ catch {
48
+ throw new Error('Invalid binary string');
49
+ }
50
+ };
51
+ const context = vm.createContext({
52
+ console: isolatedConsole,
53
+ getIntegration: getIntegration || (() => ({ fetch: undefined, post: undefined })),
54
+ URL,
55
+ URLSearchParams,
56
+ atob: safeAtob,
57
+ btoa: safeBtoa,
58
+ escape: safeEscape,
59
+ unescape,
60
+ decodeURIComponent,
61
+ encodeURIComponent,
62
+ fetch: undefined,
63
+ integrationFetch: undefined,
64
+ process: undefined,
65
+ require: undefined,
66
+ Buffer: undefined,
67
+ global: undefined,
68
+ globalThis: undefined,
69
+ setImmediate: undefined,
70
+ setInterval: undefined,
71
+ setTimeout: undefined,
72
+ clearImmediate: undefined,
73
+ clearInterval: undefined,
74
+ clearTimeout: undefined,
75
+ eval: undefined,
76
+ Function: undefined,
77
+ });
78
+ const userModule = new vm.SourceTextModule(source, { context });
79
+ const moduleCache = {};
80
+ await userModule.link((specifier) => {
81
+ const pkg = ALLOWED_PACKAGES[specifier];
82
+ if (!pkg)
83
+ throw new Error(`Import "${specifier}" is not allowed in workflow modules.`);
84
+ if (!moduleCache[specifier])
85
+ moduleCache[specifier] = makeSyntheticFromObject(pkg, context);
86
+ return moduleCache[specifier];
87
+ });
88
+ await userModule.evaluate({ timeout: 5000 });
89
+ return userModule.namespace;
90
+ }
91
+ export function createSafeHandlerFromString(handlerString, getIntegration, utils) {
92
+ const realConsole = console;
93
+ const isolatedConsole = {
94
+ log: (...args) => realConsole.log(...args),
95
+ info: (...args) => realConsole.info(...args),
96
+ warn: (...args) => realConsole.warn(...args),
97
+ error: (...args) => realConsole.error(...args),
98
+ debug: (...args) => realConsole.debug?.(...args) ?? realConsole.log(...args),
99
+ };
100
+ const safeAtob = (base64String) => {
101
+ if (typeof base64String !== 'string')
102
+ throw new TypeError('atob expects a string');
103
+ try {
104
+ const buffer = Buffer.from(base64String, 'base64');
105
+ return buffer.toString('binary');
106
+ }
107
+ catch {
108
+ throw new Error('Invalid base64 string');
109
+ }
110
+ };
111
+ const safeBtoa = (binaryString) => {
112
+ if (typeof binaryString !== 'string')
113
+ throw new TypeError('btoa expects a string');
114
+ try {
115
+ const buffer = Buffer.from(binaryString, 'binary');
116
+ return buffer.toString('base64');
117
+ }
118
+ catch {
119
+ throw new Error('Invalid binary string');
120
+ }
121
+ };
122
+ const safeEscape = (str) => {
123
+ return encodeURIComponent(str).replace(/[!'()*]/g, (c) => {
124
+ return `%${c.charCodeAt(0).toString(16).toUpperCase()}`;
125
+ });
126
+ };
127
+ const context = vm.createContext({
128
+ console: isolatedConsole,
129
+ getIntegration,
130
+ utils: utils || {},
131
+ module: {},
132
+ URL,
133
+ URLSearchParams,
134
+ atob: safeAtob,
135
+ btoa: safeBtoa,
136
+ escape: safeEscape,
137
+ unescape,
138
+ decodeURIComponent,
139
+ encodeURIComponent,
140
+ fetch: undefined,
141
+ integrationFetch: undefined,
142
+ process: undefined,
143
+ require: undefined,
144
+ Buffer: undefined,
145
+ global: undefined,
146
+ globalThis: undefined,
147
+ setImmediate: undefined,
148
+ setInterval: undefined,
149
+ setTimeout: undefined,
150
+ clearImmediate: undefined,
151
+ clearInterval: undefined,
152
+ clearTimeout: undefined,
153
+ eval: undefined,
154
+ Function: undefined,
155
+ });
156
+ const code = `module.exports = async function(input) { return (${handlerString})(input) }`;
157
+ const script = new vm.Script(code);
158
+ script.runInContext(context);
159
+ return withLogging(context.module.exports, isolatedConsole);
160
+ }
161
+ function withLogging(handler, vmConsole) {
162
+ function safeSerializeForLog(value) {
163
+ if (typeof value === 'string')
164
+ return value;
165
+ try {
166
+ if (value && typeof value === 'object' && typeof value.json === 'function' && typeof value.text === 'function') {
167
+ const resp = value;
168
+ const summary = {
169
+ type: 'FetchResponse',
170
+ ok: !!resp.ok,
171
+ status: resp.status,
172
+ statusText: resp.statusText,
173
+ url: resp.url,
174
+ bodyUsed: !!resp.bodyUsed,
175
+ };
176
+ return JSON.stringify(summary);
177
+ }
178
+ return JSON.stringify(value);
179
+ }
180
+ catch {
181
+ try {
182
+ return String(value);
183
+ }
184
+ catch {
185
+ return '[Unserializable]';
186
+ }
187
+ }
188
+ }
189
+ return async function wrappedHandler(args) {
190
+ const logs = [];
191
+ const originalLog = vmConsole.log;
192
+ try {
193
+ vmConsole.log = (...args2) => {
194
+ const line = args2.map(a => safeSerializeForLog(a)).join(' ');
195
+ if (logs.join('\n').length < 10_000)
196
+ logs.push(line);
197
+ originalLog.apply(vmConsole, args2);
198
+ };
199
+ const result = await handler(args);
200
+ return { success: true, result, logs };
201
+ }
202
+ catch (err) {
203
+ logs.push(err?.stack || String(err));
204
+ // Serialize Error objects into plain objects so JSON.stringify captures all fields
205
+ // including message (which is non-enumerable on Error).
206
+ const result = (err && typeof err === 'object')
207
+ ? {
208
+ ...err,
209
+ message: err.message,
210
+ ...(err.statusCode !== undefined ? { statusCode: err.statusCode } : {}),
211
+ ...(err.data !== undefined ? { data: err.data } : {}),
212
+ }
213
+ : err;
214
+ return { success: false, result, logs };
215
+ }
216
+ finally {
217
+ vmConsole.log = originalLog;
218
+ }
219
+ };
220
+ }
221
+ //# sourceMappingURL=sandbox.js.map