npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@tushare/sdk

v1.2.0

Published

Tushare Pro SDK

Downloads

55

Readme

@tushare/sdk

Tushare Pro 门面聚合 SDK(严格类型、零 any,Node 18+ / 浏览器)

@tushare/sdk 基于 @tushare/core 的通用能力(固定窗口限流、指数退避重试、内存缓存、同构 fetch),通过“注册表 + 工厂”自动生成强类型方法,免去手写样板代码,专注业务调用。

  • 强类型:字段选择按字面量数组收窄,返回值自动 Pick<>
  • 通用能力:重试/限流/缓存/超时,统一可配
  • 同构:Node 18+ 和浏览器均可使用(浏览器建议经后端代理)
  • 轻量:按需导入类型;运行时仅保留必要元信息

安装

# 使用 pnpm(推荐)
pnpm add @tushare/sdk

# 或 npm
npm i @tushare/sdk
# 或 yarn
yarn add @tushare/sdk

快速上手

// 中文注释:引入门面类并初始化(请使用你的 Tushare token)
import { Tushare } from '@tushare/sdk';

// 中文注释:可选配置,均有合理默认值
const sdk = new Tushare('YOUR_TUSHARE_TOKEN', {
  baseUrl: 'https://api.tushare.pro', // 中文注释:基础地址
  defaults: {
    transform: 'object', // 中文注释:将表格转换为对象数组;'raw' 则返回原始二维表
    cacheTtlMs: 10_000,  // 中文注释:内存缓存时长(毫秒);0 表示关闭
    timeoutMs: 20_000,   // 中文注释:请求超时(毫秒)
  },
  rateLimit: {
    windowMs: 1000,      // 中文注释:固定窗口(毫秒)
    maxRequests: 80,     // 中文注释:每窗口最大请求数
  },
  maxRetries: 3,         // 中文注释:最大重试次数
  backoffBaseMs: 200,    // 中文注释:退避初始毫秒
  backoffFactor: 2,      // 中文注释:退避倍率
  backoffJitter: true,   // 中文注释:是否加入抖动
});

// 中文注释:通过自动模块/方法调用 API;字段选择将收窄返回类型
const rows = await sdk.auto.getStockBasic(
  { limit: 1 },                    // 中文注释:参数对象(类型安全)
  ['ts_code', 'name'] as const     // 中文注释:字段选择(字面量数组)
);

// rows: Array<{ ts_code: string; name: string }>
console.log(rows);

API 结构与命名

  • 模块来自注册表 registry 的分节(section)。常用分节之一为 auto
  • 每个方法名称通常以 getXxx 命名,对应 Tushare 的 api_name(例如 stock_basicgetStockBasic)。
  • 统一方法签名:
    • sdk[section][method](params, fields?)
    • params:严格类型化的参数对象
    • fields:可选的字段字面量数组(传入则返回值自动收窄为 Pick<TEntity, K[number]>[]

你也可以在编辑器中查看自动生成的类型:import type { ... } from '@tushare/sdk'

错误处理

import { TushareError } from '@tushare/core';

try {
  const rows = await sdk.auto.getStockBasic({ limit: 1 }, ['ts_code'] as const);
  console.log(rows);
} catch (e) {
  // 中文注释:业务错误(code != 0)或 HTTP 错误都会抛出 TushareError
  if (e instanceof TushareError) {
    console.error('API 出错', {
      name: e.name,           // 'TushareError'
      api: e.apiName,         // 中文注释:接口名(如 'stock_basic')
      code: e.code,           // 中文注释:业务码(非 0)
      httpStatus: e.httpStatus,
      params: e.params,
      message: e.message,
    });
  } else {
    console.error(e);
  }
}

性能与可靠性

  • 限流:固定窗口(windowMs / maxRequests
  • 重试:支持最大次数与指数退避(可抖动)
  • 缓存:内存缓存(TTL + 简易 LRU)
  • 超时:请求级超时控制

以上能力由 @tushare/core 提供,在本 SDK 中通过 TushareClientOptions 统一配置。

分页与大数据处理

  • SDK 不内置自动分页@tushare/sdk 方法一次只执行一次 API 调用。你可以手动使用 limit/offset 分页;或推荐使用 @tushare/mcpsdk_call 顺序分页(含重试/退避)。

  • 手动分页示例(TS):

// 中文注释:手动 limit/offset 循环(仅示例,生产建议改用 MCP 顺序分页)
import { Tushare } from '@tushare/sdk';

const sdk = new Tushare('TOKEN');

const pageSize = 5000; // 中文注释:单页条数
let offset = 0;        // 中文注释:偏移量
const all: Array<{ ts_code: string; trade_date: string; close: number }> = [];

while (true) {
  const rows = await sdk.auto.getDaily(
    { ts_code: '000001.SZ', start_date: '20240101', limit: pageSize, offset },
    ['ts_code', 'trade_date', 'close'] as const
  );
  if (!rows.length) break;
  all.push(...rows);
  offset += rows.length;
  if (rows.length < pageSize) break; // 中文注释:已到最后一页
}

console.log('total rows:', all.length);
  • 使用 MCP 顺序分页(推荐):
{
  "name": "sdk_call",
  "arguments": {
    "api_name": "daily",
    "params": { "ts_code": "000001.SZ", "start_date": "20240101" },
    "paginate": true,
    "limit": 5000,
    "max_rows": 20000,
    "fields_preset": "basic",
    "transform": "object"
  }
}

提示:MCP 的 paginate=true 为顺序分页,带有指数退避与重试,更适合大数据抓取与限流环境。

在浏览器中使用

  • SDK 为 ESM 包,可在现代打包器中直接使用。
  • 出于安全考虑,请勿在前端直接暴露 Tushare Token。推荐通过后端代理转发请求;或为浏览器环境单独申请受限 token。

TypeScript 支持

  • 项目默认严格类型检查(no any)。
  • 字段选择使用字面量数组(as const)实现返回值的编译期收窄。
  • 所有实体与参数类型来自代码生成(src/generated),会随着接口的扩展而自动更新。

运行环境

  • Node.js >= 18(内置 fetch)
  • 或现代浏览器(通过打包器)

示例:更多选项

import { Tushare } from '@tushare/sdk';

const sdk = new Tushare('TOKEN', {
  baseUrl: 'https://api.tushare.pro',
  defaults: { transform: 'raw', cacheTtlMs: 0, timeoutMs: 10_000 }, // 中文注释:返回原始二维表
  rateLimit: { windowMs: 1000, maxRequests: 60 },                    // 中文注释:更保守的限流
  maxRetries: 5,
  backoffBaseMs: 100,
  backoffFactor: 2,
  backoffJitter: true,
});

const table = await sdk.auto.getStockBasic({ market: '主板', limit: 5 });
console.log(table);

常见问题(FAQ)

  • 字段名在哪里查?
    • 参见 Tushare 官方文档;本包暴露的类型也可在编辑器悬浮查看。
  • 返回值为什么有时是对象数组、有时是二维表?
    • defaults.transform 或单次调用时的 transform 决定。'object' 返回对象数组,'raw' 返回原始表格。
  • 为什么我的请求没有发送?
    • 可能被内存缓存命中(TTL 内相同请求体只调用一次)。设置 cacheTtlMs: 0 可禁用。