@oomol-lab/open-connector 1.9.0 → 1.9.1
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/agentearth.json +441 -0
- package/assets/open-connector/catalog/apps/appgrowing_mcp.json +863 -0
- package/assets/open-connector/catalog/apps/arcmira.json +610 -0
- package/assets/open-connector/catalog/apps/bainiu.json +654 -0
- package/assets/open-connector/catalog/apps/chaport.json +331 -0
- package/assets/open-connector/catalog/apps/cnb.json +1408 -0
- package/assets/open-connector/catalog/apps/crtsh.json +123 -0
- package/assets/open-connector/catalog/apps/eastmoney_miaoxiang.json +406 -0
- package/assets/open-connector/catalog/apps/fastmoss_mcp.json +876 -876
- package/assets/open-connector/catalog/apps/ftshare.json +1162 -0
- package/assets/open-connector/catalog/apps/fusion-api.json +143 -0
- package/assets/open-connector/catalog/apps/fxbaogao.json +308 -0
- package/assets/open-connector/catalog/apps/github.json +38 -3
- package/assets/open-connector/catalog/apps/hrmos_kintai.json +7519 -0
- package/assets/open-connector/catalog/apps/humor_api.json +351 -0
- package/assets/open-connector/catalog/apps/kaonavi.json +1723 -0
- package/assets/open-connector/catalog/apps/linear_mcp.json +882 -22
- package/assets/open-connector/catalog/apps/listinggood.json +362 -0
- package/assets/open-connector/catalog/apps/notion_mcp.json +338 -1
- package/assets/open-connector/catalog/apps/outlook.json +414 -0
- package/assets/open-connector/catalog/apps/porteden.json +1258 -0
- package/assets/open-connector/catalog/apps/qiuxiaoce.json +915 -0
- package/assets/open-connector/catalog/apps/qqmusic.json +1834 -0
- package/assets/open-connector/catalog/apps/rakuraku_seisan.json +217 -0
- package/assets/open-connector/catalog/apps/redfox.json +9661 -897
- package/assets/open-connector/catalog/apps/salesforce.json +4907 -0
- package/assets/open-connector/catalog/apps/sansan.json +4594 -0
- package/assets/open-connector/catalog/apps/smarthr.json +8071 -0
- package/assets/open-connector/catalog/apps/smooth.json +914 -0
- package/assets/open-connector/catalog/apps/tapd.json +727 -0
- package/assets/open-connector/catalog/apps/tencent_meeting_mcp.json +1301 -0
- package/assets/open-connector/catalog/apps/threatfox.json +203 -0
- package/assets/open-connector/catalog/apps/tradebee.json +915 -0
- package/assets/open-connector/catalog/apps/twittrapi.json +4914 -0
- package/assets/open-connector/catalog/apps/urlhaus.json +246 -0
- package/assets/open-connector/catalog/apps/weread.json +1514 -0
- package/assets/open-connector/catalog/apps/whatsapp.json +12 -0
- package/assets/open-connector/catalog/apps/zhiliaobiaoxun.json +812 -0
- package/assets/open-connector/catalog/apps-index.json +1 -1
- package/package.json +2 -1
- package/src/connection-service.js +55 -11
- package/src/core/provider-error-codes.d.ts +9 -0
- package/src/core/provider-error-codes.js +13 -0
- package/src/core/request.d.ts +2 -0
- package/src/core/request.js +11 -2
- package/src/mail/imap-smtp/protocol.js +4 -3
- package/src/oauth/oauth-flow-service.js +1 -0
- package/src/oauth/oauth-token.d.ts +2 -0
- package/src/providers/17track/runtime.js +17 -20
- package/src/providers/action-contracts.generated.d.ts +36 -6
- package/src/providers/agentearth/actions.d.ts +2 -0
- package/src/providers/agentearth/actions.js +100 -0
- package/src/providers/agentearth/executors.d.ts +4 -0
- package/src/providers/agentearth/executors.js +109 -0
- package/src/providers/appgrowing_mcp/actions.d.ts +2 -0
- package/src/providers/appgrowing_mcp/actions.js +175 -0
- package/src/providers/appgrowing_mcp/executors.d.ts +4 -0
- package/src/providers/appgrowing_mcp/executors.js +66 -0
- package/src/providers/arcmira/executors.d.ts +3 -0
- package/src/providers/arcmira/executors.js +8 -0
- package/src/providers/arcmira/runtime.d.ts +6 -0
- package/src/providers/arcmira/runtime.js +41 -0
- package/src/providers/bainiu/actions.d.ts +2 -0
- package/src/providers/bainiu/actions.js +108 -0
- package/src/providers/bainiu/executors.d.ts +4 -0
- package/src/providers/bainiu/executors.js +113 -0
- package/src/providers/baixiao/executors.js +1 -1
- package/src/providers/bing_webmaster/executors.js +1 -1
- package/src/providers/chaport/actions.d.ts +2 -0
- package/src/providers/chaport/actions.js +70 -0
- package/src/providers/chaport/executors.d.ts +4 -0
- package/src/providers/chaport/executors.js +128 -0
- package/src/providers/clickup/runtime.js +49 -52
- package/src/providers/cnb/actions.d.ts +2 -0
- package/src/providers/cnb/actions.js +341 -0
- package/src/providers/cnb/executors.d.ts +4 -0
- package/src/providers/cnb/executors.js +135 -0
- package/src/providers/coupontools/runtime.js +11 -14
- package/src/providers/crtsh/executors.d.ts +3 -0
- package/src/providers/crtsh/executors.js +19 -0
- package/src/providers/crtsh/runtime.d.ts +17 -0
- package/src/providers/crtsh/runtime.js +84 -0
- package/src/providers/eastmoney_miaoxiang/actions.d.ts +2 -0
- package/src/providers/eastmoney_miaoxiang/actions.js +95 -0
- package/src/providers/eastmoney_miaoxiang/executors.d.ts +4 -0
- package/src/providers/eastmoney_miaoxiang/executors.js +81 -0
- package/src/providers/fastmoss_mcp/actions-content.d.ts +2 -0
- package/src/providers/fastmoss_mcp/actions-content.js +140 -0
- package/src/providers/fastmoss_mcp/actions-creator.d.ts +2 -0
- package/src/providers/fastmoss_mcp/actions-creator.js +154 -0
- package/src/providers/fastmoss_mcp/actions-product.d.ts +2 -0
- package/src/providers/fastmoss_mcp/actions-product.js +167 -0
- package/src/providers/fastmoss_mcp/actions-research.d.ts +2 -0
- package/src/providers/fastmoss_mcp/actions-research.js +174 -0
- package/src/providers/fastmoss_mcp/actions-shop.d.ts +2 -0
- package/src/providers/fastmoss_mcp/actions-shop.js +142 -0
- package/src/providers/fastmoss_mcp/actions.js +11 -12
- package/src/providers/fastmoss_mcp/schemas.d.ts +51 -0
- package/src/providers/fastmoss_mcp/schemas.js +52 -0
- package/src/providers/ftshare/actions.d.ts +2 -0
- package/src/providers/ftshare/actions.js +124 -0
- package/src/providers/ftshare/executors.d.ts +4 -0
- package/src/providers/ftshare/executors.js +102 -0
- package/src/providers/fusion-api/operations.js +37 -0
- package/src/providers/fxbaogao/actions.d.ts +2 -0
- package/src/providers/fxbaogao/actions.js +74 -0
- package/src/providers/fxbaogao/executors.d.ts +4 -0
- package/src/providers/fxbaogao/executors.js +155 -0
- package/src/providers/github/app-installation.d.ts +37 -0
- package/src/providers/github/app-installation.js +233 -0
- package/src/providers/github/executors.js +93 -15
- package/src/providers/github/runtime-repository.js +21 -1
- package/src/providers/github/runtime-shared.d.ts +2 -0
- package/src/providers/github/runtime-shared.js +1 -0
- package/src/providers/googledrive/runtime-request.js +3 -3
- package/src/providers/hrmos_kintai/actions.d.ts +2 -0
- package/src/providers/hrmos_kintai/actions.js +139 -0
- package/src/providers/hrmos_kintai/attendance-actions.d.ts +2 -0
- package/src/providers/hrmos_kintai/attendance-actions.js +276 -0
- package/src/providers/hrmos_kintai/business-actions.d.ts +2 -0
- package/src/providers/hrmos_kintai/business-actions.js +143 -0
- package/src/providers/hrmos_kintai/business-schemas.d.ts +4 -0
- package/src/providers/hrmos_kintai/business-schemas.js +320 -0
- package/src/providers/hrmos_kintai/executors.d.ts +4 -0
- package/src/providers/hrmos_kintai/executors.js +61 -0
- package/src/providers/hrmos_kintai/export-actions.d.ts +2 -0
- package/src/providers/hrmos_kintai/export-actions.js +58 -0
- package/src/providers/hrmos_kintai/operations.d.ts +9 -0
- package/src/providers/hrmos_kintai/operations.js +278 -0
- package/src/providers/hrmos_kintai/runtime.d.ts +10 -0
- package/src/providers/hrmos_kintai/runtime.js +217 -0
- package/src/providers/hrmos_kintai/schemas.d.ts +10 -0
- package/src/providers/hrmos_kintai/schemas.js +70 -0
- package/src/providers/humor_api/actions.d.ts +2 -0
- package/src/providers/humor_api/actions.js +96 -0
- package/src/providers/humor_api/executors.d.ts +4 -0
- package/src/providers/humor_api/executors.js +76 -0
- package/src/providers/kaonavi/actions.d.ts +4 -0
- package/src/providers/kaonavi/actions.js +144 -0
- package/src/providers/kaonavi/additional-actions.d.ts +10 -0
- package/src/providers/kaonavi/additional-actions.js +203 -0
- package/src/providers/kaonavi/executors.d.ts +4 -0
- package/src/providers/kaonavi/executors.js +69 -0
- package/src/providers/kaonavi/runtime.d.ts +4 -0
- package/src/providers/kaonavi/runtime.js +69 -0
- package/src/providers/linear_mcp/actions.d.ts +14 -0
- package/src/providers/linear_mcp/actions.js +134 -0
- package/src/providers/linear_mcp/runtime-mcp.d.ts +7 -1
- package/src/providers/linear_mcp/runtime-mcp.js +140 -28
- package/src/providers/linkfox/runtime.js +48 -51
- package/src/providers/listinggood/actions.d.ts +2 -0
- package/src/providers/listinggood/actions.js +95 -0
- package/src/providers/listinggood/executors.d.ts +4 -0
- package/src/providers/listinggood/executors.js +99 -0
- package/src/providers/mcp-tools.d.ts +3 -0
- package/src/providers/mcp-tools.js +5 -4
- package/src/providers/notion_mcp/executors.js +53 -24
- package/src/providers/notion_mcp/mcp-response.d.ts +26 -0
- package/src/providers/notion_mcp/mcp-response.js +95 -0
- package/src/providers/omise/executors.js +1 -1
- package/src/providers/outlook/executors.js +35 -2
- package/src/providers/porteden/actions.d.ts +2 -0
- package/src/providers/porteden/actions.js +162 -0
- package/src/providers/porteden/executors.d.ts +4 -0
- package/src/providers/porteden/executors.js +140 -0
- package/src/providers/provider-runtime.d.ts +3 -2
- package/src/providers/pushover/runtime.js +28 -31
- package/src/providers/qianfan/runtime.js +16 -19
- package/src/providers/qiuxiaoce/actions.d.ts +2 -0
- package/src/providers/qiuxiaoce/actions.js +248 -0
- package/src/providers/qiuxiaoce/executors.d.ts +4 -0
- package/src/providers/qiuxiaoce/executors.js +76 -0
- package/src/providers/qiuxiaoce/routes.d.ts +1 -0
- package/src/providers/qiuxiaoce/routes.js +20 -0
- package/src/providers/qqmusic/actions.d.ts +2 -0
- package/src/providers/qqmusic/actions.js +229 -0
- package/src/providers/qqmusic/executors.d.ts +4 -0
- package/src/providers/qqmusic/executors.js +92 -0
- package/src/providers/qqmusic/report-schema.d.ts +4 -0
- package/src/providers/qqmusic/report-schema.js +119 -0
- package/src/providers/rakuraku_seisan/actions.d.ts +2 -0
- package/src/providers/rakuraku_seisan/actions.js +50 -0
- package/src/providers/rakuraku_seisan/executors.d.ts +4 -0
- package/src/providers/rakuraku_seisan/executors.js +40 -0
- package/src/providers/rakuraku_seisan/runtime.d.ts +8 -0
- package/src/providers/rakuraku_seisan/runtime.js +251 -0
- package/src/providers/redfox/actions-account.d.ts +2 -0
- package/src/providers/redfox/actions-account.js +24 -0
- package/src/providers/redfox/actions-autohome.d.ts +2 -0
- package/src/providers/redfox/actions-autohome.js +51 -0
- package/src/providers/redfox/actions-baijiahao.d.ts +2 -0
- package/src/providers/redfox/actions-baijiahao.js +58 -0
- package/src/providers/redfox/actions-bilibili.d.ts +2 -0
- package/src/providers/redfox/actions-bilibili.js +67 -0
- package/src/providers/redfox/actions-dongchedi.d.ts +2 -0
- package/src/providers/redfox/actions-dongchedi.js +49 -0
- package/src/providers/redfox/actions-douyin.d.ts +2 -0
- package/src/providers/redfox/actions-douyin.js +297 -0
- package/src/providers/redfox/actions-generation.d.ts +2 -0
- package/src/providers/redfox/actions-generation.js +293 -0
- package/src/providers/redfox/actions-instagram.d.ts +2 -0
- package/src/providers/redfox/actions-instagram.js +49 -0
- package/src/providers/redfox/actions-kuaishou.d.ts +2 -0
- package/src/providers/redfox/actions-kuaishou.js +53 -0
- package/src/providers/redfox/actions-search.d.ts +2 -0
- package/src/providers/redfox/actions-search.js +125 -0
- package/src/providers/redfox/actions-tiktok.d.ts +2 -0
- package/src/providers/redfox/actions-tiktok.js +136 -0
- package/src/providers/redfox/actions-tools.d.ts +2 -0
- package/src/providers/redfox/actions-tools.js +151 -0
- package/src/providers/redfox/actions-toutiao.d.ts +2 -0
- package/src/providers/redfox/actions-toutiao.js +68 -0
- package/src/providers/redfox/actions-transcription.d.ts +2 -0
- package/src/providers/redfox/actions-transcription.js +165 -0
- package/src/providers/redfox/actions-wechat-channel.d.ts +2 -0
- package/src/providers/redfox/actions-wechat-channel.js +63 -0
- package/src/providers/redfox/actions-wechat.d.ts +2 -0
- package/src/providers/redfox/actions-wechat.js +302 -0
- package/src/providers/redfox/actions-weibo.d.ts +2 -0
- package/src/providers/redfox/actions-weibo.js +61 -0
- package/src/providers/redfox/actions-x.d.ts +2 -0
- package/src/providers/redfox/actions-x.js +126 -0
- package/src/providers/redfox/actions-xiaohongshu.d.ts +2 -0
- package/src/providers/redfox/actions-xiaohongshu.js +244 -0
- package/src/providers/redfox/actions-yiche.d.ts +2 -0
- package/src/providers/redfox/actions-yiche.js +59 -0
- package/src/providers/redfox/actions-youtube.d.ts +2 -0
- package/src/providers/redfox/actions-youtube.js +64 -0
- package/src/providers/redfox/actions-zhihu.d.ts +2 -0
- package/src/providers/redfox/actions-zhihu.js +26 -0
- package/src/providers/redfox/actions.d.ts +2 -0
- package/src/providers/redfox/actions.js +49 -0
- package/src/providers/redfox/executors.d.ts +2 -14
- package/src/providers/redfox/executors.js +28 -551
- package/src/providers/redfox/routes.d.ts +11 -0
- package/src/providers/redfox/routes.js +329 -0
- package/src/providers/redfox/runtime.d.ts +6 -0
- package/src/providers/redfox/runtime.js +151 -0
- package/src/providers/redfox/schemas.d.ts +9 -0
- package/src/providers/redfox/schemas.js +40 -0
- package/src/providers/registry.generated.js +30 -0
- package/src/providers/salesforce/context.d.ts +16 -0
- package/src/providers/salesforce/context.js +58 -0
- package/src/providers/salesforce/executors.d.ts +5 -0
- package/src/providers/salesforce/executors.js +54 -0
- package/src/providers/salesforce/media.d.ts +9 -0
- package/src/providers/salesforce/media.js +66 -0
- package/src/providers/salesforce/oauth.d.ts +2 -0
- package/src/providers/salesforce/oauth.js +89 -0
- package/src/providers/salesforce/runtime-analytics.d.ts +2 -0
- package/src/providers/salesforce/runtime-analytics.js +60 -0
- package/src/providers/salesforce/runtime-automation.d.ts +2 -0
- package/src/providers/salesforce/runtime-automation.js +64 -0
- package/src/providers/salesforce/runtime-base.d.ts +2 -0
- package/src/providers/salesforce/runtime-base.js +51 -0
- package/src/providers/salesforce/runtime-bulk.d.ts +2 -0
- package/src/providers/salesforce/runtime-bulk.js +98 -0
- package/src/providers/salesforce/runtime-data.d.ts +2 -0
- package/src/providers/salesforce/runtime-data.js +207 -0
- package/src/providers/salesforce/runtime-files.d.ts +2 -0
- package/src/providers/salesforce/runtime-files.js +108 -0
- package/src/providers/salesforce/transport.d.ts +9 -0
- package/src/providers/salesforce/transport.js +65 -0
- package/src/providers/sansan/actions.d.ts +2 -0
- package/src/providers/sansan/actions.js +165 -0
- package/src/providers/sansan/admin-actions.d.ts +2 -0
- package/src/providers/sansan/admin-actions.js +181 -0
- package/src/providers/sansan/admin.d.ts +2 -0
- package/src/providers/sansan/admin.js +42 -0
- package/src/providers/sansan/business-actions.d.ts +2 -0
- package/src/providers/sansan/business-actions.js +160 -0
- package/src/providers/sansan/business.d.ts +2 -0
- package/src/providers/sansan/business.js +51 -0
- package/src/providers/sansan/executors.d.ts +4 -0
- package/src/providers/sansan/executors.js +59 -0
- package/src/providers/sansan/file-schema.d.ts +2 -0
- package/src/providers/sansan/file-schema.js +8 -0
- package/src/providers/sansan/files.d.ts +11 -0
- package/src/providers/sansan/files.js +49 -0
- package/src/providers/sansan/organization-actions.d.ts +2 -0
- package/src/providers/sansan/organization-actions.js +198 -0
- package/src/providers/sansan/organization-columns.d.ts +2 -0
- package/src/providers/sansan/organization-columns.js +33 -0
- package/src/providers/sansan/organization.d.ts +2 -0
- package/src/providers/sansan/organization.js +88 -0
- package/src/providers/sansan/read.d.ts +2 -0
- package/src/providers/sansan/read.js +25 -0
- package/src/providers/sansan/request.d.ts +22 -0
- package/src/providers/sansan/request.js +94 -0
- package/src/providers/sansan/schemas.d.ts +7 -0
- package/src/providers/sansan/schemas.js +72 -0
- package/src/providers/shopee/runtime.d.ts +33 -29
- package/src/providers/shopee/runtime.js +166 -169
- package/src/providers/smarthr/actions.d.ts +2 -0
- package/src/providers/smarthr/actions.js +286 -0
- package/src/providers/smarthr/employee-runtime.d.ts +1 -0
- package/src/providers/smarthr/employee-runtime.js +63 -0
- package/src/providers/smarthr/employee-schema.d.ts +3 -0
- package/src/providers/smarthr/employee-schema.js +222 -0
- package/src/providers/smarthr/executors.d.ts +4 -0
- package/src/providers/smarthr/executors.js +35 -0
- package/src/providers/smarthr/pagination.d.ts +1 -0
- package/src/providers/smarthr/pagination.js +84 -0
- package/src/providers/smarthr/resource-routes.d.ts +16 -0
- package/src/providers/smarthr/resource-routes.js +163 -0
- package/src/providers/smarthr/runtime.d.ts +13 -0
- package/src/providers/smarthr/runtime.js +242 -0
- package/src/providers/smarthr/supplemental-actions.d.ts +2 -0
- package/src/providers/smarthr/supplemental-actions.js +541 -0
- package/src/providers/smooth/actions.d.ts +2 -0
- package/src/providers/smooth/actions.js +138 -0
- package/src/providers/smooth/executors.d.ts +4 -0
- package/src/providers/smooth/executors.js +102 -0
- package/src/providers/tapd/actions.d.ts +8 -0
- package/src/providers/tapd/actions.js +89 -0
- package/src/providers/tapd/executors.d.ts +4 -0
- package/src/providers/tapd/executors.js +137 -0
- package/src/providers/teable/runtime.js +12 -15
- package/src/providers/tencent_meeting_mcp/actions.d.ts +2 -0
- package/src/providers/tencent_meeting_mcp/actions.js +420 -0
- package/src/providers/tencent_meeting_mcp/executors.d.ts +4 -0
- package/src/providers/tencent_meeting_mcp/executors.js +117 -0
- package/src/providers/threatfox/executors.d.ts +4 -0
- package/src/providers/threatfox/executors.js +40 -0
- package/src/providers/threatfox/runtime.d.ts +15 -0
- package/src/providers/threatfox/runtime.js +128 -0
- package/src/providers/ticket_tailor/runtime.js +1 -1
- package/src/providers/ticketmaster/runtime.js +3 -6
- package/src/providers/timelinesai/runtime.js +13 -16
- package/src/providers/tradebee/actions.d.ts +2 -0
- package/src/providers/tradebee/actions.js +176 -0
- package/src/providers/tradebee/executors.d.ts +4 -0
- package/src/providers/tradebee/executors.js +83 -0
- package/src/providers/twittrapi/executors.d.ts +4 -0
- package/src/providers/twittrapi/executors.js +17 -0
- package/src/providers/twittrapi/runtime.d.ts +12 -0
- package/src/providers/twittrapi/runtime.js +203 -0
- package/src/providers/urlhaus/executors.d.ts +4 -0
- package/src/providers/urlhaus/executors.js +40 -0
- package/src/providers/urlhaus/runtime.d.ts +15 -0
- package/src/providers/urlhaus/runtime.js +142 -0
- package/src/providers/wangdian/runtime.js +16 -19
- package/src/providers/weread/actions.d.ts +2 -0
- package/src/providers/weread/actions.js +424 -0
- package/src/providers/weread/executors.d.ts +4 -0
- package/src/providers/weread/executors.js +98 -0
- package/src/providers/whatsapp/runtime.js +6 -1
- package/src/providers/workast/runtime.js +12 -17
- package/src/providers/youzan/runtime.js +21 -24
- package/src/providers/zenkit/runtime.js +13 -19
- package/src/providers/zhiliaobiaoxun/actions.d.ts +2 -0
- package/src/providers/zhiliaobiaoxun/actions.js +138 -0
- package/src/providers/zhiliaobiaoxun/executors.d.ts +4 -0
- package/src/providers/zhiliaobiaoxun/executors.js +78 -0
- package/src/server/api/auth.d.ts +2 -0
- package/src/server/api/auth.js +2 -1
- package/src/server/api/console-catalog-routes.d.ts +17 -0
- package/src/server/api/console-catalog-routes.js +88 -0
- package/src/server/api/console-oauth-routes.d.ts +18 -0
- package/src/server/api/console-oauth-routes.js +298 -0
- package/src/server/api/docs-routes.d.ts +12 -0
- package/src/server/api/docs-routes.js +38 -0
- package/src/server/api/http-utils.d.ts +1 -0
- package/src/server/api/http-utils.js +8 -0
- package/src/server/api/marketplace-routes.d.ts +7 -0
- package/src/server/api/marketplace-routes.js +62 -0
- package/src/server/api/mcp-routes.d.ts +18 -0
- package/src/server/api/mcp-routes.js +37 -0
- package/src/server/api/policy-routes.d.ts +13 -0
- package/src/server/api/policy-routes.js +50 -0
- package/src/server/api/policy-snapshot.d.ts +14 -0
- package/src/server/api/policy-snapshot.js +30 -0
- package/src/server/api/run-log-routes.d.ts +7 -0
- package/src/server/api/run-log-routes.js +70 -0
- package/src/server/api/runtime-api.d.ts +0 -7
- package/src/server/api/runtime-api.js +0 -13
- package/src/server/api/runtime-app-routes.d.ts +10 -0
- package/src/server/api/runtime-app-routes.js +72 -0
- package/src/server/api/runtime-catalog-routes.d.ts +37 -0
- package/src/server/api/runtime-catalog-routes.js +133 -0
- package/src/server/api/runtime-execution-routes.d.ts +16 -0
- package/src/server/api/runtime-execution-routes.js +198 -0
- package/src/server/api/saas-oauth-routes.d.ts +9 -0
- package/src/server/api/saas-oauth-routes.js +27 -0
- package/src/server/api/saas-project-routes.d.ts +7 -0
- package/src/server/api/saas-project-routes.js +16 -0
- package/src/server/api/transit-file-routes.d.ts +9 -0
- package/src/server/api/transit-file-routes.js +49 -0
- package/src/server/api/trigger-routes.d.ts +15 -0
- package/src/server/api/trigger-routes.js +48 -0
- package/src/server/connect-app.d.ts +1 -0
- package/src/server/connect-app.js +3 -1
- package/src/server/connect-server.d.ts +3 -54
- package/src/server/connect-server.js +95 -1148
- package/src/providers/fastmoss_mcp/official-tools.json +0 -2922
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { optionalInteger, optionalRecord, optionalScalarString, optionalString, optionalStringArray, rawStringOrNull, } from "../../core/cast.js";
|
|
2
|
+
import { encodePathSegment } from "../../core/request.js";
|
|
3
|
+
import { parseProviderJsonBodyText, providerInputError, providerResponseError, providerUserAgent, ProviderRequestError, readProviderTextBody, requiredResponseRecord, runProviderRequest, setSearchParams, } from "../provider-runtime.js";
|
|
4
|
+
export const twittrapiApiBaseUrl = "https://api.twittrapi.com";
|
|
5
|
+
// The balance endpoint is free and identifies the key's account.
|
|
6
|
+
const twittrapiValidationPath = "/balance";
|
|
7
|
+
export const twittrapiActionHandlers = {
|
|
8
|
+
async search_tweets(input, context) {
|
|
9
|
+
const payload = await getTwittrapiJson({
|
|
10
|
+
path: "/search",
|
|
11
|
+
query: {
|
|
12
|
+
searchItem: optionalString(input.query),
|
|
13
|
+
category: optionalString(input.category),
|
|
14
|
+
...pageQuery(input),
|
|
15
|
+
},
|
|
16
|
+
}, context);
|
|
17
|
+
return pageOutput(payload, "tweets");
|
|
18
|
+
},
|
|
19
|
+
async search_users(input, context) {
|
|
20
|
+
const payload = await getTwittrapiJson({
|
|
21
|
+
path: "/search",
|
|
22
|
+
query: { searchItem: optionalString(input.query), category: "People", ...pageQuery(input) },
|
|
23
|
+
}, context);
|
|
24
|
+
return pageOutput(payload, "users");
|
|
25
|
+
},
|
|
26
|
+
async get_tweet(input, context) {
|
|
27
|
+
const payload = await getTwittrapiJson({ path: `/simpletweet/${encodePathSegment(input.tweetId)}` }, context);
|
|
28
|
+
const tweet = readData(payload);
|
|
29
|
+
return { tweet: tweet === null ? null : requiredResponseRecord(tweet, "TwittrAPI tweet") };
|
|
30
|
+
},
|
|
31
|
+
async get_tweet_conversation(input, context) {
|
|
32
|
+
const payload = await getTwittrapiJson({
|
|
33
|
+
path: `/tweet/${encodePathSegment(input.tweetId)}`,
|
|
34
|
+
query: { rankingMode: optionalString(input.rankingMode), cursor: optionalString(input.cursor) },
|
|
35
|
+
}, context);
|
|
36
|
+
return pageOutput(payload, "tweets");
|
|
37
|
+
},
|
|
38
|
+
async get_tweet_quotes(input, context) {
|
|
39
|
+
const payload = await getTwittrapiJson({ path: `/tweet/${encodePathSegment(input.tweetId)}/quotes`, query: pageQuery(input) }, context);
|
|
40
|
+
return pageOutput(payload, "tweets");
|
|
41
|
+
},
|
|
42
|
+
async get_tweet_retweeters(input, context) {
|
|
43
|
+
const payload = await getTwittrapiJson({ path: `/tweet/${encodePathSegment(input.tweetId)}/retweets`, query: pageQuery(input) }, context);
|
|
44
|
+
return pageOutput(payload, "users");
|
|
45
|
+
},
|
|
46
|
+
async get_user(input, context) {
|
|
47
|
+
const userId = optionalString(input.userId);
|
|
48
|
+
const username = optionalString(input.username);
|
|
49
|
+
if (!userId && !username) {
|
|
50
|
+
throw providerInputError("userId or username is required.");
|
|
51
|
+
}
|
|
52
|
+
const path = userId
|
|
53
|
+
? `/user/${encodePathSegment(userId)}`
|
|
54
|
+
: `/user/by/username/${encodePathSegment(stripHandlePrefix(username))}`;
|
|
55
|
+
const payload = await getTwittrapiJson({ path }, context);
|
|
56
|
+
const user = readData(payload);
|
|
57
|
+
return { user: user === null ? null : requiredResponseRecord(user, "TwittrAPI user") };
|
|
58
|
+
},
|
|
59
|
+
async get_users_by_ids(input, context) {
|
|
60
|
+
const payload = await getTwittrapiJson({ path: "/user/users/by/ids", query: { ids: optionalStringArray(input.userIds)?.join(",") } }, context);
|
|
61
|
+
return { users: readTwittrapiPage(payload).items };
|
|
62
|
+
},
|
|
63
|
+
async get_user_tweets(input, context) {
|
|
64
|
+
return pageOutput(await getUserCollection(input, "tweets", context), "tweets");
|
|
65
|
+
},
|
|
66
|
+
async get_user_tweets_and_replies(input, context) {
|
|
67
|
+
return pageOutput(await getUserCollection(input, "tweetsAndReplies", context), "tweets");
|
|
68
|
+
},
|
|
69
|
+
async get_user_followers(input, context) {
|
|
70
|
+
return pageOutput(await getUserCollection(input, "followers", context), "users");
|
|
71
|
+
},
|
|
72
|
+
async get_user_following(input, context) {
|
|
73
|
+
return pageOutput(await getUserCollection(input, "followings", context), "users");
|
|
74
|
+
},
|
|
75
|
+
async get_list_tweets(input, context) {
|
|
76
|
+
const payload = await getTwittrapiJson({ path: "/lists/tweets", query: { listId: optionalString(input.listId), ...pageQuery(input) } }, context);
|
|
77
|
+
return pageOutput(payload, "tweets");
|
|
78
|
+
},
|
|
79
|
+
async get_community_tweets(input, context) {
|
|
80
|
+
const payload = await getTwittrapiJson({ path: `/communities/${encodePathSegment(input.communityId)}/tweets`, query: pageQuery(input) }, context);
|
|
81
|
+
return pageOutput(payload, "tweets");
|
|
82
|
+
},
|
|
83
|
+
async get_trends(input, context) {
|
|
84
|
+
const woeid = optionalString(input.woeid) ?? "1";
|
|
85
|
+
const payload = await getTwittrapiJson({ path: `/trends/${encodePathSegment(woeid)}` }, context);
|
|
86
|
+
return { trends: readTwittrapiPage(payload).items };
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Validate a TwittrAPI key against the free balance endpoint and report the
|
|
91
|
+
* account it belongs to.
|
|
92
|
+
*/
|
|
93
|
+
export async function validateTwittrapiCredential(apiKey, fetcher, signal) {
|
|
94
|
+
const payload = await getTwittrapiJson({ path: twittrapiValidationPath, simple: false }, { apiKey, fetcher, signal }, "validate");
|
|
95
|
+
const accountId = optionalScalarString(optionalRecord(payload)?.user_id);
|
|
96
|
+
return {
|
|
97
|
+
profile: {
|
|
98
|
+
accountId: accountId ?? "api_key",
|
|
99
|
+
displayName: "TwittrAPI API Key",
|
|
100
|
+
},
|
|
101
|
+
grantedScopes: [],
|
|
102
|
+
metadata: {
|
|
103
|
+
apiBaseUrl: twittrapiApiBaseUrl,
|
|
104
|
+
validationEndpoint: twittrapiValidationPath,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// Profile collections take a numeric user ID in the path. With only a handle,
|
|
109
|
+
// the API expects -1 there and the handle in the username query parameter.
|
|
110
|
+
async function getUserCollection(input, collection, context) {
|
|
111
|
+
const userId = optionalString(input.userId);
|
|
112
|
+
const username = optionalString(input.username);
|
|
113
|
+
if (!userId && !username) {
|
|
114
|
+
throw providerInputError("userId or username is required.");
|
|
115
|
+
}
|
|
116
|
+
return getTwittrapiJson({
|
|
117
|
+
path: `/user/${encodePathSegment(userId ?? "-1")}/${collection}`,
|
|
118
|
+
query: { username: userId ? undefined : stripHandlePrefix(username), ...pageQuery(input) },
|
|
119
|
+
}, context);
|
|
120
|
+
}
|
|
121
|
+
async function getTwittrapiJson(request, context, phase = "execute") {
|
|
122
|
+
const url = new URL(request.path, twittrapiApiBaseUrl);
|
|
123
|
+
setSearchParams(url, { ...request.query, format: request.simple === false ? undefined : "simple" });
|
|
124
|
+
return runProviderRequest({ signal: context.signal, label: "TwittrAPI" }, async (signal) => {
|
|
125
|
+
const response = await context.fetcher(url, {
|
|
126
|
+
method: "GET",
|
|
127
|
+
headers: {
|
|
128
|
+
accept: "application/json",
|
|
129
|
+
"user-agent": providerUserAgent,
|
|
130
|
+
"x-api-key": context.apiKey,
|
|
131
|
+
},
|
|
132
|
+
signal,
|
|
133
|
+
});
|
|
134
|
+
const text = await readProviderTextBody(response, "TwittrAPI response", undefined, signal);
|
|
135
|
+
if (!response.ok) {
|
|
136
|
+
throw createTwittrapiError(response.status, parseErrorBody(text), phase);
|
|
137
|
+
}
|
|
138
|
+
return parseProviderJsonBodyText(text, {
|
|
139
|
+
emptyBody: null,
|
|
140
|
+
invalidJsonMessage: "TwittrAPI returned a response that is not valid JSON",
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function parseErrorBody(text) {
|
|
145
|
+
return parseProviderJsonBodyText(text, {
|
|
146
|
+
emptyBody: null,
|
|
147
|
+
invalidJsonMessage: "TwittrAPI returned an error that is not valid JSON",
|
|
148
|
+
invalidJsonFallback: (raw) => raw.trim().slice(0, 500),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
function createTwittrapiError(status, payload, phase) {
|
|
152
|
+
const message = optionalString(optionalRecord(payload)?.error) ??
|
|
153
|
+
(typeof payload === "string" ? optionalString(payload) : undefined) ??
|
|
154
|
+
`TwittrAPI request failed with status ${status}`;
|
|
155
|
+
// An invalid, unknown, or deactivated key should surface as a field error on
|
|
156
|
+
// the connect form rather than as a reconnect prompt.
|
|
157
|
+
if (phase === "validate" && (status === 401 || status === 404)) {
|
|
158
|
+
return new ProviderRequestError(400, message, payload);
|
|
159
|
+
}
|
|
160
|
+
if (status === 402) {
|
|
161
|
+
return new ProviderRequestError(402, message, payload, "insufficient_credit");
|
|
162
|
+
}
|
|
163
|
+
return new ProviderRequestError(status || 500, message, payload, status === 429 ? "rate_limited" : "provider_error");
|
|
164
|
+
}
|
|
165
|
+
function readData(payload) {
|
|
166
|
+
const record = requiredResponseRecord(payload, "TwittrAPI response");
|
|
167
|
+
if (!("data" in record)) {
|
|
168
|
+
throw providerResponseError("TwittrAPI response is missing data.");
|
|
169
|
+
}
|
|
170
|
+
return record.data;
|
|
171
|
+
}
|
|
172
|
+
function readTwittrapiPage(payload) {
|
|
173
|
+
const record = requiredResponseRecord(payload, "TwittrAPI response");
|
|
174
|
+
if (!Array.isArray(record.data)) {
|
|
175
|
+
throw providerResponseError("TwittrAPI response data must be an array.");
|
|
176
|
+
}
|
|
177
|
+
const nextCursor = rawStringOrNull(record.nextCursor);
|
|
178
|
+
return {
|
|
179
|
+
nextCursor,
|
|
180
|
+
previousCursor: rawStringOrNull(record.previousCursor),
|
|
181
|
+
hasNextPage: typeof record.hasNextPage === "boolean" ? record.hasNextPage : nextCursor !== null,
|
|
182
|
+
items: record.data.map((item) => requiredResponseRecord(item, "TwittrAPI response item")),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function pageOutput(payload, itemField) {
|
|
186
|
+
const page = readTwittrapiPage(payload);
|
|
187
|
+
return {
|
|
188
|
+
[itemField]: page.items,
|
|
189
|
+
nextCursor: page.nextCursor,
|
|
190
|
+
previousCursor: page.previousCursor,
|
|
191
|
+
hasNextPage: page.hasNextPage,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function pageQuery(input) {
|
|
195
|
+
const count = optionalInteger(input.count);
|
|
196
|
+
return {
|
|
197
|
+
count: count === undefined ? undefined : String(count),
|
|
198
|
+
cursor: optionalString(input.cursor),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function stripHandlePrefix(username) {
|
|
202
|
+
return username.startsWith("@") ? username.slice(1) : username;
|
|
203
|
+
}
|
|
@@ -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,40 @@
|
|
|
1
|
+
import { defineProviderExecutors, defineProviderProxy, requireApiKeyCredential } from "../provider-runtime.js";
|
|
2
|
+
import { readUrlhausError } from "./runtime.js";
|
|
3
|
+
import { urlhausActionHandlers, urlhausApiBaseUrl, urlhausValidationPath, validateUrlhausAuthKey } from "./runtime.js";
|
|
4
|
+
const service = "urlhaus";
|
|
5
|
+
export const executors = defineProviderExecutors({
|
|
6
|
+
service,
|
|
7
|
+
handlers: urlhausActionHandlers,
|
|
8
|
+
skipDnsValidation: true,
|
|
9
|
+
async createContext(context, fetcher) {
|
|
10
|
+
const credential = await requireApiKeyCredential(context, service);
|
|
11
|
+
return {
|
|
12
|
+
apiKey: credential.apiKey,
|
|
13
|
+
fetcher,
|
|
14
|
+
signal: context.signal,
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
export const proxy = defineProviderProxy({
|
|
19
|
+
readError: readUrlhausError,
|
|
20
|
+
service,
|
|
21
|
+
baseUrl: urlhausApiBaseUrl,
|
|
22
|
+
auth: { type: "api_key_header", name: "Auth-Key" },
|
|
23
|
+
skipDnsValidation: true,
|
|
24
|
+
});
|
|
25
|
+
export const credentialValidators = {
|
|
26
|
+
async apiKey(input, { fetcher, signal }) {
|
|
27
|
+
await validateUrlhausAuthKey(input.apiKey, fetcher, signal);
|
|
28
|
+
return {
|
|
29
|
+
profile: {
|
|
30
|
+
accountId: "urlhaus-auth-key",
|
|
31
|
+
displayName: "URLhaus Auth-Key",
|
|
32
|
+
},
|
|
33
|
+
grantedScopes: [],
|
|
34
|
+
metadata: {
|
|
35
|
+
apiBaseUrl: urlhausApiBaseUrl,
|
|
36
|
+
validationEndpoint: urlhausValidationPath,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ProviderActionHandlers, ProviderFetch } from "../provider-runtime.ts";
|
|
2
|
+
import { ProviderRequestError } from "../provider-runtime.ts";
|
|
3
|
+
export declare const urlhausApiBaseUrl = "https://urlhaus-api.abuse.ch";
|
|
4
|
+
export declare const urlhausValidationPath = "/v1/urls/recent/limit/1/";
|
|
5
|
+
export interface UrlhausRuntimeContext {
|
|
6
|
+
apiKey: string;
|
|
7
|
+
fetcher: ProviderFetch;
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
}
|
|
10
|
+
type UrlhausActionHandler = (input: Record<string, unknown>, context: UrlhausRuntimeContext) => Promise<unknown>;
|
|
11
|
+
export declare const urlhausActionHandlers: ProviderActionHandlers<"urlhaus", UrlhausActionHandler>;
|
|
12
|
+
/** Lightweight credential check: lists one recent URL; HTTP failures retain their provider error semantics. */
|
|
13
|
+
export declare function validateUrlhausAuthKey(apiKey: string, fetcher: ProviderFetch, signal?: AbortSignal): Promise<void>;
|
|
14
|
+
export declare function readUrlhausError(response: Response): Promise<ProviderRequestError>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { optionalInteger, optionalObjectArray, optionalRecord, optionalString, optionalStringArray, } from "../../core/cast.js";
|
|
2
|
+
import { parseProviderJsonBodyText, providerInputError, ProviderRequestError, providerUserAgent, readProviderErrorTextBody, readProviderTextBody, requiredInputString, runProviderRequest, withRetryAfterSeconds, } from "../provider-runtime.js";
|
|
3
|
+
export const urlhausApiBaseUrl = "https://urlhaus-api.abuse.ch";
|
|
4
|
+
export const urlhausValidationPath = "/v1/urls/recent/limit/1/";
|
|
5
|
+
export const urlhausActionHandlers = {
|
|
6
|
+
async lookup_url(input, context) {
|
|
7
|
+
const url = lookupUrlParam(input.url);
|
|
8
|
+
const payload = await requestUrlhaus({ context, url });
|
|
9
|
+
const record = optionalRecord(payload);
|
|
10
|
+
const queryStatus = optionalString(record?.query_status) ?? "";
|
|
11
|
+
if (queryStatus === "no_results") {
|
|
12
|
+
return { found: false, query_status: queryStatus, entry: undefined };
|
|
13
|
+
}
|
|
14
|
+
if (queryStatus === "invalid_url") {
|
|
15
|
+
throw providerInputError("URLhaus rejected the url as invalid.");
|
|
16
|
+
}
|
|
17
|
+
if (queryStatus !== "ok" || !record) {
|
|
18
|
+
throw new ProviderRequestError(502, `URLhaus returned an unexpected query_status: ${queryStatus || "missing"}`);
|
|
19
|
+
}
|
|
20
|
+
return { found: true, query_status: queryStatus, entry: normalizeUrlEntry(record) };
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* The queried value travels to URLhaus as POST data and is never fetched, so
|
|
25
|
+
* only the scheme and general shape are validated here; URLhaus itself
|
|
26
|
+
* reports `invalid_url` for anything it cannot parse.
|
|
27
|
+
*/
|
|
28
|
+
function lookupUrlParam(value) {
|
|
29
|
+
const url = requiredInputString(value, "url").trim();
|
|
30
|
+
let parsed;
|
|
31
|
+
try {
|
|
32
|
+
parsed = new URL(url);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
throw providerInputError("url must be a valid absolute URL, for example https://example.com/payload.exe.");
|
|
36
|
+
}
|
|
37
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
38
|
+
throw providerInputError("url must use the http or https scheme.");
|
|
39
|
+
}
|
|
40
|
+
return url;
|
|
41
|
+
}
|
|
42
|
+
async function requestUrlhaus(request) {
|
|
43
|
+
const endpoint = new URL("/v1/url/", urlhausApiBaseUrl);
|
|
44
|
+
return runProviderRequest({ label: "URLhaus", signal: request.context.signal }, async (signal) => {
|
|
45
|
+
const response = await request.context.fetcher(endpoint, {
|
|
46
|
+
method: "POST",
|
|
47
|
+
headers: {
|
|
48
|
+
"Auth-Key": request.context.apiKey,
|
|
49
|
+
accept: "application/json",
|
|
50
|
+
// URLhaus expects form-encoded POST data (see urlhaus-api.abuse.ch docs),
|
|
51
|
+
// not JSON: a JSON body yields HTTP 200 with an empty response.
|
|
52
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
53
|
+
"user-agent": providerUserAgent,
|
|
54
|
+
},
|
|
55
|
+
body: new URLSearchParams({ url: request.url }).toString(),
|
|
56
|
+
signal,
|
|
57
|
+
});
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
throw await readUrlhausError(response);
|
|
60
|
+
}
|
|
61
|
+
return parseProviderJsonBodyText(await readProviderTextBody(response, "URLhaus response"), {
|
|
62
|
+
emptyBody: null,
|
|
63
|
+
invalidJsonMessage: "URLhaus returned malformed JSON",
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/** Lightweight credential check: lists one recent URL; HTTP failures retain their provider error semantics. */
|
|
68
|
+
export async function validateUrlhausAuthKey(apiKey, fetcher, signal) {
|
|
69
|
+
await runProviderRequest({ label: "URLhaus", signal }, async (requestSignal) => {
|
|
70
|
+
const response = await fetcher(new URL(urlhausValidationPath, urlhausApiBaseUrl), {
|
|
71
|
+
headers: {
|
|
72
|
+
"Auth-Key": apiKey,
|
|
73
|
+
accept: "application/json",
|
|
74
|
+
"user-agent": providerUserAgent,
|
|
75
|
+
},
|
|
76
|
+
signal: requestSignal,
|
|
77
|
+
});
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
throw await readUrlhausError(response);
|
|
80
|
+
}
|
|
81
|
+
const payload = optionalRecord(parseProviderJsonBodyText(await readProviderTextBody(response, "URLhaus validation response"), {
|
|
82
|
+
emptyBody: null,
|
|
83
|
+
invalidJsonMessage: "URLhaus returned malformed JSON",
|
|
84
|
+
}));
|
|
85
|
+
if (optionalString(payload?.query_status) !== "ok") {
|
|
86
|
+
throw new ProviderRequestError(502, "URLhaus validation returned an unexpected response");
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
function normalizeUrlEntry(record) {
|
|
91
|
+
const blacklists = optionalRecord(record.blacklists) ?? {};
|
|
92
|
+
const idValue = record.id;
|
|
93
|
+
return {
|
|
94
|
+
...record,
|
|
95
|
+
id: typeof idValue === "string" ? idValue : typeof idValue === "number" ? String(idValue) : "",
|
|
96
|
+
urlhaus_reference: optionalString(record.urlhaus_reference) ?? "",
|
|
97
|
+
url: optionalString(record.url) ?? "",
|
|
98
|
+
url_status: optionalString(record.url_status) ?? "",
|
|
99
|
+
host: optionalString(record.host) ?? "",
|
|
100
|
+
date_added: optionalString(record.date_added) ?? "",
|
|
101
|
+
last_online: optionalString(record.last_online) ?? null,
|
|
102
|
+
threat: optionalString(record.threat) ?? "",
|
|
103
|
+
blacklists: {
|
|
104
|
+
...blacklists,
|
|
105
|
+
surbl: optionalString(blacklists.surbl) ?? "",
|
|
106
|
+
spamhaus_dbl: optionalString(blacklists.spamhaus_dbl) ?? "",
|
|
107
|
+
},
|
|
108
|
+
reporter: optionalString(record.reporter) ?? "",
|
|
109
|
+
larted: optionalString(record.larted) ?? "",
|
|
110
|
+
takedown_time_seconds: optionalInteger(record.takedown_time_seconds) ?? null,
|
|
111
|
+
tags: optionalStringArray(record.tags) ?? [],
|
|
112
|
+
payloads: (optionalObjectArray(record.payloads) ?? []).map(normalizePayload),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function normalizePayload(item) {
|
|
116
|
+
return {
|
|
117
|
+
...item,
|
|
118
|
+
firstseen: optionalString(item.firstseen) ?? "",
|
|
119
|
+
filename: optionalString(item.filename) ?? null,
|
|
120
|
+
file_type: optionalString(item.file_type) ?? "",
|
|
121
|
+
response_size: stringifySize(item.response_size),
|
|
122
|
+
response_md5: optionalString(item.response_md5) ?? "",
|
|
123
|
+
response_sha256: optionalString(item.response_sha256) ?? "",
|
|
124
|
+
urlhaus_download: optionalString(item.urlhaus_download) ?? "",
|
|
125
|
+
signature: optionalString(item.signature) ?? null,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/** URLhaus reports the payload size inconsistently as a string or a number. */
|
|
129
|
+
function stringifySize(value) {
|
|
130
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
131
|
+
return String(Math.trunc(value));
|
|
132
|
+
}
|
|
133
|
+
return optionalString(value) ?? "";
|
|
134
|
+
}
|
|
135
|
+
// HTTP status alone cannot distinguish an invalid key from access or subscription restrictions.
|
|
136
|
+
export async function readUrlhausError(response) {
|
|
137
|
+
const text = (await readProviderErrorTextBody(response, "URLhaus error response")).trim();
|
|
138
|
+
const message = text.slice(0, 200) || `URLhaus request failed with HTTP ${response.status}`;
|
|
139
|
+
const status = response.status;
|
|
140
|
+
const code = status === 429 ? "rate_limited" : "provider_error";
|
|
141
|
+
return new ProviderRequestError(status, message, withRetryAfterSeconds(response, {}), code);
|
|
142
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Buffer } from "node:buffer";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { compactObject, optionalBoolean, optionalInteger, optionalRecord, optionalString } from "../../core/cast.js";
|
|
4
|
-
import { createProviderTimeout, mapProviderActionSources, ProviderRequestError, providerUserAgent, toProviderExecutionError, } from "../provider-runtime.js";
|
|
4
|
+
import { createProviderTimeout, mapProviderActionSources, ProviderRequestError, providerUserAgent, toProviderExecutionError, providerInputError, } from "../provider-runtime.js";
|
|
5
5
|
export const wangdianApiBaseUrl = "https://api.wangdian.cn/openapi2";
|
|
6
6
|
const maximumWindowMs = 30 * 24 * 60 * 60 * 1_000;
|
|
7
7
|
const maximumOrderWindowMs = 60 * 60 * 1_000;
|
|
@@ -93,7 +93,7 @@ export function readWangdianProxyParameters(body) {
|
|
|
93
93
|
return Object.fromEntries(new URLSearchParams(body));
|
|
94
94
|
const value = optionalRecord(body);
|
|
95
95
|
if (!value) {
|
|
96
|
-
throw
|
|
96
|
+
throw providerInputError("Wangdian proxy body must be an object or form-encoded string");
|
|
97
97
|
}
|
|
98
98
|
return value;
|
|
99
99
|
}
|
|
@@ -103,7 +103,7 @@ export function toWangdianExecutionError(error) {
|
|
|
103
103
|
async function executeWangdianAction(actionName, input, context) {
|
|
104
104
|
const config = actionConfigByName[actionName];
|
|
105
105
|
if (!config)
|
|
106
|
-
throw
|
|
106
|
+
throw providerInputError(`Unsupported Wangdian action: ${actionName}`);
|
|
107
107
|
validateActionInput(actionName, input);
|
|
108
108
|
const payload = await requestWangdian({
|
|
109
109
|
endpoint: config.endpoint,
|
|
@@ -114,7 +114,7 @@ async function executeWangdianAction(actionName, input, context) {
|
|
|
114
114
|
const responseRecords = payload[config.responseField];
|
|
115
115
|
const records = responseRecords === undefined && config.optionalResponseList ? [] : responseRecords;
|
|
116
116
|
if (!Array.isArray(records)) {
|
|
117
|
-
throw
|
|
117
|
+
throw new ProviderRequestError(502, `Wangdian returned an invalid ${config.responseField} response`, undefined, "provider_error");
|
|
118
118
|
}
|
|
119
119
|
return {
|
|
120
120
|
[config.outputField]: records,
|
|
@@ -175,7 +175,7 @@ function validateOptionalDateTimes(input) {
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
function invalidInput(message) {
|
|
178
|
-
throw
|
|
178
|
+
throw new ProviderRequestError(400, message, undefined, "invalid_input");
|
|
179
179
|
}
|
|
180
180
|
function hasValue(value, fields) {
|
|
181
181
|
return fields.some((field) => Boolean(optionalString(value[field])));
|
|
@@ -197,7 +197,7 @@ function parseChinaDateTime(value) {
|
|
|
197
197
|
function requireCredentialValue(value, label) {
|
|
198
198
|
const normalized = optionalString(value);
|
|
199
199
|
if (!normalized)
|
|
200
|
-
throw
|
|
200
|
+
throw providerInputError(`${label} is required`);
|
|
201
201
|
return normalized;
|
|
202
202
|
}
|
|
203
203
|
function buildActionParameters(actionName, input) {
|
|
@@ -291,7 +291,7 @@ function buildActionParameters(actionName, input) {
|
|
|
291
291
|
...page,
|
|
292
292
|
});
|
|
293
293
|
default:
|
|
294
|
-
throw
|
|
294
|
+
throw providerInputError(`Unsupported Wangdian action: ${actionName}`);
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
function booleanFlag(value) {
|
|
@@ -338,7 +338,7 @@ async function requestWangdian(input) {
|
|
|
338
338
|
const root = optionalRecord(payload);
|
|
339
339
|
const code = parseOptionalInteger(root?.code);
|
|
340
340
|
if (!root || code === undefined) {
|
|
341
|
-
throw
|
|
341
|
+
throw new ProviderRequestError(502, "Wangdian returned an invalid response", undefined, "provider_error");
|
|
342
342
|
}
|
|
343
343
|
if (code !== 0)
|
|
344
344
|
throw createWangdianError(200, root, input.phase);
|
|
@@ -348,9 +348,9 @@ async function requestWangdian(input) {
|
|
|
348
348
|
if (error instanceof ProviderRequestError)
|
|
349
349
|
throw error;
|
|
350
350
|
if (timeout.didTimeout() || (error instanceof Error && error.name === "AbortError")) {
|
|
351
|
-
throw
|
|
351
|
+
throw new ProviderRequestError(504, "Wangdian request timed out", undefined, "provider_error");
|
|
352
352
|
}
|
|
353
|
-
throw
|
|
353
|
+
throw new ProviderRequestError(502, error instanceof Error ? `Wangdian request failed: ${error.message}` : "Wangdian request failed", undefined, "provider_error");
|
|
354
354
|
}
|
|
355
355
|
finally {
|
|
356
356
|
timeout.cleanup();
|
|
@@ -364,7 +364,7 @@ async function readWangdianPayload(response) {
|
|
|
364
364
|
return JSON.parse(text);
|
|
365
365
|
}
|
|
366
366
|
catch {
|
|
367
|
-
throw
|
|
367
|
+
throw new ProviderRequestError(502, "Wangdian returned invalid JSON", undefined, "provider_error");
|
|
368
368
|
}
|
|
369
369
|
}
|
|
370
370
|
function createWangdianError(status, payload, phase) {
|
|
@@ -373,9 +373,9 @@ function createWangdianError(status, payload, phase) {
|
|
|
373
373
|
const message = optionalString(root?.message) ?? `Wangdian request failed with status ${status}`;
|
|
374
374
|
const lowerMessage = message.toLowerCase();
|
|
375
375
|
if (status === 429)
|
|
376
|
-
return
|
|
376
|
+
return new ProviderRequestError(429, message, payload, "rate_limited");
|
|
377
377
|
if (message.includes("权限不足") || message.includes("无仓库访问权限")) {
|
|
378
|
-
return
|
|
378
|
+
return new ProviderRequestError(403, message, payload, "authorization_failed");
|
|
379
379
|
}
|
|
380
380
|
if (status === 401 ||
|
|
381
381
|
status === 403 ||
|
|
@@ -390,15 +390,12 @@ function createWangdianError(status, payload, phase) {
|
|
|
390
390
|
lowerMessage.includes("sign error") ||
|
|
391
391
|
lowerMessage.includes("invalid sign") ||
|
|
392
392
|
lowerMessage.includes("sign is")) {
|
|
393
|
-
return
|
|
393
|
+
return new ProviderRequestError(phase === "validate" ? 400 : 401, message, payload, phase === "validate" ? "invalid_input" : "authorization_failed");
|
|
394
394
|
}
|
|
395
395
|
if (status === 400 || status === 422 || code === 1 || code === 100 || code === 2104) {
|
|
396
|
-
return
|
|
396
|
+
return new ProviderRequestError(400, message, payload, "invalid_input");
|
|
397
397
|
}
|
|
398
|
-
return
|
|
399
|
-
}
|
|
400
|
-
function wangdianError(code, message, status, details) {
|
|
401
|
-
return new ProviderRequestError(status, message, details, code);
|
|
398
|
+
return new ProviderRequestError(502, message, payload, "provider_error");
|
|
402
399
|
}
|
|
403
400
|
function parseOptionalInteger(value) {
|
|
404
401
|
if (value === undefined || value === null || value === "")
|