@tool-bridge/server 0.16.0 → 0.17.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/dist/{airtable-S3T4TAN7.js → airtable-NOSOMOVB.js} +106 -114
- package/dist/{alt_text_generator_ai-4DIRIDKL.js → alt_text_generator_ai-BHIJ4LW5.js} +25 -16
- package/dist/{amap-LGVGNPML.js → amap-QRLP4TWZ.js} +114 -123
- package/dist/{anthropic-27RFZO35.js → anthropic-IEOI36EV.js} +34 -56
- package/dist/{apify-6WLYAIAS.js → apify-3CCYTQVK.js} +31 -49
- package/dist/{brave_search-K2SVJ66F.js → brave_search-PZNYDQG7.js} +52 -77
- package/dist/chunk-JXHMDBAY.js +45 -0
- package/dist/chunk-LMLX3DJF.js +50 -0
- package/dist/{chunk-YB2FLNWI.js → chunk-RVWZN3CI.js} +2103 -1775
- package/dist/{chunk-BB6ZLMTU.js → chunk-TLNUIPFZ.js} +492 -300
- package/dist/chunk-U5UHT7CX.js +977 -0
- package/dist/chunk-U67V476Y.js +35 -0
- package/dist/chunk-WW2IMPQK.js +283 -0
- package/dist/{chunk-VK3V2WTY.js → chunk-YASUMV2K.js} +4 -6
- package/dist/{circleci-WV3ITU7Q.js → circleci-VSJ4O5FC.js} +36 -55
- package/dist/{clerk-NFQEFKS4.js → clerk-CC2JZBZI.js} +60 -80
- package/dist/{cloudflare_dns-2RK5ASBJ.js → cloudflare_dns-PJEBSEYQ.js} +90 -113
- package/dist/{cohere-5KEW7LWT.js → cohere-KBACYSPF.js} +33 -49
- package/dist/{confluence-SZE63S46.js → confluence-2PX3O7G5.js} +79 -115
- package/dist/{convertapi-QPG2JC5K.js → convertapi-BVOTD2PJ.js} +13 -16
- package/dist/{currencyapi-UO2APQRY.js → currencyapi-6ZQ2VNQ7.js} +30 -53
- package/dist/{deepseek-LJELIMM3.js → deepseek-MB3WVVTB.js} +30 -38
- package/dist/{docker_hub-2MFXSBOF.js → docker_hub-7CLQL2IJ.js} +141 -157
- package/dist/{dropbox-GQYNTTVA.js → dropbox-VFYDVUNK.js} +134 -141
- package/dist/{dub-KI2LHXST.js → dub-QN3EETJY.js} +61 -93
- package/dist/{e2b-WO6ISY3C.js → e2b-NKC3Y776.js} +39 -69
- package/dist/{exa-IZ7B3BPT.js → exa-KKZ6F25K.js} +49 -77
- package/dist/{fal_ai-LTMF36GJ.js → fal_ai-25LYJD2O.js} +37 -44
- package/dist/{feishu-WM7SLSFD.js → feishu-NRT55B3Q.js} +4 -6
- package/dist/{feishu_custom_bot-66W3MXH2.js → feishu_custom_bot-3W3XXUG4.js} +4 -5
- package/dist/{figma-2Z274VQZ.js → figma-4FLP35TC.js} +56 -81
- package/dist/{firehydrant-IFI4R65V.js → firehydrant-BLXPLZ3X.js} +40 -53
- package/dist/{fixer-BCCZEB3D.js → fixer-4OR62TGE.js} +31 -43
- package/dist/{fly-755FXYB5.js → fly-MYCKOZZK.js} +50 -66
- package/dist/{front-4FZKKXXK.js → front-3DFYVMF3.js} +43 -66
- package/dist/{geocodio-WYKDJ3DP.js → geocodio-CXMD6VKA.js} +37 -63
- package/dist/{ghost-5BNQTCOH.js → ghost-4UUE737W.js} +51 -57
- package/dist/{github-ULELF5VX.js → github-WFS2ON2N.js} +48 -41
- package/dist/{gmail-G34WT64J.js → gmail-KW7FXA7A.js} +26 -36
- package/dist/{googlecalendar-BQU255SC.js → googlecalendar-AMH5JQMC.js} +57 -78
- package/dist/{googledocs-HPCNQXYJ.js → googledocs-R5VA6CKD.js} +14 -22
- package/dist/{grafana-VOV24FIC.js → grafana-IT6DWIVB.js} +95 -122
- package/dist/{graphhopper-D5RXW6AP.js → graphhopper-TYFDJZWC.js} +32 -46
- package/dist/index.d.ts +57 -50
- package/dist/index.js +4 -3
- package/dist/{ip2proxy-DAYO7EKZ.js → ip2proxy-GJ4HXVXO.js} +35 -42
- package/dist/{ipgeolocation_io-XD4PSLII.js → ipgeolocation_io-OAGR6PRF.js} +40 -60
- package/dist/{ipqualityscore-K27QEAWK.js → ipqualityscore-BCKAMDGL.js} +30 -42
- package/dist/{jina_ai-E6UXFV2P.js → jina_ai-N3NXRVIZ.js} +32 -58
- package/dist/{jira-ZDSXGQ6W.js → jira-CHLBKWLO.js} +116 -126
- package/dist/{langsmith-TIFJRREW.js → langsmith-OIKOTPY3.js} +101 -121
- package/dist/{lemlist-DASEMJMA.js → lemlist-VAKYPKS3.js} +57 -68
- package/dist/{linear-KE6UP4SP.js → linear-Q6QTPJ5R.js} +109 -118
- package/dist/{logsnag-IMNDN4R5.js → logsnag-SQOQBTES.js} +31 -48
- package/dist/main.js +103 -102
- package/dist/{mattermost-HHHMUXQA.js → mattermost-G2KBEICM.js} +45 -62
- package/dist/{mem0-D2FGGOIY.js → mem0-D2FPLYDX.js} +72 -98
- package/dist/{memos-4OVIGFPH.js → memos-76PTWV5V.js} +68 -122
- package/dist/{metabase-33WCX5YD.js → metabase-TWSIDVBM.js} +47 -60
- package/dist/{mistral_ai-QIMZ2JYL.js → mistral_ai-TP7TQUEJ.js} +35 -40
- package/dist/{mother_duck-M6VWS2VH.js → mother_duck-UXY5THYU.js} +42 -62
- package/dist/{ngrok-Z2PKQBHH.js → ngrok-RZW2ISJK.js} +42 -58
- package/dist/{notes-SS4RPC4K.js → notes-B2I6FWK2.js} +3 -5
- package/dist/{notion-FJCNQ6I7.js → notion-QOKRUE6M.js} +83 -97
- package/dist/{open_exchange_rates-WU57WTT5.js → open_exchange_rates-ODLFWEJ7.js} +35 -39
- package/dist/{openai-JODZ4GKT.js → openai-ZPBPPPGT.js} +51 -55
- package/dist/{opengraph_io-SQRAUSV5.js → opengraph_io-EOI5UJKT.js} +61 -79
- package/dist/{openrouter-Q5XXEJZ7.js → openrouter-BUWLF3BG.js} +41 -55
- package/dist/{outline-RT2EHJ2X.js → outline-NXS3QRXO.js} +89 -104
- package/dist/{paddle-OF2V7GAC.js → paddle-T4MSKQ76.js} +34 -49
- package/dist/{perplexity-LNZEWLHG.js → perplexity-WW5N2LW7.js} +33 -50
- package/dist/{pinecone-JSJIXZYN.js → pinecone-RY5AZPQM.js} +65 -91
- package/dist/{pipedrive-D4CKVUXR.js → pipedrive-OHYQNZTU.js} +37 -59
- package/dist/{polar-M7ZYP6UR.js → polar-XZIAHXS5.js} +43 -53
- package/dist/{posthog-YV7CZOH4.js → posthog-DTPTWORY.js} +58 -77
- package/dist/{postmark-KYHLECRG.js → postmark-F4UCQKC3.js} +52 -71
- package/dist/{prerender-HCMHBKV2.js → prerender-P3Y2MLIC.js} +32 -50
- package/dist/{pubmed-WYVLCCN3.js → pubmed-RHU3GXFB.js} +28 -60
- package/dist/{railway-TWIRD5KR.js → railway-VB6SRLI6.js} +32 -39
- package/dist/{readwise-UZ467IQ7.js → readwise-DIMSKJZR.js} +62 -78
- package/dist/{render-MECUC5CC.js → render-XCCDCEEK.js} +48 -64
- package/dist/{replicate-A5MEK3SW.js → replicate-IUEOQ4JC.js} +41 -58
- package/dist/{resend-BC6EAWJQ.js → resend-N5MJZH5E.js} +27 -37
- package/dist/{rootly-ZM3QDUIS.js → rootly-25T4NBTU.js} +64 -76
- package/dist/{scrapfly-WAML42QJ.js → scrapfly-PK4XFXUA.js} +45 -51
- package/dist/{scrapingbee-DG7PET3V.js → scrapingbee-ITPBMWQU.js} +25 -33
- package/dist/{screenshot_fyi-HY6WTHIO.js → screenshot_fyi-5U6ZYPKR.js} +29 -47
- package/dist/{semantic_scholar-C5IZA7IP.js → semantic_scholar-BJGCI2MU.js} +37 -56
- package/dist/{sentry-OKBPSTDM.js → sentry-63IC263P.js} +66 -85
- package/dist/{shodan-PPC6DYU4.js → shodan-2WBIFHFN.js} +42 -53
- package/dist/{shopify-EWGUHBXO.js → shopify-XLLJRAGM.js} +32 -49
- package/dist/{stripe-6RPDPC5W.js → stripe-WLVCY3UN.js} +4 -5
- package/dist/{supabase-SK7DQ42N.js → supabase-BKNZ35ER.js} +69 -88
- package/dist/{tavily-YCG5VQMH.js → tavily-YFSDEUTL.js} +37 -62
- package/dist/{telegram-2OES5FYB.js → telegram-FC35W74G.js} +168 -177
- package/dist/{telnyx-POOSBBR4.js → telnyx-MI32XZUG.js} +30 -50
- package/dist/{todoist-M7YD6YSS.js → todoist-4ZFJKZC6.js} +77 -89
- package/dist/{trello-IS6V5W3E.js → trello-UOGFNMK4.js} +108 -122
- package/dist/{turso-RCFHUFVH.js → turso-YTSTW3ZS.js} +52 -64
- package/dist/{twilio-OS2RXFGO.js → twilio-XAJDFUQH.js} +48 -55
- package/dist/{umami-PQ2SJ2LN.js → umami-ZVIUBPAI.js} +49 -69
- package/dist/{unsplash-C6BPZO4E.js → unsplash-IU3PLDNS.js} +35 -52
- package/dist/{upstash_redis-WH6UER7H.js → upstash_redis-3EYJW7SY.js} +28 -40
- package/dist/{uptimerobot-M3YZGS6Z.js → uptimerobot-PJG2ASRU.js} +11 -12
- package/dist/{v2ex-R4JWTEHN.js → v2ex-KFQWWGFC.js} +36 -61
- package/dist/{vercel-FZVYUOQD.js → vercel-I2ZDOQRL.js} +124 -150
- package/dist/{webapi-VLM4IKVB.js → webapi-GW5QXWXE.js} +1 -1
- package/dist/{wolfram_alpha_api-2KOLO5DC.js → wolfram_alpha_api-BNXOJMB6.js} +26 -34
- package/dist/{wordpress-XRWGO6LG.js → wordpress-36D7BSMP.js} +87 -104
- package/dist/{workos-WR4NKOYL.js → workos-6X4JJRRC.js} +37 -56
- package/dist/{zhihu-BKZIB3WA.js → zhihu-CIXKCHIU.js} +35 -57
- package/package.json +5 -5
- package/dist/chunk-2O27H4Y2.js +0 -183
- package/dist/chunk-GKX72JMJ.js +0 -378
- package/dist/chunk-MLKGABMK.js +0 -9
|
@@ -1,77 +1,57 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createProviderHttpClient
|
|
3
|
+
} from "./chunk-WW2IMPQK.js";
|
|
4
|
+
import {
|
|
5
|
+
asJsonObject,
|
|
6
|
+
trimmedText
|
|
7
|
+
} from "./chunk-JXHMDBAY.js";
|
|
1
8
|
import {
|
|
2
9
|
createProviderPlugin,
|
|
3
10
|
requireApiKey,
|
|
4
11
|
upstreamError
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import
|
|
7
|
-
guardedFetch
|
|
8
|
-
} from "./chunk-2O27H4Y2.js";
|
|
9
|
-
import "./chunk-GKX72JMJ.js";
|
|
12
|
+
} from "./chunk-YASUMV2K.js";
|
|
13
|
+
import "./chunk-U5UHT7CX.js";
|
|
10
14
|
import {
|
|
11
15
|
TBError,
|
|
12
16
|
external_exports
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
17
|
+
} from "./chunk-RVWZN3CI.js";
|
|
18
|
+
import "./chunk-U67V476Y.js";
|
|
15
19
|
|
|
16
20
|
// ../plugins/src/telnyx/api.ts
|
|
17
21
|
var SERVICE = "telnyx";
|
|
18
22
|
var API_BASE = "https://api.telnyx.com/v2";
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
function text(value) {
|
|
23
|
-
if (typeof value !== "string") return void 0;
|
|
24
|
-
const trimmed = value.trim();
|
|
25
|
-
return trimmed === "" ? void 0 : trimmed;
|
|
26
|
-
}
|
|
27
|
-
function errorMessage(payload, response) {
|
|
23
|
+
var http = createProviderHttpClient({ baseUrl: `${API_BASE}/`, service: SERVICE });
|
|
24
|
+
function errorMessage(payload, status, statusText) {
|
|
28
25
|
if (typeof payload === "string" && payload.trim() !== "") return payload;
|
|
29
|
-
const record =
|
|
26
|
+
const record = asJsonObject(payload);
|
|
30
27
|
const errors = Array.isArray(record?.errors) ? record.errors : [];
|
|
31
|
-
const first = errors.map(
|
|
32
|
-
const message = first === void 0 ?
|
|
33
|
-
return message ?? (
|
|
34
|
-
}
|
|
35
|
-
async function readPayload(response) {
|
|
36
|
-
const body = await response.text().catch(() => "");
|
|
37
|
-
if (body.trim() === "") return null;
|
|
38
|
-
try {
|
|
39
|
-
return JSON.parse(body);
|
|
40
|
-
} catch {
|
|
41
|
-
throw upstreamError(response.status === 429 ? 429 : 502, "Telnyx \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94");
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
async function send(url, init) {
|
|
45
|
-
try {
|
|
46
|
-
return await guardedFetch(url.toString(), init);
|
|
47
|
-
} catch (error) {
|
|
48
|
-
if (error instanceof TypeError) {
|
|
49
|
-
throw upstreamError(502, `telnyx request failed: ${error.message}`);
|
|
50
|
-
}
|
|
51
|
-
throw error;
|
|
52
|
-
}
|
|
28
|
+
const first = errors.map(asJsonObject).find(Boolean);
|
|
29
|
+
const message = first === void 0 ? trimmedText(record?.detail) ?? trimmedText(record?.message) ?? trimmedText(record?.error) ?? trimmedText(record?.title) : trimmedText(first.detail) ?? trimmedText(first.title) ?? trimmedText(first.code);
|
|
30
|
+
return message ?? (statusText || `Telnyx \u8FD4\u56DE HTTP ${status}`);
|
|
53
31
|
}
|
|
54
32
|
async function request(ctx, path, input = {}) {
|
|
55
|
-
const url = new URL(`${API_BASE}${path}`);
|
|
56
|
-
for (const [name, value] of input.query ?? []) {
|
|
57
|
-
if (value === void 0 || value === null || value === "") continue;
|
|
58
|
-
url.searchParams.set(name, String(value));
|
|
59
|
-
}
|
|
60
33
|
const headers = {
|
|
61
34
|
accept: "application/json",
|
|
62
35
|
authorization: `Bearer ${requireApiKey(ctx, SERVICE)}`
|
|
63
36
|
};
|
|
64
|
-
|
|
65
|
-
const response = await send(url, {
|
|
37
|
+
const response = await http.request({
|
|
66
38
|
method: input.method ?? "GET",
|
|
39
|
+
path,
|
|
40
|
+
// 空串不进 query:Telnyx 会把 `filter[name]=` 读成"匹配空名字",而调用方省略一个
|
|
41
|
+
// 可选筛选时想要的是"不筛选"。
|
|
42
|
+
query: (input.query ?? []).filter(([, value]) => value !== void 0 && value !== null && value !== ""),
|
|
67
43
|
headers,
|
|
68
44
|
// JSON.stringify 自己会丢掉值为 undefined 的键,故不必复制上游的 removeUndefined;
|
|
69
45
|
// 但 null 必须留住 —— schema 允许 sendAt 显式传 null,那是要发给 Telnyx 的值。
|
|
70
|
-
...input.body === void 0 ? {} : {
|
|
46
|
+
...input.body === void 0 ? {} : { json: input.body },
|
|
47
|
+
invalidJsonMessage: "Telnyx \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94",
|
|
48
|
+
mapError: ({ bodyKind, data, status, statusText }) => bodyKind === "invalid-json" ? upstreamError(status === 429 ? 429 : 502, "Telnyx \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94") : upstreamError(status, errorMessage(bodyKind === "empty" ? null : data, status, statusText)),
|
|
49
|
+
mapTransportError: ({ message }) => upstreamError(
|
|
50
|
+
502,
|
|
51
|
+
message === void 0 ? "telnyx request failed" : `telnyx request failed: ${message}`
|
|
52
|
+
)
|
|
71
53
|
});
|
|
72
|
-
const
|
|
73
|
-
if (!response.ok) throw upstreamError(response.status, errorMessage(payload, response));
|
|
74
|
-
const record = toRecord(payload);
|
|
54
|
+
const record = asJsonObject(response.bodyKind === "empty" ? null : response.data);
|
|
75
55
|
if (record === void 0) {
|
|
76
56
|
throw upstreamError(502, "Telnyx \u7684\u6210\u529F\u54CD\u5E94\u4E0D\u662F\u4E00\u4E2A\u5BF9\u8C61");
|
|
77
57
|
}
|
|
@@ -1,118 +1,106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createProviderHttpClient
|
|
3
|
+
} from "./chunk-WW2IMPQK.js";
|
|
4
|
+
import {
|
|
5
|
+
asJsonObject,
|
|
6
|
+
compactDefined,
|
|
7
|
+
trimmedText
|
|
8
|
+
} from "./chunk-JXHMDBAY.js";
|
|
1
9
|
import {
|
|
2
10
|
createProviderPlugin,
|
|
3
11
|
requireApiKey,
|
|
4
12
|
upstreamError
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import
|
|
7
|
-
guardedFetch
|
|
8
|
-
} from "./chunk-2O27H4Y2.js";
|
|
9
|
-
import "./chunk-GKX72JMJ.js";
|
|
13
|
+
} from "./chunk-YASUMV2K.js";
|
|
14
|
+
import "./chunk-U5UHT7CX.js";
|
|
10
15
|
import {
|
|
11
16
|
TBError,
|
|
12
17
|
external_exports
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
18
|
+
} from "./chunk-RVWZN3CI.js";
|
|
19
|
+
import "./chunk-U67V476Y.js";
|
|
15
20
|
|
|
16
21
|
// ../plugins/src/todoist/api.ts
|
|
17
22
|
var SERVICE = "todoist";
|
|
18
23
|
var API_BASE = "https://api.todoist.com/api/v1";
|
|
19
24
|
var USER_PATH = "/user";
|
|
20
|
-
|
|
21
|
-
if (typeof value !== "string") return void 0;
|
|
22
|
-
const trimmed = value.trim();
|
|
23
|
-
return trimmed === "" ? void 0 : trimmed;
|
|
24
|
-
}
|
|
25
|
-
function record(value) {
|
|
26
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
27
|
-
}
|
|
28
|
-
function compact(input) {
|
|
29
|
-
return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0));
|
|
30
|
-
}
|
|
25
|
+
var http = createProviderHttpClient({ baseUrl: `${API_BASE}/`, service: SERVICE });
|
|
31
26
|
function requireText(value, field) {
|
|
32
|
-
const result =
|
|
27
|
+
const result = trimmedText(value);
|
|
33
28
|
if (result === void 0) throw new TBError("invalid_argument", `${field} is required.`);
|
|
34
29
|
return result;
|
|
35
30
|
}
|
|
36
31
|
function stringArray(value) {
|
|
37
32
|
if (!Array.isArray(value)) return void 0;
|
|
38
|
-
const items = value.map((item) =>
|
|
33
|
+
const items = value.map((item) => trimmedText(item)).filter((item) => item !== void 0);
|
|
39
34
|
return items.length > 0 ? items : void 0;
|
|
40
35
|
}
|
|
41
36
|
function requireRecord(value, label) {
|
|
42
|
-
const result =
|
|
37
|
+
const result = asJsonObject(value);
|
|
43
38
|
if (result === void 0) throw new TBError("unavailable", `${label}\u4E0D\u662F\u5BF9\u8C61`, { retryable: true });
|
|
44
39
|
return result;
|
|
45
40
|
}
|
|
46
41
|
function errorMessage(status, payload) {
|
|
47
|
-
const body =
|
|
48
|
-
const direct =
|
|
42
|
+
const body = asJsonObject(payload);
|
|
43
|
+
const direct = trimmedText(body?.error) ?? trimmedText(body?.error_description) ?? trimmedText(body?.message) ?? trimmedText(body?.detail);
|
|
49
44
|
if (direct !== void 0) return direct;
|
|
50
45
|
if (Array.isArray(body?.errors)) {
|
|
51
|
-
const first = body.errors.find((item) =>
|
|
46
|
+
const first = body.errors.find((item) => trimmedText(item) !== void 0);
|
|
52
47
|
if (first !== void 0) return first;
|
|
53
48
|
}
|
|
54
49
|
return `todoist request failed with ${status}`;
|
|
55
50
|
}
|
|
56
51
|
async function request(ctx, input) {
|
|
57
|
-
const url = new URL(input.path.replace(/^\/+/, ""), `${API_BASE}/`);
|
|
58
|
-
for (const [key, value] of Object.entries(input.query ?? {})) {
|
|
59
|
-
if (value === void 0) continue;
|
|
60
|
-
url.searchParams.set(key, Array.isArray(value) ? value.join(",") : String(value));
|
|
61
|
-
}
|
|
62
52
|
const hasBody = input.body !== void 0;
|
|
63
|
-
const
|
|
53
|
+
const query = Object.entries(input.query ?? {}).map(([key, value]) => [
|
|
54
|
+
key,
|
|
55
|
+
// 多值参数(list_tasks 的 ids)是**逗号串**,不是重复的同名参数。
|
|
56
|
+
Array.isArray(value) ? value.join(",") : value
|
|
57
|
+
]);
|
|
58
|
+
const { data } = await http.request({
|
|
59
|
+
path: input.path,
|
|
64
60
|
method: input.method ?? "GET",
|
|
61
|
+
query,
|
|
65
62
|
headers: {
|
|
66
63
|
accept: "application/json",
|
|
67
|
-
authorization: `Bearer ${requireApiKey(ctx, SERVICE)}
|
|
68
|
-
...hasBody ? { "content-type": "application/json" } : {}
|
|
64
|
+
authorization: `Bearer ${requireApiKey(ctx, SERVICE)}`
|
|
69
65
|
},
|
|
70
|
-
|
|
66
|
+
...hasBody ? { json: input.body } : {},
|
|
67
|
+
invalidJsonMessage: "Todoist \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94",
|
|
68
|
+
mapError: ({ data: data2, status }) => upstreamError(
|
|
69
|
+
status,
|
|
70
|
+
errorMessage(status, typeof data2 === "string" ? { message: data2 } : data2)
|
|
71
|
+
)
|
|
71
72
|
});
|
|
72
|
-
|
|
73
|
-
let payload = {};
|
|
74
|
-
if (raw !== "") {
|
|
75
|
-
try {
|
|
76
|
-
payload = JSON.parse(raw);
|
|
77
|
-
} catch {
|
|
78
|
-
if (response.ok) {
|
|
79
|
-
throw new TBError("unavailable", "Todoist \u8FD4\u56DE\u4E86\u975E JSON \u54CD\u5E94", { retryable: true });
|
|
80
|
-
}
|
|
81
|
-
payload = { message: raw };
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
if (!response.ok) throw upstreamError(response.status, errorMessage(response.status, payload));
|
|
85
|
-
return payload;
|
|
73
|
+
return data ?? {};
|
|
86
74
|
}
|
|
87
75
|
function results(payload, label) {
|
|
88
76
|
const body = requireRecord(payload, `${label} \u54CD\u5E94`);
|
|
89
77
|
if (!Array.isArray(body.results)) {
|
|
90
78
|
throw new TBError("unavailable", `${label} \u54CD\u5E94\u7F3A\u5C11 results`, { retryable: true });
|
|
91
79
|
}
|
|
92
|
-
return body.results.map((item) =>
|
|
80
|
+
return body.results.map((item) => asJsonObject(item)).filter((item) => item !== void 0);
|
|
93
81
|
}
|
|
94
82
|
function nextCursor(payload) {
|
|
95
|
-
return
|
|
83
|
+
return trimmedText(asJsonObject(payload)?.next_cursor) ?? null;
|
|
96
84
|
}
|
|
97
85
|
function idValue(value) {
|
|
98
86
|
if (typeof value === "number" && Number.isInteger(value)) return value;
|
|
99
|
-
return
|
|
87
|
+
return trimmedText(value);
|
|
100
88
|
}
|
|
101
89
|
function normalizeComment(payload) {
|
|
102
90
|
const comment = requireRecord(payload, "todoist comment");
|
|
103
|
-
return
|
|
91
|
+
return compactDefined({
|
|
104
92
|
...comment,
|
|
105
|
-
attachment:
|
|
93
|
+
attachment: asJsonObject(comment.attachment) ?? asJsonObject(comment.file_attachment)
|
|
106
94
|
});
|
|
107
95
|
}
|
|
108
96
|
function commentAttachment(value) {
|
|
109
|
-
const attachment =
|
|
97
|
+
const attachment = asJsonObject(value);
|
|
110
98
|
if (attachment === void 0) return void 0;
|
|
111
|
-
return
|
|
112
|
-
file_url:
|
|
113
|
-
file_name:
|
|
114
|
-
file_type:
|
|
115
|
-
resource_type:
|
|
99
|
+
return compactDefined({
|
|
100
|
+
file_url: trimmedText(attachment.fileUrl),
|
|
101
|
+
file_name: trimmedText(attachment.fileName),
|
|
102
|
+
file_type: trimmedText(attachment.fileType),
|
|
103
|
+
resource_type: trimmedText(attachment.resourceType)
|
|
116
104
|
});
|
|
117
105
|
}
|
|
118
106
|
function notifyUserIds(value) {
|
|
@@ -121,20 +109,20 @@ function notifyUserIds(value) {
|
|
|
121
109
|
return ids.length > 0 ? ids : void 0;
|
|
122
110
|
}
|
|
123
111
|
function taskBody(input, isCreate) {
|
|
124
|
-
return
|
|
125
|
-
content: isCreate ? requireText(input.content, "content") :
|
|
112
|
+
return compactDefined({
|
|
113
|
+
content: isCreate ? requireText(input.content, "content") : trimmedText(input.content),
|
|
126
114
|
description: input.description,
|
|
127
|
-
project_id:
|
|
128
|
-
section_id:
|
|
129
|
-
parent_id:
|
|
115
|
+
project_id: trimmedText(input.projectId),
|
|
116
|
+
section_id: trimmedText(input.sectionId),
|
|
117
|
+
parent_id: trimmedText(input.parentId),
|
|
130
118
|
order: input.order,
|
|
131
119
|
labels: stringArray(input.labels),
|
|
132
120
|
priority: input.priority,
|
|
133
121
|
assignee_id: input.assigneeId,
|
|
134
|
-
due_string:
|
|
135
|
-
due_date:
|
|
136
|
-
due_datetime:
|
|
137
|
-
due_lang:
|
|
122
|
+
due_string: trimmedText(input.dueString),
|
|
123
|
+
due_date: trimmedText(input.dueDate),
|
|
124
|
+
due_datetime: trimmedText(input.dueDatetime),
|
|
125
|
+
due_lang: trimmedText(input.dueLang),
|
|
138
126
|
duration: input.duration,
|
|
139
127
|
duration_unit: input.durationUnit,
|
|
140
128
|
deadline_date: input.deadlineDate,
|
|
@@ -152,7 +140,7 @@ async function listProjects(input, ctx) {
|
|
|
152
140
|
query: {
|
|
153
141
|
folder_id: idValue(input.folderId),
|
|
154
142
|
workspace_id: idValue(input.workspaceId),
|
|
155
|
-
cursor:
|
|
143
|
+
cursor: trimmedText(input.cursor),
|
|
156
144
|
limit: input.limit
|
|
157
145
|
}
|
|
158
146
|
});
|
|
@@ -166,14 +154,14 @@ async function createProject(input, ctx) {
|
|
|
166
154
|
const payload = await request(ctx, {
|
|
167
155
|
path: "/projects",
|
|
168
156
|
method: "POST",
|
|
169
|
-
body:
|
|
157
|
+
body: compactDefined({
|
|
170
158
|
name: requireText(input.name, "name"),
|
|
171
|
-
description:
|
|
159
|
+
description: trimmedText(input.description),
|
|
172
160
|
// 上游显式区分 null(建成顶层项目)与"未给"(不带这个键)。
|
|
173
|
-
parent_id: input.parentId === null ? null :
|
|
161
|
+
parent_id: input.parentId === null ? null : trimmedText(input.parentId),
|
|
174
162
|
color: input.color,
|
|
175
163
|
is_favorite: input.isFavorite,
|
|
176
|
-
view_style:
|
|
164
|
+
view_style: trimmedText(input.viewStyle),
|
|
177
165
|
workspace_id: idValue(input.workspaceId)
|
|
178
166
|
})
|
|
179
167
|
});
|
|
@@ -184,7 +172,7 @@ async function updateProject(input, ctx) {
|
|
|
184
172
|
path: `/projects/${encodeURIComponent(requireText(input.projectId, "projectId"))}`,
|
|
185
173
|
method: "POST",
|
|
186
174
|
// 更新是三态字段:未给不改、null 清空、有值改成它 —— 故原样透传。
|
|
187
|
-
body:
|
|
175
|
+
body: compactDefined({
|
|
188
176
|
name: input.name,
|
|
189
177
|
description: input.description,
|
|
190
178
|
color: input.color,
|
|
@@ -200,7 +188,7 @@ async function updateProject(input, ctx) {
|
|
|
200
188
|
async function listSections(input, ctx) {
|
|
201
189
|
const payload = await request(ctx, {
|
|
202
190
|
path: "/sections",
|
|
203
|
-
query: { project_id:
|
|
191
|
+
query: { project_id: trimmedText(input.projectId), cursor: trimmedText(input.cursor), limit: input.limit }
|
|
204
192
|
});
|
|
205
193
|
return { sections: results(payload, "todoist sections"), nextCursor: nextCursor(payload) };
|
|
206
194
|
}
|
|
@@ -212,7 +200,7 @@ async function createSection(input, ctx) {
|
|
|
212
200
|
const payload = await request(ctx, {
|
|
213
201
|
path: "/sections",
|
|
214
202
|
method: "POST",
|
|
215
|
-
body:
|
|
203
|
+
body: compactDefined({
|
|
216
204
|
name: requireText(input.name, "name"),
|
|
217
205
|
project_id: requireText(input.projectId, "projectId"),
|
|
218
206
|
order: input.order
|
|
@@ -224,7 +212,7 @@ async function updateSection(input, ctx) {
|
|
|
224
212
|
const payload = await request(ctx, {
|
|
225
213
|
path: `/sections/${encodeURIComponent(requireText(input.sectionId, "sectionId"))}`,
|
|
226
214
|
method: "POST",
|
|
227
|
-
body:
|
|
215
|
+
body: compactDefined({
|
|
228
216
|
name: input.name,
|
|
229
217
|
section_order: input.sectionOrder,
|
|
230
218
|
is_collapsed: input.isCollapsed
|
|
@@ -236,13 +224,13 @@ async function listTasks(input, ctx) {
|
|
|
236
224
|
const payload = await request(ctx, {
|
|
237
225
|
path: "/tasks",
|
|
238
226
|
query: {
|
|
239
|
-
project_id:
|
|
240
|
-
section_id:
|
|
241
|
-
parent_id:
|
|
242
|
-
label:
|
|
227
|
+
project_id: trimmedText(input.projectId),
|
|
228
|
+
section_id: trimmedText(input.sectionId),
|
|
229
|
+
parent_id: trimmedText(input.parentId),
|
|
230
|
+
label: trimmedText(input.label),
|
|
243
231
|
ids: stringArray(input.ids),
|
|
244
|
-
goal_id:
|
|
245
|
-
cursor:
|
|
232
|
+
goal_id: trimmedText(input.goalId),
|
|
233
|
+
cursor: trimmedText(input.cursor),
|
|
246
234
|
limit: input.limit
|
|
247
235
|
}
|
|
248
236
|
});
|
|
@@ -275,9 +263,9 @@ async function listComments(input, ctx) {
|
|
|
275
263
|
const payload = await request(ctx, {
|
|
276
264
|
path: "/comments",
|
|
277
265
|
query: {
|
|
278
|
-
task_id:
|
|
279
|
-
project_id:
|
|
280
|
-
cursor:
|
|
266
|
+
task_id: trimmedText(input.taskId),
|
|
267
|
+
project_id: trimmedText(input.projectId),
|
|
268
|
+
cursor: trimmedText(input.cursor),
|
|
281
269
|
limit: input.limit
|
|
282
270
|
}
|
|
283
271
|
});
|
|
@@ -294,10 +282,10 @@ async function createComment(input, ctx) {
|
|
|
294
282
|
const payload = await request(ctx, {
|
|
295
283
|
path: "/comments",
|
|
296
284
|
method: "POST",
|
|
297
|
-
body:
|
|
285
|
+
body: compactDefined({
|
|
298
286
|
content: requireText(input.content, "content"),
|
|
299
|
-
task_id:
|
|
300
|
-
project_id:
|
|
287
|
+
task_id: trimmedText(input.taskId),
|
|
288
|
+
project_id: trimmedText(input.projectId),
|
|
301
289
|
attachment: commentAttachment(input.attachment),
|
|
302
290
|
uids_to_notify: notifyUserIds(input.uidsToNotify)
|
|
303
291
|
})
|
|
@@ -316,7 +304,7 @@ async function updateComment(input, ctx) {
|
|
|
316
304
|
async function listLabels(input, ctx) {
|
|
317
305
|
const payload = await request(ctx, {
|
|
318
306
|
path: "/labels",
|
|
319
|
-
query: { cursor:
|
|
307
|
+
query: { cursor: trimmedText(input.cursor), limit: input.limit }
|
|
320
308
|
});
|
|
321
309
|
return { labels: results(payload, "todoist labels"), nextCursor: nextCursor(payload) };
|
|
322
310
|
}
|