mcp-scraper 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/dist/bin/api-server.cjs +278 -20
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +1 -1
- package/dist/bin/mcp-scraper-cli.cjs +1 -1
- package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-install.cjs +1 -1
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +1 -1
- package/dist/bin/mcp-stdio-server.cjs +42 -10
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/chunk-HQYIP5X3.js +7 -0
- package/dist/chunk-HQYIP5X3.js.map +1 -0
- package/dist/{chunk-ETJBTYZX.js → chunk-YIV4IKFG.js} +43 -11
- package/dist/chunk-YIV4IKFG.js.map +1 -0
- package/dist/{server-DDKXWYTO.js → server-QEXOVJPR.js} +238 -12
- package/dist/server-QEXOVJPR.js.map +1 -0
- package/docs/mcp-tool-manifest.generated.json +162 -6
- package/docs/specs/google-drive-bulk-access-and-mcp-schema-passthrough-spec.md +1680 -0
- package/package.json +1 -1
- package/dist/chunk-ETJBTYZX.js.map +0 -1
- package/dist/chunk-TK2S2M7G.js +0 -7
- package/dist/chunk-TK2S2M7G.js.map +0 -1
- package/dist/server-DDKXWYTO.js.map +0 -1
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
renewConnectedDataArtifactDownload,
|
|
38
38
|
sanitizeAttempts,
|
|
39
39
|
sanitizeHarvestResult
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-YIV4IKFG.js";
|
|
41
41
|
import {
|
|
42
42
|
auditImages,
|
|
43
43
|
buildLinkReport,
|
|
@@ -73,7 +73,7 @@ import {
|
|
|
73
73
|
RawMapsOverviewSchema,
|
|
74
74
|
RawMapsReviewStatsSchema
|
|
75
75
|
} from "./chunk-XGIPATLV.js";
|
|
76
|
-
import "./chunk-
|
|
76
|
+
import "./chunk-HQYIP5X3.js";
|
|
77
77
|
import {
|
|
78
78
|
completeExtractJob,
|
|
79
79
|
countSuccessfulPages,
|
|
@@ -20356,6 +20356,10 @@ async function collectConnectedDataExport(args) {
|
|
|
20356
20356
|
recordBytes += pageBytes;
|
|
20357
20357
|
cursor = page.nextCursor ?? void 0;
|
|
20358
20358
|
continuationCursor = page.nextCursor ?? null;
|
|
20359
|
+
if (page.complete === false && typeof beforePageCursor === "string" && page.nextCursor === beforePageCursor) {
|
|
20360
|
+
warnings.add("The provider could not advance this page after bounded retries. Its records and warnings were included once; retry this exact continuation later.");
|
|
20361
|
+
break;
|
|
20362
|
+
}
|
|
20359
20363
|
if (page.complete || page.nextCursor === null || page.nextCursor === void 0) {
|
|
20360
20364
|
complete = true;
|
|
20361
20365
|
continuationCursor = null;
|
|
@@ -20629,6 +20633,7 @@ async function dbUsage(identity, plan) {
|
|
|
20629
20633
|
}
|
|
20630
20634
|
|
|
20631
20635
|
// src/api/nango-control.ts
|
|
20636
|
+
import { createHash as createHash5 } from "crypto";
|
|
20632
20637
|
var DEFAULT_NANGO_CONTROL_URL = "https://mcp-scraper-scheduler.vercel.app";
|
|
20633
20638
|
var DISABLED_NANGO_TOOLS = {
|
|
20634
20639
|
"google-mail": /* @__PURE__ */ new Set(["list-filters"]),
|
|
@@ -20707,10 +20712,14 @@ function connectionSyncSelectionError(connections) {
|
|
|
20707
20712
|
}
|
|
20708
20713
|
var NangoControlError = class extends Error {
|
|
20709
20714
|
status;
|
|
20710
|
-
|
|
20715
|
+
code;
|
|
20716
|
+
retryable;
|
|
20717
|
+
constructor(message, status = 502, code = status === 503 ? "connection_transport_unavailable" : "connection_control_failed", retryable = status === 429 || status >= 500) {
|
|
20711
20718
|
super(message);
|
|
20712
20719
|
this.name = "NangoControlError";
|
|
20713
20720
|
this.status = status;
|
|
20721
|
+
this.code = code;
|
|
20722
|
+
this.retryable = retryable;
|
|
20714
20723
|
}
|
|
20715
20724
|
};
|
|
20716
20725
|
var ScheduleConnectionValidationError = class extends Error {
|
|
@@ -20775,6 +20784,63 @@ function arrayFromPayload(value, keys) {
|
|
|
20775
20784
|
}
|
|
20776
20785
|
return [];
|
|
20777
20786
|
}
|
|
20787
|
+
var SAFE_CONTROL_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
20788
|
+
"invalid_request",
|
|
20789
|
+
"tool_not_allowed",
|
|
20790
|
+
"invalid_schema",
|
|
20791
|
+
"connection_not_found",
|
|
20792
|
+
"connection_inactive",
|
|
20793
|
+
"actions_disabled",
|
|
20794
|
+
"action_not_allowed",
|
|
20795
|
+
"upstream_rate_limited",
|
|
20796
|
+
"tool_discovery_failed",
|
|
20797
|
+
"live_tool_missing",
|
|
20798
|
+
"connection_transport_unavailable",
|
|
20799
|
+
"connection_control_failed"
|
|
20800
|
+
]);
|
|
20801
|
+
var CONTROL_ERROR_CODE_ALIASES = /* @__PURE__ */ new Map([
|
|
20802
|
+
["connection_not_active", "connection_inactive"],
|
|
20803
|
+
["actions_not_enabled", "actions_disabled"],
|
|
20804
|
+
["action_tool_not_allowed", "action_not_allowed"],
|
|
20805
|
+
["no_action_for_provider", "action_not_allowed"],
|
|
20806
|
+
["tool_not_available", "live_tool_missing"]
|
|
20807
|
+
]);
|
|
20808
|
+
function controlErrorStatus(status) {
|
|
20809
|
+
if (status === 400 || status === 403 || status === 404 || status === 409 || status === 429 || status === 502 || status === 503) {
|
|
20810
|
+
return status;
|
|
20811
|
+
}
|
|
20812
|
+
return status >= 500 ? 503 : 502;
|
|
20813
|
+
}
|
|
20814
|
+
function defaultControlErrorCode(status) {
|
|
20815
|
+
if (status === 400) return "invalid_request";
|
|
20816
|
+
if (status === 403) return "actions_disabled";
|
|
20817
|
+
if (status === 404) return "connection_not_found";
|
|
20818
|
+
if (status === 409) return "connection_inactive";
|
|
20819
|
+
if (status === 429) return "upstream_rate_limited";
|
|
20820
|
+
if (status === 503) return "connection_transport_unavailable";
|
|
20821
|
+
return "connection_control_failed";
|
|
20822
|
+
}
|
|
20823
|
+
function defaultControlErrorMessage(status) {
|
|
20824
|
+
if (status === 400) return "The connection request was invalid.";
|
|
20825
|
+
if (status === 403) return "Actions are disabled for this service connection.";
|
|
20826
|
+
if (status === 404) return "The service connection was not found.";
|
|
20827
|
+
if (status === 409) return "The service connection is not currently usable.";
|
|
20828
|
+
if (status === 429) return "The connected service is temporarily rate limited.";
|
|
20829
|
+
if (status === 503) return "The service connection transport is temporarily unavailable.";
|
|
20830
|
+
return "The service connection control request failed.";
|
|
20831
|
+
}
|
|
20832
|
+
function safeControlErrorPayload(body, responseStatus) {
|
|
20833
|
+
const status = controlErrorStatus(responseStatus);
|
|
20834
|
+
const unwrapped = unwrapData(body);
|
|
20835
|
+
const record = isRecord(unwrapped) ? unwrapped : isRecord(body) ? body : null;
|
|
20836
|
+
const candidateCode = record ? firstString(record, ["code", "errorCode", "error_code"], 100) : null;
|
|
20837
|
+
const normalizedCandidateCode = candidateCode ? CONTROL_ERROR_CODE_ALIASES.get(candidateCode) ?? candidateCode : null;
|
|
20838
|
+
const code = normalizedCandidateCode && SAFE_CONTROL_ERROR_CODES.has(normalizedCandidateCode) ? normalizedCandidateCode : defaultControlErrorCode(status);
|
|
20839
|
+
const candidateMessage = record ? firstString(record, ["error", "message"], 500) : null;
|
|
20840
|
+
const message = normalizedCandidateCode && SAFE_CONTROL_ERROR_CODES.has(normalizedCandidateCode) && candidateMessage ? candidateMessage.replace(/[\u0000-\u001f\u007f]/g, " ") : defaultControlErrorMessage(status);
|
|
20841
|
+
const retryable = record && typeof record.retryable === "boolean" ? record.retryable : status === 429 || status >= 500;
|
|
20842
|
+
return { status, code, message, retryable };
|
|
20843
|
+
}
|
|
20778
20844
|
async function controlRequest(path5, init, timeoutMs = 2e4) {
|
|
20779
20845
|
const response = await fetch(`${controlBaseUrl()}${path5}`, {
|
|
20780
20846
|
...init,
|
|
@@ -20786,7 +20852,13 @@ async function controlRequest(path5, init, timeoutMs = 2e4) {
|
|
|
20786
20852
|
},
|
|
20787
20853
|
signal: AbortSignal.timeout(timeoutMs)
|
|
20788
20854
|
}).catch((err) => {
|
|
20789
|
-
|
|
20855
|
+
const cause = err instanceof Error && err.name === "TimeoutError" ? "request timed out" : "network error";
|
|
20856
|
+
throw new NangoControlError(
|
|
20857
|
+
`Scheduled service connection control is unavailable: ${cause}.`,
|
|
20858
|
+
503,
|
|
20859
|
+
"connection_transport_unavailable",
|
|
20860
|
+
true
|
|
20861
|
+
);
|
|
20790
20862
|
});
|
|
20791
20863
|
const text = await response.text();
|
|
20792
20864
|
let body = {};
|
|
@@ -20796,8 +20868,8 @@ async function controlRequest(path5, init, timeoutMs = 2e4) {
|
|
|
20796
20868
|
body = {};
|
|
20797
20869
|
}
|
|
20798
20870
|
if (!response.ok) {
|
|
20799
|
-
const
|
|
20800
|
-
throw new NangoControlError(
|
|
20871
|
+
const error = safeControlErrorPayload(body, response.status);
|
|
20872
|
+
throw new NangoControlError(error.message, error.status, error.code, error.retryable);
|
|
20801
20873
|
}
|
|
20802
20874
|
return body;
|
|
20803
20875
|
}
|
|
@@ -20892,6 +20964,9 @@ async function getNangoConnections(identity) {
|
|
|
20892
20964
|
actionsEnabled: row.actionsEnabled === true || row.actions_enabled === true,
|
|
20893
20965
|
readTools: cleanTools(row.readTools ?? row.read_tools),
|
|
20894
20966
|
actionTools: cleanTools(row.actionTools ?? row.action_tools ?? row.writeTools ?? row.write_tools),
|
|
20967
|
+
mcpEndpoint: null,
|
|
20968
|
+
schemaDiscovery: "compatibility_describe",
|
|
20969
|
+
toolRevision: firstString(row, ["toolRevision", "tool_revision"], 200),
|
|
20895
20970
|
vaultName: firstString(row, ["vaultName", "vault_name"], 100),
|
|
20896
20971
|
tableName: firstString(row, ["tableName", "table_name"], 100),
|
|
20897
20972
|
createdAt: firstString(row, ["createdAt", "created_at"], 100),
|
|
@@ -21024,6 +21099,145 @@ async function callScheduleConnectionRead(identity, connectionId, tool, args) {
|
|
|
21024
21099
|
const data = unwrapData(body);
|
|
21025
21100
|
return isRecord(data) ? data.result ?? data : data;
|
|
21026
21101
|
}
|
|
21102
|
+
function sanitizeToolSchema(value) {
|
|
21103
|
+
if (!isRecord(value) || value.type !== "object") return null;
|
|
21104
|
+
try {
|
|
21105
|
+
const serialized = JSON.stringify(value);
|
|
21106
|
+
if (Buffer.byteLength(serialized, "utf8") > 256 * 1024) return null;
|
|
21107
|
+
const cloned = JSON.parse(serialized);
|
|
21108
|
+
return isRecord(cloned) ? cloned : null;
|
|
21109
|
+
} catch {
|
|
21110
|
+
return null;
|
|
21111
|
+
}
|
|
21112
|
+
}
|
|
21113
|
+
function sanitizeToolAnnotations(value) {
|
|
21114
|
+
if (!isRecord(value)) return void 0;
|
|
21115
|
+
const annotations = {};
|
|
21116
|
+
const title = cleanString(value.title, 200);
|
|
21117
|
+
if (title) annotations.title = title;
|
|
21118
|
+
for (const key of ["readOnlyHint", "destructiveHint", "idempotentHint", "openWorldHint"]) {
|
|
21119
|
+
if (typeof value[key] === "boolean") annotations[key] = value[key];
|
|
21120
|
+
}
|
|
21121
|
+
return Object.keys(annotations).length > 0 ? annotations : void 0;
|
|
21122
|
+
}
|
|
21123
|
+
function sanitizeToolIconSource(value) {
|
|
21124
|
+
const candidate = cleanString(value, 1e4);
|
|
21125
|
+
if (!candidate) return null;
|
|
21126
|
+
if (/^data:image\/(?:png|jpeg|webp|gif|svg\+xml);base64,[a-z0-9+/=]+$/i.test(candidate)) return candidate;
|
|
21127
|
+
return cleanHttpsUrl(candidate);
|
|
21128
|
+
}
|
|
21129
|
+
function sanitizeToolIcons(value) {
|
|
21130
|
+
if (!Array.isArray(value)) return void 0;
|
|
21131
|
+
const icons = [];
|
|
21132
|
+
for (const item of value.slice(0, 16)) {
|
|
21133
|
+
if (!isRecord(item)) continue;
|
|
21134
|
+
const src = sanitizeToolIconSource(item.src);
|
|
21135
|
+
if (!src) continue;
|
|
21136
|
+
const mimeType = cleanString(item.mimeType ?? item.mime_type, 100);
|
|
21137
|
+
const sizes = cleanStringArray(item.sizes, 16, 32);
|
|
21138
|
+
const theme = item.theme === "light" || item.theme === "dark" ? item.theme : void 0;
|
|
21139
|
+
icons.push({
|
|
21140
|
+
src,
|
|
21141
|
+
...mimeType ? { mimeType } : {},
|
|
21142
|
+
...sizes.length > 0 ? { sizes } : {},
|
|
21143
|
+
...theme ? { theme } : {}
|
|
21144
|
+
});
|
|
21145
|
+
}
|
|
21146
|
+
return icons.length > 0 ? icons : void 0;
|
|
21147
|
+
}
|
|
21148
|
+
function canonicalJson(value) {
|
|
21149
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
21150
|
+
if (isRecord(value)) {
|
|
21151
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(",")}}`;
|
|
21152
|
+
}
|
|
21153
|
+
return JSON.stringify(value);
|
|
21154
|
+
}
|
|
21155
|
+
function projectedToolSchemaHash(tool) {
|
|
21156
|
+
return createHash5("sha256").update(canonicalJson(tool)).digest("hex");
|
|
21157
|
+
}
|
|
21158
|
+
async function describeNangoTool(identity, connectionId, tool, fresh) {
|
|
21159
|
+
const body = await controlRequest("/api/internal/nango/connections/actions/describe", {
|
|
21160
|
+
method: "POST",
|
|
21161
|
+
body: JSON.stringify({
|
|
21162
|
+
identity,
|
|
21163
|
+
connectionId,
|
|
21164
|
+
tool,
|
|
21165
|
+
...fresh === void 0 ? {} : { fresh }
|
|
21166
|
+
})
|
|
21167
|
+
});
|
|
21168
|
+
const data = unwrapData(body);
|
|
21169
|
+
const rawTool = isRecord(data) && isRecord(data.tool) ? data.tool : data;
|
|
21170
|
+
if (!isRecord(rawTool)) {
|
|
21171
|
+
throw new NangoControlError(
|
|
21172
|
+
"The connection service returned an invalid live tool description.",
|
|
21173
|
+
502,
|
|
21174
|
+
"tool_discovery_failed",
|
|
21175
|
+
true
|
|
21176
|
+
);
|
|
21177
|
+
}
|
|
21178
|
+
let serializedBytes = Number.POSITIVE_INFINITY;
|
|
21179
|
+
try {
|
|
21180
|
+
serializedBytes = Buffer.byteLength(JSON.stringify(rawTool), "utf8");
|
|
21181
|
+
} catch {
|
|
21182
|
+
}
|
|
21183
|
+
const name = cleanString(rawTool.name, 200);
|
|
21184
|
+
const classification = cleanString(rawTool.classification, 20);
|
|
21185
|
+
const transport = cleanString(rawTool.transport, 20);
|
|
21186
|
+
const providerConfigKey = cleanString(rawTool.providerConfigKey ?? rawTool.provider_config_key, 200);
|
|
21187
|
+
const schemaSource = cleanString(rawTool.schemaSource ?? rawTool.schema_source, 50);
|
|
21188
|
+
const upstreamSchemaHash = cleanString(rawTool.schemaHash ?? rawTool.schema_hash, 200);
|
|
21189
|
+
const fetchedAt = cleanString(rawTool.fetchedAt ?? rawTool.fetched_at, 100);
|
|
21190
|
+
const inputSchema = sanitizeToolSchema(rawTool.inputSchema ?? rawTool.input_schema);
|
|
21191
|
+
const outputSchemaValue = rawTool.outputSchema ?? rawTool.output_schema;
|
|
21192
|
+
const outputSchema = outputSchemaValue === void 0 ? void 0 : sanitizeToolSchema(outputSchemaValue);
|
|
21193
|
+
const blockedReasonValue = rawTool.blockedReason ?? rawTool.blocked_reason;
|
|
21194
|
+
const blockedReason = blockedReasonValue === null || blockedReasonValue === void 0 ? null : blockedReasonValue === "actions_disabled" || blockedReasonValue === "inactive_connection" ? blockedReasonValue : void 0;
|
|
21195
|
+
if (serializedBytes > 256 * 1024 || !name || name !== tool || classification !== "read" && classification !== "action" || typeof rawTool.callable !== "boolean" || blockedReason === void 0 || transport !== "nango" && transport !== "remote_mcp" || !providerConfigKey || schemaSource !== "live_tools_list" || !upstreamSchemaHash || !/^[a-f0-9]{64}$/i.test(upstreamSchemaHash) || !fetchedAt || Number.isNaN(Date.parse(fetchedAt)) || !inputSchema || outputSchemaValue !== void 0 && !outputSchema) {
|
|
21196
|
+
throw new NangoControlError(
|
|
21197
|
+
"The connection service returned an invalid live tool description.",
|
|
21198
|
+
502,
|
|
21199
|
+
"tool_discovery_failed",
|
|
21200
|
+
true
|
|
21201
|
+
);
|
|
21202
|
+
}
|
|
21203
|
+
const protocolVersion = rawTool.protocolVersion === null || rawTool.protocol_version === null ? null : cleanString(rawTool.protocolVersion ?? rawTool.protocol_version, 100);
|
|
21204
|
+
const executionValue = rawTool.execution;
|
|
21205
|
+
const taskSupport = isRecord(executionValue) && (executionValue.taskSupport === "forbidden" || executionValue.taskSupport === "optional" || executionValue.taskSupport === "required") ? executionValue.taskSupport : null;
|
|
21206
|
+
const title = cleanString(rawTool.title, 200);
|
|
21207
|
+
const description = cleanString(rawTool.description, 12e3);
|
|
21208
|
+
const annotations = sanitizeToolAnnotations(rawTool.annotations);
|
|
21209
|
+
const icons = sanitizeToolIcons(rawTool.icons);
|
|
21210
|
+
const execution = taskSupport ? { taskSupport } : void 0;
|
|
21211
|
+
const schemaHash = projectedToolSchemaHash({
|
|
21212
|
+
name,
|
|
21213
|
+
inputSchema,
|
|
21214
|
+
...title ? { title } : {},
|
|
21215
|
+
...description ? { description } : {},
|
|
21216
|
+
...outputSchema ? { outputSchema } : {},
|
|
21217
|
+
...annotations ? { annotations } : {},
|
|
21218
|
+
...icons ? { icons } : {},
|
|
21219
|
+
...execution ? { execution } : {}
|
|
21220
|
+
});
|
|
21221
|
+
return {
|
|
21222
|
+
name,
|
|
21223
|
+
title,
|
|
21224
|
+
description,
|
|
21225
|
+
classification,
|
|
21226
|
+
callable: rawTool.callable,
|
|
21227
|
+
blockedReason,
|
|
21228
|
+
transport,
|
|
21229
|
+
providerConfigKey,
|
|
21230
|
+
protocolVersion,
|
|
21231
|
+
schemaSource: "live_tools_list",
|
|
21232
|
+
inputSchema,
|
|
21233
|
+
...outputSchema ? { outputSchema } : {},
|
|
21234
|
+
...annotations ? { annotations } : {},
|
|
21235
|
+
...icons ? { icons } : {},
|
|
21236
|
+
...execution ? { execution } : {},
|
|
21237
|
+
schemaHash,
|
|
21238
|
+
fetchedAt
|
|
21239
|
+
};
|
|
21240
|
+
}
|
|
21027
21241
|
async function callScheduleConnectionExportPage(identity, input) {
|
|
21028
21242
|
const body = await controlRequest("/api/internal/nango/connections/export-page", {
|
|
21029
21243
|
method: "POST",
|
|
@@ -21243,6 +21457,9 @@ async function getResendConnections(identity) {
|
|
|
21243
21457
|
readTools: cleanTools2(row.readTools ?? row.read_tools),
|
|
21244
21458
|
actionTools: cleanTools2(row.actionTools ?? row.action_tools ?? row.writeTools ?? row.write_tools),
|
|
21245
21459
|
adminBlockedTools: cleanTools2(row.adminBlockedTools ?? row.admin_blocked_tools).length > 0 ? cleanTools2(row.adminBlockedTools ?? row.admin_blocked_tools) : [...RESEND_ADMIN_BLOCKED_TOOLS],
|
|
21460
|
+
mcpEndpoint: null,
|
|
21461
|
+
schemaDiscovery: "compatibility_describe",
|
|
21462
|
+
toolRevision: firstString2(row, ["toolRevision", "tool_revision"], 200),
|
|
21246
21463
|
vaultName: firstString2(row, ["vaultName", "vault_name"], 100),
|
|
21247
21464
|
tableName: firstString2(row, ["tableName", "table_name"], 100),
|
|
21248
21465
|
createdAt: firstString2(row, ["createdAt", "created_at"], 100),
|
|
@@ -21985,7 +22202,15 @@ app.post("/schedule-checkout", auth2, async (c) => {
|
|
|
21985
22202
|
});
|
|
21986
22203
|
function scheduleConnectionError(c, err, fallback) {
|
|
21987
22204
|
if (err instanceof ScheduleConnectionValidationError) return c.json({ ok: false, error: err.message }, 400);
|
|
21988
|
-
if (err instanceof NangoControlError)
|
|
22205
|
+
if (err instanceof NangoControlError) {
|
|
22206
|
+
return c.json({
|
|
22207
|
+
ok: false,
|
|
22208
|
+
error: err.message,
|
|
22209
|
+
code: err.code,
|
|
22210
|
+
errorCode: err.code,
|
|
22211
|
+
retryable: err.retryable
|
|
22212
|
+
}, err.status);
|
|
22213
|
+
}
|
|
21989
22214
|
if (err instanceof ResendControlError) return c.json({ ok: false, error: err.message }, err.status);
|
|
21990
22215
|
console.error("[schedule-connections]", err instanceof Error ? err.message : String(err));
|
|
21991
22216
|
return c.json({ ok: false, error: fallback }, 502);
|
|
@@ -22239,11 +22464,12 @@ app.post("/schedule-connections/actions/describe", auth2, async (c) => {
|
|
|
22239
22464
|
const providerConfigKey = providerConfigKeyFrom(body.providerConfigKey);
|
|
22240
22465
|
const tool = providerConfigKeyFrom(body.tool);
|
|
22241
22466
|
if (!connectionId || !tool) return c.json({ ok: false, error: "connectionId and tool are required." }, 400);
|
|
22467
|
+
if (body.fresh !== void 0 && typeof body.fresh !== "boolean") {
|
|
22468
|
+
return c.json({ ok: false, error: "fresh must be a boolean when provided." }, 400);
|
|
22469
|
+
}
|
|
22242
22470
|
try {
|
|
22243
|
-
|
|
22244
|
-
|
|
22245
|
-
}
|
|
22246
|
-
return c.json({ ok: true, tool: await describeResendTool(user.email, connectionId, tool) });
|
|
22471
|
+
const description = await isResendConnection(user.email, connectionId, providerConfigKey) ? await describeResendTool(user.email, connectionId, tool) : await describeNangoTool(user.email, connectionId, tool, body.fresh);
|
|
22472
|
+
return c.json({ ok: true, tool: description });
|
|
22247
22473
|
} catch (err) {
|
|
22248
22474
|
return scheduleConnectionError(c, err, "Unable to describe this connection tool.");
|
|
22249
22475
|
}
|
|
@@ -23562,4 +23788,4 @@ app.get("/blog/:slug/", (c) => {
|
|
|
23562
23788
|
export {
|
|
23563
23789
|
app
|
|
23564
23790
|
};
|
|
23565
|
-
//# sourceMappingURL=server-
|
|
23791
|
+
//# sourceMappingURL=server-QEXOVJPR.js.map
|