@oomol-lab/open-connector 1.6.4 → 1.7.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/assets/open-connector/catalog/apps/aisa.json +6394 -0
- package/assets/open-connector/catalog/apps/baizhi_mcp.json +135 -0
- package/assets/open-connector/catalog/apps/bilibili.json +2586 -0
- package/assets/open-connector/catalog/apps/bitwarden.json +1423 -0
- package/assets/open-connector/catalog/apps/cronfree.json +303 -0
- package/assets/open-connector/catalog/apps/cufinder.json +368 -0
- package/assets/open-connector/catalog/apps/discordbot.json +2888 -248
- package/assets/open-connector/catalog/apps/drawio_mcp.json +192 -0
- package/assets/open-connector/catalog/apps/firecrawl.json +176 -32
- package/assets/open-connector/catalog/apps/framejet.json +273 -0
- package/assets/open-connector/catalog/apps/futunn.json +2967 -0
- package/assets/open-connector/catalog/apps/gmail.json +298 -0
- package/assets/open-connector/catalog/apps/google_analytics.json +4 -1
- package/assets/open-connector/catalog/apps/google_bigquery.json +4 -1
- package/assets/open-connector/catalog/apps/google_search_console.json +4 -1
- package/assets/open-connector/catalog/apps/googlecalendar.json +4 -1
- package/assets/open-connector/catalog/apps/googlechat.json +694 -7
- package/assets/open-connector/catalog/apps/googledocs.json +4 -1
- package/assets/open-connector/catalog/apps/googlesheets.json +4 -1
- package/assets/open-connector/catalog/apps/granola.json +23 -0
- package/assets/open-connector/catalog/apps/investoday_mcp.json +22228 -197
- package/assets/open-connector/catalog/apps/ixspy.json +2274 -0
- package/assets/open-connector/catalog/apps/keepa.json +3534 -987
- package/assets/open-connector/catalog/apps/linear.json +17 -0
- package/assets/open-connector/catalog/apps/linear_mcp.json +510 -0
- package/assets/open-connector/catalog/apps/moneyforward_mcp.json +1432 -0
- package/assets/open-connector/catalog/apps/notion.json +446 -1
- package/assets/open-connector/catalog/apps/notion_mcp.json +490 -0
- package/assets/open-connector/catalog/apps/odoo.json +619 -0
- package/assets/open-connector/catalog/apps/osv.json +663 -0
- package/assets/open-connector/catalog/apps/outlook.json +30 -8
- package/assets/open-connector/catalog/apps/outlook_calendar.json +23 -2
- package/assets/open-connector/catalog/apps/pdf_vector.json +329 -0
- package/assets/open-connector/catalog/apps/postiz.json +334 -0
- package/assets/open-connector/catalog/apps/proworkflow.json +529 -0
- package/assets/open-connector/catalog/apps/pulsetic.json +406 -0
- package/assets/open-connector/catalog/apps/sellersprite_mcp.json +2 -1
- package/assets/open-connector/catalog/apps/shopee.json +1785 -0
- package/assets/open-connector/catalog/apps/slack.json +304 -0
- package/assets/open-connector/catalog/apps/slackbot.json +295 -0
- package/assets/open-connector/catalog/apps/speak_ai.json +360 -0
- package/assets/open-connector/catalog/apps/tencent_docs.json +3 -0
- package/assets/open-connector/catalog/apps/wisburg.json +1528 -0
- package/assets/open-connector/catalog/apps/youtube.json +4 -1
- package/assets/open-connector/catalog/apps/zerotier.json +3319 -0
- package/assets/open-connector/catalog/apps/zyhub.json +1585 -0
- package/assets/open-connector/catalog/apps-index.json +1 -1
- package/package.json +1 -1
- package/src/core/cast.d.ts +10 -0
- package/src/core/cast.js +14 -0
- package/src/core/guarded-fetch.d.ts +6 -3
- package/src/core/guarded-fetch.js +6 -3
- package/src/core/json-schema.d.ts +5 -1
- package/src/core/json-schema.js +14 -2
- package/src/core/provider-scenarios.js +67 -13
- package/src/core/request.js +4 -1
- package/src/core/types.d.ts +10 -1
- package/src/mcp.js +10 -7
- package/src/oauth/oauth-client-config-service.d.ts +16 -1
- package/src/oauth/oauth-client-config-service.js +59 -3
- package/src/oauth/oauth-credential-refresh-service.js +3 -1
- package/src/oauth/oauth-flow-service.d.ts +6 -0
- package/src/oauth/oauth-flow-service.js +21 -4
- package/src/oauth/oauth-token.d.ts +13 -0
- package/src/providers/17track/runtime.js +1 -1
- package/src/providers/action-contracts.generated.d.ts +32 -8
- package/src/providers/aifinmarket/runtime.js +1 -1
- package/src/providers/aisa/executors.d.ts +4 -0
- package/src/providers/aisa/executors.js +864 -0
- package/src/providers/aliyun_ack/runtime.js +1 -1
- package/src/providers/aliyun_sls/runtime.js +1 -1
- package/src/providers/app_store_server/runtime-helpers.js +1 -1
- package/src/providers/baizhi_mcp/actions.d.ts +2 -0
- package/src/providers/baizhi_mcp/actions.js +40 -0
- package/src/providers/baizhi_mcp/executors.d.ts +3 -0
- package/src/providers/baizhi_mcp/executors.js +102 -0
- package/src/providers/bazhuayu/runtime.js +2 -2
- package/src/providers/bilibili/articles.d.ts +3 -0
- package/src/providers/bilibili/articles.js +369 -0
- package/src/providers/bilibili/executors.d.ts +8 -0
- package/src/providers/bilibili/executors.js +262 -0
- package/src/providers/bilibili/runtime.d.ts +95 -0
- package/src/providers/bilibili/runtime.js +236 -0
- package/src/providers/bilibili/upload.d.ts +14 -0
- package/src/providers/bilibili/upload.js +107 -0
- package/src/providers/bitwarden/executors.d.ts +3 -0
- package/src/providers/bitwarden/executors.js +146 -0
- package/src/providers/cloudflare_browser_rendering/executors.js +1 -1
- package/src/providers/cloudflare_dns/executors.js +1 -1
- package/src/providers/{cloudflare-current-user.js → cloudflare_dns/runtime-user.js} +2 -2
- package/src/providers/cloudflare_dns/runtime.d.ts +1 -1
- package/src/providers/cloudflare_dns/runtime.js +1 -1
- package/src/providers/cloudflare_r2/executors.js +1 -1
- package/src/providers/cloudflare_r2/runtime.d.ts +1 -1
- package/src/providers/cloudflare_r2/runtime.js +1 -1
- package/src/providers/cloudflare_worker/executors.js +1 -1
- package/src/providers/cloudflare_worker/runtime.d.ts +1 -1
- package/src/providers/cloudflare_worker/runtime.js +1 -1
- package/src/providers/cronfree/executors.d.ts +4 -0
- package/src/providers/cronfree/executors.js +89 -0
- package/src/providers/cufinder/executors.d.ts +4 -0
- package/src/providers/cufinder/executors.js +105 -0
- package/src/providers/dingtalk_mcp/runtime.js +1 -1
- package/src/providers/discordbot/executors.d.ts +0 -9
- package/src/providers/discordbot/executors.js +9 -101
- package/src/providers/discordbot/runtime-guilds.d.ts +3 -0
- package/src/providers/discordbot/runtime-guilds.js +464 -0
- package/src/providers/discordbot/runtime.d.ts +42 -0
- package/src/providers/discordbot/runtime.js +124 -0
- package/src/providers/drawio_mcp/executors.d.ts +3 -0
- package/src/providers/drawio_mcp/executors.js +19 -0
- package/src/providers/drawio_mcp/runtime.d.ts +8 -0
- package/src/providers/drawio_mcp/runtime.js +175 -0
- package/src/providers/elevenreader/runtime.js +6 -5
- package/src/providers/fastmoss_mcp/executors.js +2 -2
- package/src/providers/finchina/executors.js +1 -1
- package/src/providers/framejet/executors.d.ts +4 -0
- package/src/providers/framejet/executors.js +19 -0
- package/src/providers/framejet/runtime.d.ts +16 -0
- package/src/providers/framejet/runtime.js +148 -0
- package/src/providers/futunn/actions.d.ts +2 -0
- package/src/providers/futunn/actions.js +152 -0
- package/src/providers/futunn/actions.research.d.ts +2 -0
- package/src/providers/futunn/actions.research.js +423 -0
- package/src/providers/futunn/actions.trading.d.ts +2 -0
- package/src/providers/futunn/actions.trading.js +204 -0
- package/src/providers/futunn/executors.d.ts +3 -0
- package/src/providers/futunn/executors.js +24 -0
- package/src/providers/futunn/runtime-research.d.ts +3 -0
- package/src/providers/futunn/runtime-research.js +133 -0
- package/src/providers/futunn/runtime-trading.d.ts +3 -0
- package/src/providers/futunn/runtime-trading.js +39 -0
- package/src/providers/futunn/runtime.d.ts +2 -0
- package/src/providers/futunn/runtime.js +50 -0
- package/src/providers/futunn/transport.d.ts +11 -0
- package/src/providers/futunn/transport.js +76 -0
- package/src/providers/gildata/executors.js +1 -1
- package/src/providers/gmail/attachment-stream.d.ts +2 -0
- package/src/providers/gmail/attachment-stream.js +162 -0
- package/src/providers/gmail/executors.d.ts +3 -1
- package/src/providers/gmail/executors.js +54 -26
- package/src/providers/gmail/message.d.ts +6 -8
- package/src/providers/gmail/message.js +4 -0
- package/src/providers/gmail/scopes.d.ts +32 -0
- package/src/providers/gmail/scopes.js +37 -0
- package/src/providers/google_analytics/executors.js +2 -2
- package/src/providers/google_analytics/scopes.js +6 -1
- package/src/providers/google_bigquery/executors.js +2 -2
- package/src/providers/google_bigquery/scopes.js +2 -0
- package/src/providers/google_search_console/executors.js +2 -2
- package/src/providers/google_search_console/scopes.js +2 -0
- package/src/providers/googleads/executors.js +1 -1
- package/src/providers/googleads/scopes.d.ts +1 -3
- package/src/providers/googleads/scopes.js +2 -4
- package/src/providers/googlecalendar/executors.js +1 -1
- package/src/providers/googlecalendar/runtime-shared.js +2 -2
- package/src/providers/googlecalendar/scopes.js +2 -0
- package/src/providers/googlechat/executors.d.ts +1 -3
- package/src/providers/googlechat/executors.js +219 -28
- package/src/providers/googlechat/members.d.ts +55 -0
- package/src/providers/googlechat/members.js +293 -0
- package/src/providers/googlechat/runtime.d.ts +16 -0
- package/src/providers/googlechat/runtime.js +25 -0
- package/src/providers/googlechat/scopes.d.ts +22 -3
- package/src/providers/googlechat/scopes.js +30 -7
- package/src/providers/googledocs/executors.js +1 -1
- package/src/providers/googledrive/executors.js +2 -2
- package/src/providers/{google-auth.d.ts → googledrive/runtime-auth.d.ts} +2 -2
- package/src/providers/{google-auth.js → googledrive/runtime-auth.js} +3 -3
- package/src/providers/googledrive/runtime-collaboration.js +1 -1
- package/src/providers/{google-runtime.d.ts → googledrive/runtime-request.d.ts} +1 -1
- package/src/providers/{google-runtime.js → googledrive/runtime-request.js} +2 -2
- package/src/providers/googleforms/executors.js +2 -2
- package/src/providers/googleforms/scopes.d.ts +0 -3
- package/src/providers/googleforms/scopes.js +2 -6
- package/src/providers/googlemeet/executors.js +2 -2
- package/src/providers/googlemeet/scopes.d.ts +0 -3
- package/src/providers/googlemeet/scopes.js +2 -6
- package/src/providers/googlesheets/executors.js +1 -1
- package/src/providers/googlesheets/scopes.js +2 -0
- package/src/providers/googleslides/executors.js +2 -2
- package/src/providers/googleslides/scopes.d.ts +0 -3
- package/src/providers/googleslides/scopes.js +2 -6
- package/src/providers/googletasks/executors.js +2 -2
- package/src/providers/googletasks/scopes.d.ts +0 -3
- package/src/providers/googletasks/scopes.js +2 -6
- package/src/providers/granola/actions.js +2 -0
- package/src/providers/granola/runtime-mcp.js +2 -0
- package/src/providers/granola/runtime.js +2 -2
- package/src/providers/indiegogo/executors.js +1 -1
- package/src/providers/investoday_mcp/executors.js +2 -2
- package/src/providers/investoday_mcp/official-actions.js +19 -372
- package/src/providers/investoday_mcp/official-tool-types.d.ts +10 -0
- package/src/providers/investoday_mcp/official-tool-types.js +4 -0
- package/src/providers/investoday_mcp/official-tools/charts.d.ts +2 -0
- package/src/providers/investoday_mcp/official-tools/charts.js +32 -0
- package/src/providers/investoday_mcp/official-tools/fixed-income.d.ts +2 -0
- package/src/providers/investoday_mcp/official-tools/fixed-income.js +326 -0
- package/src/providers/investoday_mcp/official-tools/funds.d.ts +2 -0
- package/src/providers/investoday_mcp/official-tools/funds.js +1085 -0
- package/src/providers/investoday_mcp/official-tools/hong-kong.d.ts +2 -0
- package/src/providers/investoday_mcp/official-tools/hong-kong.js +275 -0
- package/src/providers/investoday_mcp/official-tools/indices-industries.d.ts +2 -0
- package/src/providers/investoday_mcp/official-tools/indices-industries.js +642 -0
- package/src/providers/investoday_mcp/official-tools/macro-calendar.d.ts +2 -0
- package/src/providers/investoday_mcp/official-tools/macro-calendar.js +398 -0
- package/src/providers/investoday_mcp/official-tools/other.d.ts +2 -0
- package/src/providers/investoday_mcp/official-tools/other.js +131 -0
- package/src/providers/investoday_mcp/official-tools/research-news.d.ts +2 -0
- package/src/providers/investoday_mcp/official-tools/research-news.js +302 -0
- package/src/providers/investoday_mcp/official-tools/stocks.d.ts +2 -0
- package/src/providers/investoday_mcp/official-tools/stocks.js +2829 -0
- package/src/providers/ixspy/executors.d.ts +3 -0
- package/src/providers/ixspy/executors.js +220 -0
- package/src/providers/iyunbiao/runtime.js +2 -2
- package/src/providers/keepa/actions.d.ts +1 -1
- package/src/providers/keepa/actions.js +371 -149
- package/src/providers/keepa/deal-attributes.d.ts +1 -0
- package/src/providers/keepa/deal-attributes.js +26 -0
- package/src/providers/keepa/runtime.js +212 -18
- package/src/providers/kingdee/executors.js +1 -1
- package/src/providers/kingdee/runtime.js +2 -2
- package/src/providers/kuaidi100/runtime.js +1 -1
- package/src/providers/linear/executors.js +12 -9
- package/src/providers/linear_mcp/actions.d.ts +47 -0
- package/src/providers/linear_mcp/actions.js +102 -0
- package/src/providers/linear_mcp/endpoints.d.ts +3 -0
- package/src/providers/linear_mcp/endpoints.js +3 -0
- package/src/providers/linear_mcp/executors.d.ts +3 -0
- package/src/providers/linear_mcp/executors.js +9 -0
- package/src/providers/linear_mcp/runtime-mcp.d.ts +15 -0
- package/src/providers/linear_mcp/runtime-mcp.js +238 -0
- package/src/providers/lingxing_mcp/runtime.js +1 -1
- package/src/providers/mcdonalds_cn_mcp/runtime.js +1 -1
- package/src/providers/metabase/mcp-runtime.js +1 -1
- package/src/providers/moneyforward_mcp/executors.d.ts +3 -0
- package/src/providers/moneyforward_mcp/executors.js +11 -0
- package/src/providers/moneyforward_mcp/manifest.d.ts +31 -0
- package/src/providers/moneyforward_mcp/manifest.js +204 -0
- package/src/providers/moneyforward_mcp/runtime.d.ts +18 -0
- package/src/providers/moneyforward_mcp/runtime.js +296 -0
- package/src/providers/notion/executors.js +39 -3
- package/src/providers/notion_mcp/endpoints.d.ts +3 -0
- package/src/providers/notion_mcp/endpoints.js +3 -0
- package/src/providers/notion_mcp/executors.d.ts +3 -0
- package/src/providers/notion_mcp/executors.js +176 -0
- package/src/providers/notion_mcp/mcp-response.d.ts +86 -0
- package/src/providers/notion_mcp/mcp-response.js +314 -0
- package/src/providers/odoo/executors.d.ts +3 -0
- package/src/providers/odoo/executors.js +32 -0
- package/src/providers/odoo/runtime.d.ts +16 -0
- package/src/providers/odoo/runtime.js +140 -0
- package/src/providers/osv/executors.d.ts +2 -0
- package/src/providers/osv/executors.js +11 -0
- package/src/providers/osv/runtime.d.ts +9 -0
- package/src/providers/osv/runtime.js +66 -0
- package/src/providers/outlook/executors.js +27 -6
- package/src/providers/outlook/microsoft-graph.js +17 -6
- package/src/providers/outlook_calendar/executors.js +24 -7
- package/src/providers/patsnap_mcp/executors.js +2 -2
- package/src/providers/pdf_vector/executors.d.ts +4 -0
- package/src/providers/pdf_vector/executors.js +108 -0
- package/src/providers/postiz/executors.d.ts +4 -0
- package/src/providers/postiz/executors.js +83 -0
- package/src/providers/provider-runtime.d.ts +18 -0
- package/src/providers/provider-runtime.js +60 -4
- package/src/providers/proworkflow/executors.d.ts +4 -0
- package/src/providers/proworkflow/executors.js +135 -0
- package/src/providers/pulsetic/executors.d.ts +4 -0
- package/src/providers/pulsetic/executors.js +126 -0
- package/src/providers/registry.generated.js +24 -0
- package/src/providers/scrape_creators/catalog.js +1 -1
- package/src/providers/scrape_creators/runtime.js +1 -1
- package/src/providers/sellersprite_mcp/executors.js +2 -2
- package/src/providers/sellersprite_mcp/official-actions.js +3 -2
- package/src/providers/sentry/runtime.js +6 -7
- package/src/providers/shopee/actions.d.ts +2 -0
- package/src/providers/shopee/actions.js +474 -0
- package/src/providers/shopee/executors.d.ts +3 -0
- package/src/providers/shopee/executors.js +85 -0
- package/src/providers/shopee/runtime.d.ts +79 -0
- package/src/providers/shopee/runtime.js +693 -0
- package/src/providers/slack/actions.js +69 -3
- package/src/providers/slack/runtime.js +116 -21
- package/src/providers/slickdeals/runtime.js +1 -1
- package/src/providers/sorftime_mcp/executors.js +2 -2
- package/src/providers/speak_ai/executors.d.ts +3 -0
- package/src/providers/speak_ai/executors.js +187 -0
- package/src/providers/tikhub/bounded-response.d.ts +1 -1
- package/src/providers/tikhub/bounded-response.js +8 -34
- package/src/providers/tikhub/endpoint-catalog.js +1 -1
- package/src/providers/tikhub/runtime.js +2 -2
- package/src/providers/tongdaxin/executors.js +79 -15
- package/src/providers/tushare/runtime.js +22 -9
- package/src/providers/uspto/executors.js +1 -1
- package/src/providers/waffo/executors.js +1 -1
- package/src/providers/waffo/runtime.js +1 -1
- package/src/providers/wecom_mcp/runtime.js +1 -1
- package/src/providers/wisburg/executors.d.ts +4 -0
- package/src/providers/wisburg/executors.js +13 -0
- package/src/providers/wisburg/runtime.d.ts +12 -0
- package/src/providers/wisburg/runtime.js +133 -0
- package/src/providers/xydc_mcp/executors.js +2 -2
- package/src/providers/youtube/executors.js +1 -1
- package/src/providers/youtube/runtime.js +1 -1
- package/src/providers/zerotier/executors.d.ts +9 -0
- package/src/providers/zerotier/executors.js +629 -0
- package/src/providers/zerotier/runtime.d.ts +54 -0
- package/src/providers/zerotier/runtime.js +207 -0
- package/src/providers/zyhub/executors.d.ts +3 -0
- package/src/providers/zyhub/executors.js +240 -0
- package/src/server/api/openapi.js +12 -2
- package/src/server/api/runtime-api.d.ts +8 -1
- package/src/server/api/runtime-api.js +19 -1
- package/src/server/connect-server.js +10 -2
- package/src/server/files/transit-files.d.ts +3 -2
- package/src/server/files/transit-files.js +31 -35
- package/src/providers/sentry/scopes.d.ts +0 -1
- package/src/providers/sentry/scopes.js +0 -7
- /package/src/providers/{cloudflare-current-user.d.ts → cloudflare_dns/runtime-user.d.ts} +0 -0
|
@@ -1,44 +1,18 @@
|
|
|
1
|
+
import { readBoundedResponseBytes } from "../../core/request.js";
|
|
1
2
|
import { TikHubRequestError } from "./errors.js";
|
|
2
3
|
export class BoundedResponseTooLargeError extends TikHubRequestError {
|
|
3
4
|
}
|
|
4
5
|
export async function readBoundedResponseText(response, input) {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
throw responseTooLarge(input);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
if (!response.body) {
|
|
14
|
-
return "";
|
|
15
|
-
}
|
|
16
|
-
const reader = response.body.getReader();
|
|
17
|
-
const chunks = [];
|
|
18
|
-
let totalBytes = 0;
|
|
19
|
-
while (true) {
|
|
20
|
-
const result = await reader.read();
|
|
21
|
-
if (result.done) {
|
|
22
|
-
break;
|
|
23
|
-
}
|
|
24
|
-
totalBytes += result.value.byteLength;
|
|
25
|
-
if (totalBytes > input.maxBytes) {
|
|
26
|
-
await reader.cancel();
|
|
27
|
-
throw responseTooLarge(input);
|
|
28
|
-
}
|
|
29
|
-
chunks.push(result.value);
|
|
30
|
-
}
|
|
31
|
-
const bytes = new Uint8Array(totalBytes);
|
|
32
|
-
let offset = 0;
|
|
33
|
-
for (const chunk of chunks) {
|
|
34
|
-
bytes.set(chunk, offset);
|
|
35
|
-
offset += chunk.byteLength;
|
|
36
|
-
}
|
|
6
|
+
const bytes = await readBoundedResponseBytes(response, {
|
|
7
|
+
maxBytes: input.maxBytes,
|
|
8
|
+
fieldName: input.label,
|
|
9
|
+
createError: () => responseTooLarge(input),
|
|
10
|
+
});
|
|
37
11
|
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
38
12
|
}
|
|
39
|
-
export
|
|
13
|
+
export function cancelResponseBody(response) {
|
|
40
14
|
try {
|
|
41
|
-
|
|
15
|
+
void response.body?.cancel().catch(() => undefined);
|
|
42
16
|
}
|
|
43
17
|
catch {
|
|
44
18
|
return;
|
|
@@ -105,7 +105,7 @@ async function fetchOpenApi(fetcher) {
|
|
|
105
105
|
const response = await fetcher(tikhubOpenApiUrl, {
|
|
106
106
|
method: "GET",
|
|
107
107
|
headers: { accept: "application/json" },
|
|
108
|
-
redirect: "
|
|
108
|
+
redirect: "manual",
|
|
109
109
|
signal: timeout.signal,
|
|
110
110
|
});
|
|
111
111
|
if (!response.ok) {
|
|
@@ -166,7 +166,7 @@ async function invokeTikHubEndpoint(input, fetcher, apiKey) {
|
|
|
166
166
|
"user-agent": providerUserAgent,
|
|
167
167
|
},
|
|
168
168
|
...(serializedBody === undefined ? {} : { body: serializedBody }),
|
|
169
|
-
redirect: "
|
|
169
|
+
redirect: "manual",
|
|
170
170
|
signal: timeout.signal,
|
|
171
171
|
});
|
|
172
172
|
let responseBody;
|
|
@@ -454,7 +454,7 @@ async function requestTikHubUserJson(input) {
|
|
|
454
454
|
authorization: `Bearer ${input.apiKey}`,
|
|
455
455
|
"user-agent": providerUserAgent,
|
|
456
456
|
},
|
|
457
|
-
redirect: "
|
|
457
|
+
redirect: "manual",
|
|
458
458
|
signal: timeout.signal,
|
|
459
459
|
});
|
|
460
460
|
const payload = await readTikHubResponseBody(response, tikhubDynamicResponseMaxBytes);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ProtocolError, SdkHttpError, UnauthorizedError } from "@modelcontextprotocol/client";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import { optionalRecord } from "../../core/cast.js";
|
|
3
|
+
import { optionalNumber, optionalRecord, optionalString } from "../../core/cast.js";
|
|
4
|
+
import { readBoundedResponseBytes } from "../../core/request.js";
|
|
4
5
|
import { withMcpClient } from "../mcp-client.js";
|
|
5
6
|
import { defineApiKeyProviderExecutors, providerUserAgent, ProviderRequestError, requiredInputString, } from "../provider-runtime.js";
|
|
6
7
|
import { tongdaxinActions, tongdaxinReadOnlyToolNames } from "./actions.js";
|
|
@@ -9,10 +10,15 @@ import { isTongdaxinNamedActionName, resolveTongdaxinNamedToolCall } from "./nam
|
|
|
9
10
|
const service = "tongdaxin";
|
|
10
11
|
const endpoint = new URL("https://txmcp.tdx.com.cn:3001/txmcp");
|
|
11
12
|
const requestTimeoutMs = 60_000;
|
|
13
|
+
const errorResponseMaxBytes = 64 * 1024;
|
|
14
|
+
const insufficientPointsToolError = "MCP error -32603: Your usage quota has been reached";
|
|
15
|
+
const insufficientPointsDescription = "TDX MCP quota is below 10. Please recharge before continuing.";
|
|
16
|
+
const rechargeOrigin = "https://vip.tdx.com.cn";
|
|
17
|
+
const rechargePath = "/site/app/pc-mall/main.html";
|
|
12
18
|
const supportedToolNames = new Set(tongdaxinReadOnlyToolNames);
|
|
13
19
|
const handlers = {
|
|
14
20
|
async list_tools(_input, context) {
|
|
15
|
-
return { tools: await discoverSupportedTools(context
|
|
21
|
+
return { tools: await discoverSupportedTools(context) };
|
|
16
22
|
},
|
|
17
23
|
async call_tool(input, context) {
|
|
18
24
|
const toolName = requiredInputString(input.toolName, "toolName");
|
|
@@ -20,7 +26,8 @@ const handlers = {
|
|
|
20
26
|
if (!argumentsValue)
|
|
21
27
|
throw new ProviderRequestError(400, "arguments must be a JSON object");
|
|
22
28
|
assertToolArgumentsSize(argumentsValue);
|
|
23
|
-
const result = await withTongdaxinClient(context,
|
|
29
|
+
const result = await withTongdaxinClient(context, false, (client) => client.callTool({ name: toolName, arguments: argumentsValue }, { timeout: requestTimeoutMs, signal: context.signal }));
|
|
30
|
+
assertSufficientTongdaxinCredit(result);
|
|
24
31
|
if (!("toolResult" in result) && result.isError) {
|
|
25
32
|
throw new ProviderRequestError(502, `Tongdaxin MCP tool ${toolName} returned an error`, result);
|
|
26
33
|
}
|
|
@@ -37,7 +44,7 @@ for (const actionName of Object.keys(resolveNamedHandlers())) {
|
|
|
37
44
|
throw new ProviderRequestError(400, `Unknown action: ${actionName}`);
|
|
38
45
|
const toolCall = resolveTongdaxinNamedToolCall(actionName, input);
|
|
39
46
|
assertToolArgumentsSize(toolCall.arguments);
|
|
40
|
-
const tools = await discoverSupportedTools(context
|
|
47
|
+
const tools = await discoverSupportedTools(context);
|
|
41
48
|
const tool = tools.find((candidate) => candidate.name === toolCall.toolName);
|
|
42
49
|
if (!tool && toolCall.toolName !== "wenda_macro_query") {
|
|
43
50
|
throw new ProviderRequestError(409, `Tongdaxin action ${actionName} is unavailable because this connection does not expose ${toolCall.toolName}`);
|
|
@@ -48,7 +55,8 @@ for (const actionName of Object.keys(resolveNamedHandlers())) {
|
|
|
48
55
|
tool.annotations.destructiveHint === true)) {
|
|
49
56
|
throw new ProviderRequestError(403, `Tongdaxin MCP does not currently affirm ${tool.name} as a non-destructive read-only tool`);
|
|
50
57
|
}
|
|
51
|
-
const result = await withTongdaxinClient(context,
|
|
58
|
+
const result = await withTongdaxinClient(context, true, (client) => client.callTool({ name: toolCall.toolName, arguments: toolCall.arguments }, { timeout: requestTimeoutMs, signal: context.signal }));
|
|
59
|
+
assertSufficientTongdaxinCredit(result);
|
|
52
60
|
if (!("toolResult" in result) && result.isError) {
|
|
53
61
|
throw new ProviderRequestError(502, `Tongdaxin MCP tool ${toolCall.toolName} returned an error`, result);
|
|
54
62
|
}
|
|
@@ -62,7 +70,7 @@ export const executors = defineApiKeyProviderExecutors(service, handlers, {
|
|
|
62
70
|
export const credentialValidators = {
|
|
63
71
|
async apiKey(input, { fetcher, signal }) {
|
|
64
72
|
const context = { apiKey: input.apiKey, fetcher, signal };
|
|
65
|
-
const tools = await discoverSupportedTools(context
|
|
73
|
+
const tools = await discoverSupportedTools(context);
|
|
66
74
|
if (tools.length === 0) {
|
|
67
75
|
throw new ProviderRequestError(400, "Tongdaxin MCP did not expose any supported read-only tools");
|
|
68
76
|
}
|
|
@@ -77,8 +85,8 @@ export const credentialValidators = {
|
|
|
77
85
|
};
|
|
78
86
|
},
|
|
79
87
|
};
|
|
80
|
-
async function discoverSupportedTools(context
|
|
81
|
-
const result = await withTongdaxinClient(context,
|
|
88
|
+
async function discoverSupportedTools(context) {
|
|
89
|
+
const result = await withTongdaxinClient(context, true, (client) => client.listTools({}, { timeout: requestTimeoutMs, signal: context.signal }));
|
|
82
90
|
return result.tools.map((tool) => ({
|
|
83
91
|
name: tool.name,
|
|
84
92
|
description: tool.description,
|
|
@@ -86,30 +94,30 @@ async function discoverSupportedTools(context, phase) {
|
|
|
86
94
|
inputSchema: tool.inputSchema,
|
|
87
95
|
}));
|
|
88
96
|
}
|
|
89
|
-
async function withTongdaxinClient(context,
|
|
97
|
+
async function withTongdaxinClient(context, retryOnSessionNotFound, run) {
|
|
90
98
|
return withMcpClient({
|
|
91
99
|
endpoint,
|
|
92
100
|
transport: "streamable_http",
|
|
93
|
-
fetcher: context.fetcher,
|
|
101
|
+
fetcher: createTongdaxinFetcher(context.fetcher),
|
|
94
102
|
headers: {
|
|
95
103
|
authorization: `Bearer ${context.apiKey}`,
|
|
96
104
|
"user-agent": providerUserAgent,
|
|
97
105
|
},
|
|
98
|
-
redirect: "
|
|
106
|
+
redirect: "manual",
|
|
99
107
|
signal: context.signal,
|
|
100
108
|
retryOnSessionNotFound,
|
|
101
|
-
mapError:
|
|
109
|
+
mapError: mapTongdaxinError,
|
|
102
110
|
}, run);
|
|
103
111
|
}
|
|
104
|
-
function mapTongdaxinError(error
|
|
112
|
+
function mapTongdaxinError(error) {
|
|
105
113
|
if (error instanceof ProviderRequestError)
|
|
106
114
|
return error;
|
|
107
115
|
if (error instanceof UnauthorizedError) {
|
|
108
|
-
return new ProviderRequestError(
|
|
116
|
+
return new ProviderRequestError(401, "Tongdaxin MCP denied this request");
|
|
109
117
|
}
|
|
110
118
|
if (error instanceof SdkHttpError) {
|
|
111
119
|
if (error.status === 401) {
|
|
112
|
-
return new ProviderRequestError(
|
|
120
|
+
return new ProviderRequestError(401, "Tongdaxin MCP denied this request");
|
|
113
121
|
}
|
|
114
122
|
const status = 400 <= error.status && error.status < 500 ? error.status : 502;
|
|
115
123
|
return new ProviderRequestError(status, `Tongdaxin MCP request failed: ${error.message}`, error);
|
|
@@ -119,6 +127,62 @@ function mapTongdaxinError(error, phase) {
|
|
|
119
127
|
}
|
|
120
128
|
return new ProviderRequestError(502, error instanceof Error ? `Tongdaxin MCP request failed: ${error.message}` : "Tongdaxin MCP request failed", error);
|
|
121
129
|
}
|
|
130
|
+
function createTongdaxinFetcher(fetcher) {
|
|
131
|
+
return (async (...arguments_) => {
|
|
132
|
+
const response = await fetcher(...arguments_);
|
|
133
|
+
const details = await readInsufficientPoints(response);
|
|
134
|
+
if (details) {
|
|
135
|
+
void response.body?.cancel().catch(() => undefined);
|
|
136
|
+
throw insufficientCreditError(details);
|
|
137
|
+
}
|
|
138
|
+
return response;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
async function readInsufficientPoints(response) {
|
|
142
|
+
if (response.status !== 401)
|
|
143
|
+
return undefined;
|
|
144
|
+
try {
|
|
145
|
+
const bytes = await readBoundedResponseBytes(response.clone(), {
|
|
146
|
+
maxBytes: errorResponseMaxBytes,
|
|
147
|
+
fieldName: "Tongdaxin MCP error response",
|
|
148
|
+
createError: (message) => new Error(message),
|
|
149
|
+
});
|
|
150
|
+
const payload = optionalRecord(JSON.parse(new TextDecoder().decode(bytes)));
|
|
151
|
+
const remainingCredit = optionalNumber(payload?.leftValue);
|
|
152
|
+
const rechargeUrl = optionalString(payload?.recharge_url);
|
|
153
|
+
if (payload?.error !== "unauthorized" ||
|
|
154
|
+
payload?.error_description !== insufficientPointsDescription ||
|
|
155
|
+
remainingCredit === undefined ||
|
|
156
|
+
!isOfficialRechargeUrl(rechargeUrl)) {
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
return { remainingCredit, rechargeUrl };
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function isOfficialRechargeUrl(value) {
|
|
166
|
+
if (!value)
|
|
167
|
+
return false;
|
|
168
|
+
try {
|
|
169
|
+
const url = new URL(value);
|
|
170
|
+
return url.origin === rechargeOrigin && url.pathname === rechargePath;
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function assertSufficientTongdaxinCredit(result) {
|
|
177
|
+
if (!("content" in result) || result.isError !== true)
|
|
178
|
+
return;
|
|
179
|
+
const exhausted = result.content.some((content) => content.type === "text" && content.text === insufficientPointsToolError);
|
|
180
|
+
if (exhausted)
|
|
181
|
+
throw insufficientCreditError();
|
|
182
|
+
}
|
|
183
|
+
function insufficientCreditError(details) {
|
|
184
|
+
return new ProviderRequestError(402, "Tongdaxin AI points are insufficient. Recharge the account before retrying.", details ?? { rechargeUrl: `${rechargeOrigin}${rechargePath}#/page_product_ai_jfb` }, "insufficient_credit");
|
|
185
|
+
}
|
|
122
186
|
function resolveNamedHandlers() {
|
|
123
187
|
return Object.fromEntries(tongdaxinActions
|
|
124
188
|
.filter((action) => action.name !== "list_tools" && action.name !== "call_tool")
|
|
@@ -234,12 +234,18 @@ export const tushareActionHandlers = {
|
|
|
234
234
|
},
|
|
235
235
|
};
|
|
236
236
|
export async function validateTushareCredential(apiKey, fetcher, signal) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
237
|
+
try {
|
|
238
|
+
const payload = await tushareRequest({
|
|
239
|
+
apiName: "daily",
|
|
240
|
+
params: { ts_code: "000001.SZ", trade_date: "20180903" },
|
|
241
|
+
fields: "ts_code,trade_date",
|
|
242
|
+
}, { apiKey, fetcher, signal });
|
|
243
|
+
normalizeTableData(payload.data);
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
if (!(error instanceof ProviderRequestError) || error.status !== 403)
|
|
247
|
+
throw error;
|
|
248
|
+
}
|
|
243
249
|
return {
|
|
244
250
|
profile: {
|
|
245
251
|
accountId: "tushare-token",
|
|
@@ -248,7 +254,7 @@ export async function validateTushareCredential(apiKey, fetcher, signal) {
|
|
|
248
254
|
grantedScopes: [],
|
|
249
255
|
metadata: {
|
|
250
256
|
apiBaseUrl: tushareApiBaseUrl,
|
|
251
|
-
validationApiName: "
|
|
257
|
+
validationApiName: "daily",
|
|
252
258
|
credentialHelpUrl: "https://tushare.pro/document/1?doc_id=39",
|
|
253
259
|
},
|
|
254
260
|
};
|
|
@@ -333,8 +339,10 @@ async function readJsonPayload(response) {
|
|
|
333
339
|
}
|
|
334
340
|
function createTushareHttpError(status, payload) {
|
|
335
341
|
const message = extractErrorMessage(payload) ?? `Tushare request failed with ${status || 500}`;
|
|
336
|
-
if (status === 401
|
|
342
|
+
if (status === 401)
|
|
337
343
|
return new ProviderRequestError(400, message, payload);
|
|
344
|
+
if (status === 403)
|
|
345
|
+
return new ProviderRequestError(403, message, payload);
|
|
338
346
|
if (status === 429)
|
|
339
347
|
return new ProviderRequestError(429, message, payload);
|
|
340
348
|
return new ProviderRequestError(status || 502, message, payload);
|
|
@@ -343,12 +351,17 @@ function createTushareApiError(code, payload) {
|
|
|
343
351
|
const message = `Tushare request failed: ${extractErrorMessage(payload) ?? `code ${code}`}`;
|
|
344
352
|
if (code === 40101)
|
|
345
353
|
return new ProviderRequestError(400, message, payload);
|
|
346
|
-
if (code
|
|
354
|
+
if (isTusharePermissionError(code, message))
|
|
347
355
|
return new ProviderRequestError(403, message, payload);
|
|
348
356
|
if (code === 2003 || code === 2004 || message.includes("频率超限"))
|
|
349
357
|
return new ProviderRequestError(429, message, payload);
|
|
350
358
|
return new ProviderRequestError(502, message, payload);
|
|
351
359
|
}
|
|
360
|
+
function isTusharePermissionError(code, message) {
|
|
361
|
+
return (code === 2002 ||
|
|
362
|
+
message.includes("没有权限访问该接口") ||
|
|
363
|
+
(message.includes("没有接口(") && message.includes("访问权限")));
|
|
364
|
+
}
|
|
352
365
|
function normalizeTableData(value) {
|
|
353
366
|
const data = requiredResponseRecord(value, "data");
|
|
354
367
|
return {
|
|
@@ -2,7 +2,7 @@ import { defineApiKeyProviderExecutors, defineProviderProxy, ProviderRequestErro
|
|
|
2
2
|
async function get(path, accept, apiKey, fetcher, signal) {
|
|
3
3
|
const response = await fetcher(new URL(path, "https://tsdrapi.uspto.gov"), {
|
|
4
4
|
headers: { accept, "USPTO-API-KEY": apiKey, "user-agent": providerUserAgent },
|
|
5
|
-
redirect: "
|
|
5
|
+
redirect: "manual",
|
|
6
6
|
signal,
|
|
7
7
|
});
|
|
8
8
|
const text = await response.text();
|
|
@@ -37,7 +37,7 @@ export const proxy = async (input, context) => {
|
|
|
37
37
|
method: input.method,
|
|
38
38
|
headers,
|
|
39
39
|
body: input.method === "GET" || input.body == null ? undefined : signingBody,
|
|
40
|
-
redirect: "
|
|
40
|
+
redirect: "manual",
|
|
41
41
|
signal: context.signal,
|
|
42
42
|
});
|
|
43
43
|
if (!response.ok) {
|
|
@@ -173,7 +173,7 @@ async function withWeComMcpClient(context, run) {
|
|
|
173
173
|
transport: "streamable_http",
|
|
174
174
|
fetcher: createWeComRateLimitedFetch(context.fetcher, hashWeComRateLimitKey(context)),
|
|
175
175
|
headers,
|
|
176
|
-
redirect: "
|
|
176
|
+
redirect: "manual",
|
|
177
177
|
signal: context.signal,
|
|
178
178
|
mapError: mapWeComMcpError,
|
|
179
179
|
}, run);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CredentialValidators, ProviderExecutors, ProviderProxyExecutor } from "../../core/types.ts";
|
|
2
|
+
export declare const executors: ProviderExecutors;
|
|
3
|
+
export declare const proxy: ProviderProxyExecutor;
|
|
4
|
+
export declare const credentialValidators: CredentialValidators;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineApiKeyProviderExecutors, defineProviderProxy } from "../provider-runtime.js";
|
|
2
|
+
import { validateWisburgCredential, wisburgActionHandlers, wisburgApiBaseUrl } from "./runtime.js";
|
|
3
|
+
const service = "wisburg";
|
|
4
|
+
export const executors = defineApiKeyProviderExecutors(service, wisburgActionHandlers, {
|
|
5
|
+
skipDnsValidation: true,
|
|
6
|
+
});
|
|
7
|
+
export const proxy = defineProviderProxy({
|
|
8
|
+
service,
|
|
9
|
+
baseUrl: wisburgApiBaseUrl,
|
|
10
|
+
auth: { type: "api_key_authorization", prefix: "Bearer " },
|
|
11
|
+
skipDnsValidation: true,
|
|
12
|
+
});
|
|
13
|
+
export const credentialValidators = { apiKey: validateWisburgCredential };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CredentialValidationResult } from "../../core/types.ts";
|
|
2
|
+
import type { ApiKeyProviderContext, ProviderActionHandlers, ProviderRuntimeHandler } from "../provider-runtime.ts";
|
|
3
|
+
/** Output key a detail action nests its resource under. */
|
|
4
|
+
export type WisburgDetailKey = "report" | "article" | "log";
|
|
5
|
+
export declare const wisburgApiBaseUrl = "https://api-omen.wisburg.com";
|
|
6
|
+
export declare const wisburgActionHandlers: ProviderActionHandlers<"wisburg", ProviderRuntimeHandler<ApiKeyProviderContext>>;
|
|
7
|
+
export declare function validateWisburgCredential(input: {
|
|
8
|
+
apiKey: string;
|
|
9
|
+
}, { fetcher, signal }: {
|
|
10
|
+
fetcher: typeof fetch;
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
}): Promise<CredentialValidationResult>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { sha256Hex } from "../../core/aws-sigv4.js";
|
|
2
|
+
import { objectArray, optionalInteger, optionalNumber, optionalRecord, optionalString } from "../../core/cast.js";
|
|
3
|
+
import { ProviderRequestError, parseProviderJsonBodyText, providerResponseError, providerUserAgent, readProviderErrorTextBody, readProviderJsonBody, requiredInputNumber, requiredResponseRecord, runProviderRequest, setSearchParams, } from "../provider-runtime.js";
|
|
4
|
+
export const wisburgApiBaseUrl = "https://api-omen.wisburg.com";
|
|
5
|
+
export const wisburgActionHandlers = {
|
|
6
|
+
list_reports: (input, context) => listWisburgResource(input, context, "api/reports"),
|
|
7
|
+
get_report: (input, context) => getWisburgResource(input, context, "api/reports", "report"),
|
|
8
|
+
list_archives: (input, context) => listWisburgResource(input, context, "api/archives"),
|
|
9
|
+
get_archive: (input, context) => getWisburgResource(input, context, "api/archives", "report"),
|
|
10
|
+
list_company_reports: (input, context) => listWisburgResource(input, context, "api/company-reports"),
|
|
11
|
+
get_company_report: (input, context) => getWisburgResource(input, context, "api/company-reports", "report"),
|
|
12
|
+
list_earnings_calls: (input, context) => listWisburgResource(input, context, "api/earningscalls"),
|
|
13
|
+
get_earnings_call: (input, context) => getWisburgResource(input, context, "api/earningscalls", "report"),
|
|
14
|
+
list_articles: (input, context) => listWisburgResource(input, context, "api/articles"),
|
|
15
|
+
get_article: (input, context) => getWisburgResource(input, context, "api/articles", "article"),
|
|
16
|
+
list_market_daily: (input, context) => listWisburgResource(input, context, "api/market-daily"),
|
|
17
|
+
list_feed: (input, context) => listWisburgResource(input, context, "api/feed"),
|
|
18
|
+
list_images: (input, context) => listWisburgResource(input, context, "api/images"),
|
|
19
|
+
list_am_reports: (input, context) => listWisburgResource(input, context, "api/am-reports"),
|
|
20
|
+
get_am_report: (input, context) => getWisburgResource(input, context, "api/am-reports", "report"),
|
|
21
|
+
list_mikko_logs: (input, context) => listWisburgResource(input, context, "api/mikko-logs"),
|
|
22
|
+
get_mikko_log: (input, context) => getWisburgResource(input, context, "api/mikko-logs", "log"),
|
|
23
|
+
};
|
|
24
|
+
export async function validateWisburgCredential(input, { fetcher, signal }) {
|
|
25
|
+
try {
|
|
26
|
+
await wisburgRequest({ apiKey: input.apiKey, fetcher, signal }, { path: "api/feed", query: { first: "1" } });
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
if (error instanceof ProviderRequestError && error.status === 401) {
|
|
30
|
+
throw new ProviderRequestError(400, error.message, error.details);
|
|
31
|
+
}
|
|
32
|
+
// A 403 proves the key was accepted; the feed is simply outside this key's subscription.
|
|
33
|
+
if (!(error instanceof ProviderRequestError) || error.status !== 403)
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
profile: {
|
|
38
|
+
accountId: `wisburg:${sha256Hex(input.apiKey).slice(0, 32)}`,
|
|
39
|
+
displayName: "Wisburg API Key",
|
|
40
|
+
},
|
|
41
|
+
grantedScopes: [],
|
|
42
|
+
metadata: {
|
|
43
|
+
apiBaseUrl: wisburgApiBaseUrl,
|
|
44
|
+
validationEndpoint: "/api/feed",
|
|
45
|
+
credentialHelpUrl: "https://open-docs.wisburg.com/docs/getting-started/first-call",
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async function listWisburgResource(input, context, path) {
|
|
50
|
+
const envelope = await wisburgRequest(context, {
|
|
51
|
+
path,
|
|
52
|
+
query: {
|
|
53
|
+
first: optionalInteger(input.first)?.toString(),
|
|
54
|
+
after: optionalString(input.after),
|
|
55
|
+
query: optionalString(input.query),
|
|
56
|
+
startTime: optionalString(input.startTime),
|
|
57
|
+
endTime: optionalString(input.endTime),
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
const data = requiredResponseRecord(envelope.data, "Wisburg list data");
|
|
61
|
+
const pageInfo = requiredResponseRecord(data.page_info, "Wisburg list page_info");
|
|
62
|
+
const endCursor = pageInfo.end_cursor;
|
|
63
|
+
if (endCursor != null && typeof endCursor !== "string") {
|
|
64
|
+
throw providerResponseError("Wisburg list page_info.end_cursor must be a string");
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
requestId: optionalString(envelope.request_id) ?? "",
|
|
68
|
+
items: objectArray(data.items, "Wisburg list data.items", providerResponseError),
|
|
69
|
+
pageInfo: { endCursor: optionalString(endCursor) },
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async function getWisburgResource(input, context, path, key) {
|
|
73
|
+
const id = requiredInputNumber(input.id, "id");
|
|
74
|
+
const envelope = await wisburgRequest(context, { path: `${path}/${id}` });
|
|
75
|
+
return {
|
|
76
|
+
requestId: optionalString(envelope.request_id) ?? "",
|
|
77
|
+
[key]: requiredResponseRecord(envelope.data, "Wisburg detail data"),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
async function wisburgRequest(context, input) {
|
|
81
|
+
return runProviderRequest({ signal: context.signal, label: "Wisburg" }, async (signal) => {
|
|
82
|
+
const url = new URL(input.path, `${wisburgApiBaseUrl}/`);
|
|
83
|
+
setSearchParams(url, input.query ?? {});
|
|
84
|
+
const response = await context.fetcher(url, {
|
|
85
|
+
headers: {
|
|
86
|
+
accept: "application/json",
|
|
87
|
+
authorization: `Bearer ${context.apiKey}`,
|
|
88
|
+
"user-agent": providerUserAgent,
|
|
89
|
+
},
|
|
90
|
+
signal,
|
|
91
|
+
});
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
throw await readWisburgHttpError(response);
|
|
94
|
+
}
|
|
95
|
+
const payload = await readProviderJsonBody(response, {
|
|
96
|
+
emptyBody: {},
|
|
97
|
+
invalidJsonMessage: "Wisburg returned invalid JSON",
|
|
98
|
+
});
|
|
99
|
+
const envelope = requiredResponseRecord(payload, "Wisburg response");
|
|
100
|
+
const code = optionalNumber(envelope.code);
|
|
101
|
+
if (code !== undefined && code !== 200) {
|
|
102
|
+
throw mapWisburgError(code, envelope);
|
|
103
|
+
}
|
|
104
|
+
// The envelope marks failure as status 1 even when the code field disagrees; fall back to the 1002 internal-error code when none is present.
|
|
105
|
+
if (optionalNumber(envelope.status) === 1) {
|
|
106
|
+
throw mapWisburgError(code ?? 1002, envelope);
|
|
107
|
+
}
|
|
108
|
+
return envelope;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// Keep the HTTP status for non-JSON gateway error pages; the JSON envelope, when present, only supplies the code and message.
|
|
112
|
+
async function readWisburgHttpError(response) {
|
|
113
|
+
const text = await readProviderErrorTextBody(response, "Wisburg error response");
|
|
114
|
+
const parsed = parseProviderJsonBodyText(text, {
|
|
115
|
+
emptyBody: {},
|
|
116
|
+
invalidJsonMessage: "Wisburg returned invalid JSON",
|
|
117
|
+
invalidJsonFallback: () => ({}),
|
|
118
|
+
});
|
|
119
|
+
const envelope = optionalRecord(parsed) ?? {};
|
|
120
|
+
return mapWisburgError(optionalNumber(envelope.code) ?? response.status, envelope);
|
|
121
|
+
}
|
|
122
|
+
function mapWisburgError(code, envelope) {
|
|
123
|
+
const message = optionalString(envelope.message) ?? `Wisburg request failed (${code})`;
|
|
124
|
+
// Besides the documented 401/403/404/429 codes, a bare gateway 4xx such as 414 stays a client error.
|
|
125
|
+
if (code >= 400 && code < 500) {
|
|
126
|
+
return new ProviderRequestError(code, message, envelope);
|
|
127
|
+
}
|
|
128
|
+
// 1001 marks invalid parameters and 1004 an out-of-range pagination cursor.
|
|
129
|
+
if (code === 1001 || code === 1004) {
|
|
130
|
+
return new ProviderRequestError(400, message, envelope);
|
|
131
|
+
}
|
|
132
|
+
return new ProviderRequestError(502, message, envelope);
|
|
133
|
+
}
|
|
@@ -38,7 +38,7 @@ export const proxy = defineProviderProxy({
|
|
|
38
38
|
},
|
|
39
39
|
timeoutMs: generationTimeoutMs,
|
|
40
40
|
skipDnsValidation: true,
|
|
41
|
-
redirect: "
|
|
41
|
+
redirect: "manual",
|
|
42
42
|
customizeRequest({ headers }) {
|
|
43
43
|
headers.set("accept", "application/json, text/event-stream");
|
|
44
44
|
headers.set("content-type", "application/json");
|
|
@@ -61,7 +61,7 @@ async function withClient(context, run) {
|
|
|
61
61
|
transport: "streamable_http",
|
|
62
62
|
fetcher: context.fetcher,
|
|
63
63
|
headers: { authorization: `Bearer ${context.apiKey}`, "user-agent": providerUserAgent },
|
|
64
|
-
redirect: "
|
|
64
|
+
redirect: "manual",
|
|
65
65
|
signal: context.signal,
|
|
66
66
|
mapError,
|
|
67
67
|
}, run);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { googleJsonRequest } from "../
|
|
1
|
+
import { googleJsonRequest } from "../googledrive/runtime-request.js";
|
|
2
2
|
import { defineOAuthProviderExecutors, defineProviderProxy, providerProxyEndpointPrefixes, } from "../provider-runtime.js";
|
|
3
3
|
import { youtubeActionHandlers } from "./runtime.js";
|
|
4
4
|
const service = "youtube";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { compactObject, optionalBoolean, optionalInteger, optionalString, rawStringOrNull } from "../../core/cast.js";
|
|
3
3
|
import { assertPublicHttpUrl, readBoundedResponseBytes } from "../../core/request.js";
|
|
4
|
-
import { googleJsonRequest, googleRequest } from "../
|
|
4
|
+
import { googleJsonRequest, googleRequest } from "../googledrive/runtime-request.js";
|
|
5
5
|
import { providerUserAgent, ProviderRequestError } from "../provider-runtime.js";
|
|
6
6
|
const youtubeApiBaseUrl = "https://www.googleapis.com/youtube/v3";
|
|
7
7
|
const youtubeUploadApiBaseUrl = "https://www.googleapis.com/upload/youtube/v3";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CredentialValidators, ProviderExecutors, ProviderProxyExecutor } from "../../core/types.ts";
|
|
2
|
+
import type { ProviderActionHandlers, ProviderRuntimeHandler } from "../provider-runtime.ts";
|
|
3
|
+
import type { ZerotierActionContext } from "./runtime.ts";
|
|
4
|
+
type ZerotierHandler = ProviderRuntimeHandler<ZerotierActionContext>;
|
|
5
|
+
export declare const zerotierActionHandlers: ProviderActionHandlers<"zerotier", ZerotierHandler>;
|
|
6
|
+
export declare const executors: ProviderExecutors;
|
|
7
|
+
export declare const proxy: ProviderProxyExecutor;
|
|
8
|
+
export declare const credentialValidators: CredentialValidators;
|
|
9
|
+
export {};
|