@turinhub/tale-js-sdk
v2.4.4
Published
Official TypeScript SDK for Tale backend services
Maintainers
Readme
@turinhub/tale-js-sdk
官方 TypeScript SDK,用于与 Tale 后端服务集成与交互。
- 项目主页:https://github.com/turinhub/tale-js-sdk
- 问题反馈:https://github.com/turinhub/tale-js-sdk/issues
- 许可证:MIT(详见
LICENSE)
安装
支持 npm、pnpm、yarn 安装:
npm install @turinhub/tale-js-sdk
# 或
pnpm add @turinhub/tale-js-sdk
# 或
yarn add @turinhub/tale-js-sdk快速开始
本 SDK 采用 ESM(type: module)。在 TypeScript 或现代 Node.js/前端环境中可直接导入:
import {
createTaleAdminClient,
createTaleAppClient,
} from "@turinhub/tale-js-sdk";
const admin = createTaleAdminClient({
baseUrl: "https://api.tale.example",
taleToken: "tale-user-token",
});
const currentUser = await admin.currentUser.get();
const apps = await admin.apps.listByOrg(currentUser.app.orgId);
const issued = await admin.appTokens.issue({ appKey: "oa_xxx" });
const app = createTaleAppClient({
baseUrl: "https://api.tale.example",
appToken: issued.token,
});
const files = await app.cms.listFiles({ folderId: "folder-id" });认证与 Token
SDK 中常见的鉴权选项都通过 x-t-token 发送到 Tale 后端:
appToken:应用作用域 Token,适用于 CMS、RBAC、ACL、Task、Attachment 等应用内资源 API。taleToken:Tale 用户 Token,适用于平台级 App 管理 API,例如获取当前用户、应用列表、应用详情、App Secret,以及按 App Key 换发 App Token。baseUrl:Tale 后端服务基础 URL;未显式传入时会读取环境变量。
服务端可使用 getAppToken() 通过 TALE_APP_KEY 与 TALE_APP_SECRET 获取应用 Token。getAppToken() 是 server-only helper,不应在浏览器代码中调用或暴露 TALE_APP_SECRET。浏览器端的 Cookie、缓存、自动续期和多应用切换策略不由 SDK 核心管理,调用方可基于 createTaleAdminClient().appTokens.issue() 或业务后端代理自行封装。
生产环境服务端网站建议使用动态 Token provider,而不是在进程启动时签发一次后长期持有固定 appToken:
import { createTaleAppClient, getAppToken } from "@turinhub/tale-js-sdk";
const app = createTaleAppClient({
baseUrl: process.env.TALE_BASE_URL,
appTokenProvider: () =>
getAppToken({
baseUrl: process.env.TALE_BASE_URL,
appKey: process.env.TALE_APP_KEY,
appSecret: process.env.TALE_APP_SECRET,
}),
});getAppToken() 会按凭据缓存 token,在过期前提前后台刷新;刷新失败但旧 token 仍有效时会继续使用旧 token,并在后续短间隔重试。SDK 内部请求遇到明确的 token 过期或无效响应时,会强制刷新并重试一次。多实例部署时,仍建议在应用层结合 Redis/KV 与分布式锁共享 token 并错峰刷新,避免所有实例同时请求签发接口。
Admin 与 App Client
也可以从子路径导入两个客户端入口:
import { createTaleAdminClient } from "@turinhub/tale-js-sdk/admin";
import { createTaleAppClient } from "@turinhub/tale-js-sdk/app";Admin client 只接收 taleToken,用于平台级应用管理:
const admin = createTaleAdminClient({ baseUrl, taleToken });
await admin.currentUser.get();
await admin.apps.listByOrg("org_1");
await admin.apps.create({ appName: "Demo", orgId: "org_1" });
await admin.apps.getDetail("oa_xxx");
await admin.apps.update({ appId: "app_1", appName: "Demo" });
await admin.appTokens.getSecret("oa_xxx");
await admin.appTokens.issue({ appKey: "oa_xxx" });App client 接收固定 appToken 或动态 appTokenProvider,用于单应用内资源:
const app = createTaleAppClient({ baseUrl, appToken });
await app.cms.listFiles({ folderId: "folder_1" });
await app.users.list({ page: 0, size: 20 });
await app.tasks.create({ openId: "ou_xxx", taskTypeId: "type_1" });
await app.tasks.get("task_1", {
includeAttachments: true,
includeSubTasks: true,
});
await app.rbac.listRoles();
await app.acl.listRecords();
await app.attachments.listByRef({ refType: "task", refId: "task_1" });
await app.appTokens.list({ page: 0, size: 20 });Legacy-compatible 函数导入
已有项目可以继续从根入口直接导入函数。该方式在 2.x 内保持兼容,但新项目建议优先使用 Admin/App client。
import {
getAppToken,
getCurrentUser,
listAppsByOrg,
listFiles,
} from "@turinhub/tale-js-sdk";
const appToken = await getAppToken({
baseUrl,
appKey: process.env.TALE_APP_KEY,
appSecret: process.env.TALE_APP_SECRET,
});
const files = await listFiles({ baseUrl, appToken, folderId: "folder-id" });
const currentUser = await getCurrentUser({ baseUrl, taleToken });
const apps = await listAppsByOrg(currentUser.app.orgId, { baseUrl, taleToken });AppTS 模块提供平台应用相关方法:
import {
getCurrentUser,
listAppsByOrg,
createApp,
getAppDetail,
updateApp,
} from "@turinhub/tale-js-sdk";AppTokenTS 模块提供 App Token 相关接口封装:
import {
listAppTokens,
getAppSecret,
issueAppToken,
} from "@turinhub/tale-js-sdk";
const page = await listAppTokens({
baseUrl: "https://api.tale.example",
appToken: "app-token",
page: 0,
size: 20,
isValid: true,
});
const secret = await getAppSecret("oa_xxx", {
baseUrl: "https://api.tale.example",
taleToken: "tale-user-token",
});
const issued = await issueAppToken({
baseUrl: "https://api.tale.example",
taleToken: "tale-user-token",
appKey: "oa_xxx",
});公开类型、入参和响应字段保持 camelCase。SDK 会处理 Java 后端可能返回的 { code, msg, data } envelope 与直接 payload,但不再兼容历史 snake_case 响应字段。
开发与测试
仓库采用 TypeScript 与 Jest:
pnpm install # 或 npm install / yarn
pnpm run typecheck
pnpm run build
pnpm run test:unit
pnpm test发布
如果本机配置了 npm 镜像,发布时显式指定 npm 官方 registry:
pnpm run build
pnpm run typecheck
pnpm run format:check
pnpm run test:unit
npm publish --access public --registry=https://registry.npmjs.org/更新日志与版本
遵循语义化版本(SemVer)。发布与变更说明将按迭代在仓库中维护。
TODO
- [x] 修改 User Group 等分页格式,统一为 PageResponse。
许可证
本项目基于 MIT 许可证开源,详见 LICENSE 文件。版权归 Turinhub 团队所有。
