feat: initial public release
CI / Client installer (macos-latest) (push) Canceled after 0s
CI / Client installer (ubuntu-latest) (push) Canceled after 0s
CI / Client installer (windows-latest) (push) Canceled after 0s
CI / test (22) (push) Canceled after 0s
CI / test (24) (push) Canceled after 0s
CI / release-smoke (push) Canceled after 0s
CI / Client installer (macos-latest) (push) Canceled after 0s
CI / Client installer (ubuntu-latest) (push) Canceled after 0s
CI / Client installer (windows-latest) (push) Canceled after 0s
CI / test (22) (push) Canceled after 0s
CI / test (24) (push) Canceled after 0s
CI / release-smoke (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env node
|
||||
import { readFileSync } from "node:fs";
|
||||
import { XftOpenApiClient } from "../dist/src/xft-open-api.js";
|
||||
|
||||
const [appId, secretFile, enterpriseId, dingTalkUserId, historyBillId] = process.argv.slice(2);
|
||||
if (!appId || !secretFile || !enterpriseId || !dingTalkUserId) {
|
||||
console.error("usage: node scripts/xft-open-api-readonly.mjs <appId> <secretFile> <enterpriseId> <dingTalkUserId>");
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
const config = {
|
||||
clientId: "readonly-smoke-test",
|
||||
clientSecret: "readonly-smoke-test",
|
||||
apiBaseUrl: "https://api.dingtalk.com",
|
||||
oapiBaseUrl: "https://oapi.dingtalk.com",
|
||||
publicBaseUrl: "https://localhost",
|
||||
port: 3000,
|
||||
requestTimeoutMs: 15_000,
|
||||
officialLookbackDays: 120,
|
||||
officialScanConcurrency: 2,
|
||||
officialClientOnlyProcessCodes: [],
|
||||
batchLimit: 20,
|
||||
xftOpenApi: {
|
||||
appId,
|
||||
authoritySecret: (() => {
|
||||
const lines = readFileSync(secretFile, "utf8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
||||
return lines.length >= 2 ? lines[1] : lines[0];
|
||||
})(),
|
||||
enterpriseId,
|
||||
apiBaseUrl: "https://api.cmbchina.com",
|
||||
encrypted: true,
|
||||
dingTalkAppCode: "DDingTalk",
|
||||
},
|
||||
};
|
||||
|
||||
const client = new XftOpenApiClient(config);
|
||||
if (historyBillId && historyBillId !== "--auth-only") {
|
||||
try {
|
||||
const history = await client.request(
|
||||
`/itrip/xft-api/v1/bills/taskHistory/${encodeURIComponent(historyBillId)}`,
|
||||
undefined,
|
||||
"GET",
|
||||
);
|
||||
console.log(JSON.stringify({ historyProbe: "ok", responseType: Array.isArray(history) ? "array" : typeof history }));
|
||||
} catch (error) {
|
||||
console.log(JSON.stringify({ historyProbe: "failed", message: error instanceof Error ? error.message : String(error) }));
|
||||
}
|
||||
}
|
||||
const user = { userId: dingTalkUserId };
|
||||
const auth = await client.authStatus(user);
|
||||
if (historyBillId === "--auth-only") {
|
||||
console.log(JSON.stringify({ authenticated: auth.authenticated, identity: auth.identity }, null, 2));
|
||||
process.exit(0);
|
||||
}
|
||||
const todos = await client.listMyTodos(user, 200);
|
||||
const detailCandidates = ["COMMON_REIM", "TRAVEL_REIM"]
|
||||
.map((eventType) => todos.items.find((item) => item.eventType === eventType))
|
||||
.filter(Boolean);
|
||||
const details = await Promise.all(detailCandidates.map((item) => client.getTodoDetail(user, item.billId)));
|
||||
console.log(JSON.stringify({
|
||||
authenticated: auth.authenticated,
|
||||
identity: auth.identity,
|
||||
todoCount: todos.totalCount,
|
||||
sample: todos.items.slice(0, 3).map(({ billId, title, applicantName, amount, eventType }) => ({ billId, title, applicantName, amount, eventType })),
|
||||
detailProbes: details.map((detail) => ({
|
||||
billId: detail.todo.billId,
|
||||
eventType: detail.todo.eventType,
|
||||
formType: Array.isArray(detail.form) ? "array" : typeof detail.form,
|
||||
formTopLevelKeys: detail.form && typeof detail.form === "object" && !Array.isArray(detail.form)
|
||||
? Object.keys(detail.form).slice(0, 30)
|
||||
: [],
|
||||
})),
|
||||
diagnostics: todos.diagnostics,
|
||||
}, null, 2));
|
||||
Reference in New Issue
Block a user